Im having problem with global arrays in my C code. What i am trying to do is to use a display buffer (array of 8 uint8_t with each uint8_t representing a row) to light up the leds in 8x8 led matrix using column scanning.
the relevant part of code is:
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>
uint8_t string_size=3; //DISPLAY STRING SIZE
uint8_t display_string[8][3]; //DISPLAY STRING
uint8_t display_buffer[8]; //CURRENT DISPLAY BUFFER
/*****************************************
CHARACTER MAPS
*****************************************/
uint8_t h[8]= {
0b11111111,
0b10000001,
0b10100101,
0b10100101,
0b10111101,
0b10100101,
0b10000001,
0b11111111
};
uint8_t o[8]= {
0b11111111,
0b10000001,
0b10111101,
0b10100101,
0b10100101,
0b10111101,
0b10000001,
0b11111111
};
uint8_t t[8]= {
0b11111111,
0b10000001,
0b10111101,
0b10011001,
0b10011001,
0b10011001,
0b10000001,
0b11111111
};
/*****************************************
FUNCTIONS
*****************************************/
void addCharToString(uint8_t pos, uint8_t chr[]); //ADD PASSSED CHAR TO SPECIFIED POS IN STRING
void setupDisplayBuffer(); //SETUP INITIAL DISPLAY BUFFER
void writeDisplayBuffer(); //DRAW CURRENT DISPLAY BUFFER
int main()
{
addCharToString(0,h);
addCharToString(1,o);
addCharToString(2,t);
setupDisplayBuffer();
for(;;)
{
writeDisplayBuffer();
}
}
void addCharToString(uint8_t pos, uint8_t arr[])
{
for(uint8_t i=0;i<8;i++)
{
//display_string[i][pos] = arr[i]; //PROBLEM HERE!
display_string[i][pos] = 0b10000001;
}
}
void setupDisplayBuffer()
{
//COPY THE FIRST CHARACTER FROM DISPLAY STRING TO DISPLAY BUFFER
for(uint8_t i=0;i<8;i++)
{
display_buffer[i] = display_string[i][0];
}
}
void writeDisplayBuffer()
{
for(uint8_t i=0;i<8;i++)
{
write595(display_buffer[i]);
set2903Pin(i);
_delay_loop_2(1986); // ACCURATE 1MS DELAY .. HIGHER THAN THIS = FLICKERING
}
}
When I run it I see the whole column light up (whole 8x8 grid lid up with scanning) and it seems the problem is happening in the line
display_string[i][pos] = arr[i];
in addCharToString(). if i comment out this line and use a constant value (0b10000001) in the above code it gets displayed perfectly (first and the last column lighting up)
It seems that the array(s) h, o and t are not getting initialized properly. Any ideas what could be happening here
I am using ATMEGA8.
Update:
I am using -0s optimization with the following flags set
- funsigned-chars
- funsigned-bitfields
- fpack-struct
- fshort-enums
2 Answers 2
Found the solution. As suggested by members at avrfreaks.net here the problem was that by using the default makefile the .data part of code was not getting included in the final hex file. as a result the ram was getting initialized by default value (0xFF) since it could not find the array values (in the .data part). Using a custom makefile with the flag -j .data
in avr-objcopy solved the problem.
You array initialisation is fine; see How to initialise an array in C, or K&R for chapter & verse. Up to the call to writeDisplayBuffer everything is good. Maybe the problem is within write595(), set2903Pin() or in your circuit somewhere.
-
\$\begingroup\$ i have added the code for setupDisplayBuffer() and writeDisplayBuffer() to my post. I've looked over them so many times but cant seem to pinpoint the mistake. \$\endgroup\$Ankit– Ankit2013年03月07日 13:58:30 +00:00Commented Mar 7, 2013 at 13:58
-
\$\begingroup\$ They seem fine - Ive fired them up in a debugger and your code successfully continually calls the write595 function with the bitmaps for the first letter. Looks like the problem is deeper down. \$\endgroup\$Richard Padley– Richard Padley2013年03月07日 16:58:24 +00:00Commented Mar 7, 2013 at 16:58
-
\$\begingroup\$ Yep something is definitely up! when i use the statement
display_string[i][pos] = i;
i get a blank display. using a constant value such asdisplay_string[i][pos] = 0b10000001;
produces the right pattern \$\endgroup\$Ankit– Ankit2013年03月07日 20:45:14 +00:00Commented Mar 7, 2013 at 20:45
const uint8_t h[8] PROGMEM = { 0b11111111, 0b10000001, 0b10100101, 0b10100101, 0b10111101, 0b10100101, 0b10000001, 0b11111111 };
andvoid addCharToString(uint8_t pos, const uint8_t arr[]) { for(uint8_t i=0;i<8;i++) { display_string[i][pos] = pgm_read_byte(&arr[i]); //PROBLEM HERE! //display_string[i][pos] = 0b10000001; } }
but the result was the same \$\endgroup\$display_string[i][pos] = i
produces a blank display \$\endgroup\$