NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » AVR Arrays?

April 09, 2010
by Hexorg
Hexorg's Avatar

I've been trying to make this code work for the whole day already... what irritates me the most, same code works great on pc with a few little modifications.

Code:

// Little macros I found online to make binary literals
#define HEX__(n) 0x##n##LU

/* 8-bit conversion function */
#define B8__(x) ((x&0x0000000FLU)?1:0) \
+((x&0x000000F0LU)?2:0) \
+((x&0x00000F00LU)?4:0) \
+((x&0x0000F000LU)?8:0) \
+((x&0x000F0000LU)?16:0) \
+((x&0x00F00000LU)?32:0) \
+((x&0x0F000000LU)?64:0) \
+((x&0xF0000000LU)?128:0)

/* *** user macros *** /

/* for upto 8-bit binary constants */
#define B8(d) ((unsigned char)B8__(HEX__(d)))

// my file

#define F_CPU 14745600
#define delay 100
#include <stdio.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"

void led_out(uint8_t);
void display_out(uint8_t [], uint16_t);

void display_out(uint8_t disp[], uint16_t size)
{
    long int i;
    for (i=0; i<size; i++)
    {
        led_out(disp[i]);
        delay_ms(delay);
    }
    for (i=size-1; i>=0; i--)
    {
        led_out(disp[i]);
        delay_ms(delay);
    }  
}

void led_out(uint8_t leds)
{
    PORTC = (PORTC & 0xC1) | (leds);
    if (leds & 1)
        PORTB |= (1<<PB5);
    else 
        PORTB &= ~(1<<PB5);    
}

int main()
{

    uint8_t display[]= {B8(100000),
                        B8(010000),
                        B8(001000),
                        B8(000100),
                        B8(000010),
                        B8(000001)};
    DDRC |= (1<<PC5) | (1<<PC4) | (1<<PC3) | (1<<PC2) |     (1<<PC1);
    DDRB |= (1<<PB5); // I have 6 LEDs in those ports

    while(1)
    {        
        display_out(display, sizeof(display));         
    }

    return 0;
}

for some reason all 6 LEDs start glowing and don't blink at all. if i change led_out to

void led_out(uint8_t leds)
{
    printf("%u%u%u%u%u%u", (leds & B8(100000))>>5, (leds & B8(010000))>>4, 
(leds & B8(001000))>>3, (leds & B8(000100))>>2, (leds & B8(000010))>>1, 
(leds & B8(000001))>>0);  
}

And remove some headers, it can be compiled and runs perfectly on pc, but I can't seem to find the error.

April 12, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Hexorg,

I didn't really comb through the code, but could the problem be the that you are statically initializing arrays in your code. With our Makefile set up like we do, you can't statically initialize arrays. This is a result of the AVR architecture which has separate memory spaces for RAM and your program. There is a lengthy discussion about it in this thread. The easiest way to find out if that is the issue is to remove the -j .text from the avrdude flags in the Makefile, and recompile. This will cause avrdude to send all the data including the instructions on how to initialize your arrays in RAM. Note that you arrays will then be defined both in RAM and Flash, which is can be an issue in memory constrained environments. The better solution is to define your arrays in program space, then copy them over when needed. There is a great explanation of that on the avr-libc Data in Program Space page.

Sorry if you already knew that. I'm starting to sometimes lose track of who has been involved in which conversations with all the awesome members on the forums!

Humberto

Post a Reply

Please log in to post a reply.

Did you know that a motor is harder to turn when its terminals are shorted together? Learn more...