ST7920 doesn't display properly ?

Go To Last Post
37 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Guys,

I tried to display message on ST7920 LCD,
It's displaying the text already, but I must reset few times before it can display properly,

Do I miss something here ?

Here's the code I used :

char menu_txt[21] = " ATMEGA128    "; 
void lcd_init(){
    //st7920
		lcd_cmd(0x30);
		_delay_ms(100);
		lcd_cmd(0x30);
		_delay_ms(100);
		lcd_cmd(0x0F);
		_delay_ms(100);
		//lcd_cmd(0x80);
		//_delay_ms(10);
		lcd_cmd(0x01); //clear screen
		_delay_ms(100);
		lcd_cmd(0x02);//Return home
		_delay_ms(100);

		lcd_cmd(0x06);//cursor to the right
		_delay_ms(100);
		    

   
	
}


void lcd_data(unsigned char data1)
{
	
	
	lcd_data_pin = data1;// & 0x0F;
	en=1;
    _delay_us(100);
	rs=1;
   _delay_us(100);
	rw=0;
	_delay_ms(10);
	en=0;
	
}

void lcd_cmd(unsigned char cmd){
	
	lcd_data_pin = cmd ;
	_delay_us(100);
	en=1;
    _delay_us(100);
	rs=0;
    _delay_us(100);
	rw=0;

	_delay_ms(10);
	en=0;
	
	
	
}



void lcd_string(unsigned char *str){
	
	while(*str){
		lcd_data(*str++);
	}
	
}

lcd_string(menu_txt);

Any ideas ?
thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bianchi77 wrote:

...but I must reset few times before it can display properly...

This normally indicates that you aren't initialising the display controller correctly.

And lo', whilst you haven't shown all your code (no main() ), what you have shown does not follow the sequence in the data sheet.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

do you mean my init code isn't following datasheet ?
I do following it...I'll recheck...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the main :

int main(){
	
	DDR_D.b0 = 1;
	DDR_D.b1 = 1;
	DDR_D.b2 = 1;
	DDR_D.b3 = 1;
	DDRA = 0xFF;
	
	lcd_init();
	lcd_TextMode();
		lcd_string(menu_txt);
	
	while(1){
        }
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

init flowchart

my current init code :

{
	_delay_ms(100);
	res =0;
	_delay_ms(100);
	res=1;
		lcd_cmd(0x30);
		_delay_us(100);
		lcd_cmd(0x30);
		_delay_us(100);
		lcd_cmd(0x0F);
		_delay_us(100);
		//lcd_cmd(0x80);
		//_delay_ms(10);
		lcd_cmd(0x01); //clear screen
		_delay_ms(20);
		lcd_cmd(0x02);//Return home
		_delay_ms(100);

		lcd_cmd(0x06);//cursor to the right
		_delay_us(10);
		    

   
	
}

anything miss ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

on LCD after reset few times :

reset again for a test:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You probably want a delay after the reset to give the chip time to start up

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

which reset you're talking about ? LCD reset or ATMEGA128 reset ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah-ha. That controller looks like fun. It is similar but "not quite" to regular HD44780 LCD displays. Yet can do graphics too!

Sit down with the data sheet, and follow the timing sequence properly. i.e. EN.

AS with HD44780, you can either check BUSY or just add delays. However, adding massive delays in the wrong place will not work.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
{ 
   _delay_ms(100); 
   res =0; 
   _delay_ms(100); 
   res=1; 

You gave two choices - you could've tried them both in less time it took to write the response.
Of course i meant after resetting the display chip. Add delay after the above code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I put even longer but the result is not yet what I want...

      _delay_ms(500);
	res =0;
	_delay_ms(500);
	res=1;

?? abit puzzling for me this chipset, I thought it was similar with HD44780

I must push reset button few times, until I can get the text I want......

update lcd_cmd

void lcd_cmd(unsigned char cmd){
//st7920	
	_delay_us(500);
	rs=0;
	_delay_us(400);
	rw=0;
	_delay_us(200);
	en=1;
	
    lcd_data_pin = cmd ;
	_delay_us(300);
	en=0;
	
}	

following :

Please correct me if I'm wrong....thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hd44780 doesn't have a reset signal. Why did you make the delays longer? I suggested you add a delay AFTER that code.

Currently you reset the chip then send it a command - it may need some startup time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Compare your function with 8-bit interface timing diagram on p42.

void lcd_data(unsigned char data1)
{
   lcd_data_pin = data1;// & 0x0F;
   en=1;
    _delay_us(100);
   rs=1;
   _delay_us(100);
   rw=0;
   _delay_ms(10);
   en=0;
}

Now think what happens when you have successive calls to lcd_data(). Or if you have a lcd_cmd() followed by lcd_data(). The time between the en=0 and the subsequent lcd_data_pin = data1.

The execution does not start until EN goes low.

What is the value of TAS from your code? i.e. -100us

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also rs and rw should be stable before en goes high.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

how about lcd_data :

void lcd_data(unsigned char data1)
{
	_delay_us(500);
	rs=1;
	_delay_us(400);
	rw=0;
	_delay_us(200);
	en=1;
	
	lcd_data_pin = data1 ;
	_delay_us(300);
	en=0;
	
}

I uploaded to the chip and it's displaying correctly but not sure yet, since I haven't push the reset button to test it.....cross my finger..
.

Thanks guys, it's stable now...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now read the datasheet and fix up your timing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

God invented data sheets so that you can use correct timing sequence. Note that you get min, typ, max values. Always design for the worst case. e.g. 72us * (590kHz / 540kHz) = 79us for lcd_data().

It is not unreasonable to use ballpark figures. e.g. I might design for 100us as a nice round number.
However, inserting 10000us delay is a bit pointless.

Note that the data sheet tells you the execution time for HOME and CLRHOME. You can easily test for these two special cases.

Most of these times like TAS are nothing to worry about. It must be positive, but 10ns is faster than any microcontroller can ever wiggle GPIO pins. Even fast ARM chips !

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the advice,

I tried to loop :

while(1){
		   lcd_string("ATMEGA128");
		   lcd_cmd(0x90);
		   lcd_string(by_bianchi);
		   
		   lcd_cmd(0x01);
           
		      lcd_string("ST 7920");
		      lcd_cmd(0x90);
		      lcd_string("TEST");
	}

but the second message never appear properly, does anyone know why ?

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you follow our advice?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, from the data sheet: 0x90 is "Set DDRAM Address." with a nominal execution time of 72us.

If you followed my earlier advice, you would write down in pencil:

lcd_data('0');   // the last char from "ST7920"
lcd_cmd(0x90);   // the subsequent call.
lcd_data('T');   // the first char from "Test"

Then expand the actual statements in the functions.

You have corrected the timing sequence in your lcd_data().
Have you done the same with lcd_cmd() ?

You have probably noticed similarities between lcd_cmd() and lcd_data(). If you replace with a single generic function, you only need to edit / maintain one sequence.

As a related point:
Have you tested for 0x01 in lcd_cmd() ?
Have you added an extra 1.6ms ?

Throw away all your RedBull and other "Energy drinks".
Buy some good quality tea. You know it makes sense.

David.

p.s. if you listen to "The Prairie Home Companion" on public radio, you might benefit from ketchup.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hehehe....
Now I have another question :

//This function is creating rectangle
 void lcd_rectangle(){
	 unsigned char x, y;
	 lcd_GraphicMode();
	 lcd_GraphicClear();
	//Top line begin
	 for(y = 0; y < 1; y++)
	 {
		 if(y + 16 < 32)
			 {
				 lcd_cmd(0x80 | y + 0);
				 lcd_cmd(0x80);
			 }
			 for(x = 0; x < 16; x++)
			 {
				 lcd_data(0xff);
			 }
	 }
	 //Top line end
	 //Bottom line begin
	 for(y = 0; y < 1; y++)
	 {
		 if(y + 16 < 32)
		 {
			 lcd_cmd(0x98 | y + 7);
			 lcd_cmd(0x98);
		 }
		 for(x = 0; x < 16; x++)
		 {
			 lcd_data(0xff);
		 }
	 }
	 //Bottom line end
 }

I tried to create the side line....any ideas guys?
because I always got a line to right, never been from top to bottom on the side no matter I changed the value of x or y....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you looked at the numerous libraries available via Google?

Besides, you have two for loops that interate only once.

If you want to write your own code from scratch, write a function that allows you to address each pixel and set or clear it. Then you can start to draw lines.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Kartman
any experiences on addressing 1 pixel ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, grab a library for the arduino that suits your display.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Kartman,

I use bmp graphic method, with array of bitmap but I got
Error 26 Program Memory Usage : 5560 bytes 4.2 % Full
Data Memory Usage : 4184 bytes 102.1 % Full (Memory Overflow) LCDv1.0 0 0 LCDv1.0

any work around it, for example move the graphic picture to program memory ?
one of the array example (bmp) :

const unsigned char round1 [] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which respected library are you using ?

Most will have library functions for displaying bitmaps and strings from flash memory.

All you have to do is place the bitmap in flash. e.g. with PROGMEM or __flash

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@David,

I have created my own library on loading the bmp,
and I got error

the line:

const unsigned char round1 []  __flash  = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,...

Error 1 expected '=', ',', ';', 'asm' or '__attribute__' before '__flash' C:\Users\antonius\Documents\Atmel Studio\6.1\LCDv1.0\LCDv1.0\round1.h 6 32 LCDv1.0

any clues ? thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HeHeHe, did you read the documentation on the use of __flash or just randomly put it where you felt like?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Surely you could start with http://code.google.com/p/u8glib/ and away you go.

No, I have not used this library, but I guess that it will do everything you want.

Seriously, it is always wise to start with a working solution. Then you can write your own with something to compare with.

It is also a good reason for buying an Arduino. You can test hardware with the proven Arduino libraries. Let's face it. Almost every peripheral chip, module etc is supported by the Arduino.

Yes, I like to write my own software. But I am realistic. I start with proven code on a proven hardware target. Then develop from there, hopefully to run on many targets. I bet that most other people do the same.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

http://www.nongnu.org/avr-libc/user-manual/pgmspace.html
Is this the documentation you're talking about ?
I still got the same error....what do I miss here ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What did you miss? If you read the doc on progmem why didn't you use progmem?

https://www.avrfreaks.net/index.p...

Amazing what a little searching finds. Realise most of the problems you encounter have been found by others and solved. Dredging the same stuff up again really doesnt benefit civilisation does it?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good stuff, thanks for the info...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried to render from flash with :

 for(y = 0; y < 64; y++)
	 {
		 if(y < 32)
		 {
			 for(x = 0; x < 8; x++)							// Draws top half of the screen.
			 {												// In extended instruction mode, vertical and horizontal coordinates must be specified before sending data in.
				 lcd_cmd(0x80 | y);				// Vertical coordinate of the screen is specified first. (0-31)
				 lcd_cmd(0x80 | x);				// Then horizontal coordinate of the screen is specified. (0-8)
				 //lcd_data(graphic[2*x + 16*y]);		// Data to the upper byte is sent to the coordinate.
				 for (int i=0; i<1077; i++)
				 {
					 lcd_data( (pgm_read_byte(&graphic[i])[2*x + 16*y] ));
				 }
				 
				 lcd_data(graphic[2*x+1 + 16*y]);	// Data to the lower byte is sent to the coordinate.
			 }
		 }

I got error for

lcd_data( (pgm_read_byte(&graphic[i])[2*x + 16*y] ));

Error 9 subscripted value is neither array nor pointer nor vector

the original without flash :

//lcd_data(graphic[2*x + 16*y]);

any workarounds for it ?

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It works with PROGMEM, thanks guys
http://www.youtube.com/watch?v=WIGPYorPKxU

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You obviously didn't read enough. Pgm_read works with progmem not __flash.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Pgm_read works with progmem not __flash.

You sure?

#include 
#include 

const __flash char foo[] = {0x55, 0xAA};

int main(void) {
    while(1) {
        PORTB = foo[PIND];
        PORTB = pgm_read_byte(&foo[PIND]);
    }
}
//==>         PORTB = foo[PIND];
	in r30,0x10
	ldi r31,0
	subi r30,lo8(-(foo))
	sbci r31,hi8(-(foo))
	lpm r24,Z
	out 0x18,r24
//==>         PORTB = pgm_read_byte(&foo[PIND]);
	in r30,0x10
	ldi r31,0
	subi r30,lo8(-(foo))
	sbci r31,hi8(-(foo))
/* #APP */
 ;  9 ".././test.c" 1
	lpm r30, Z
	
 ;  0 "" 2
/* #NOAPP */
	out 0x18,r30

As to the original post:

pgm_read_byte(&graphic[i])[2*x + 16*y]

Surely that's just mis-placed parentheses and should read:

pgm_read_byte(&graphic[i][2*x + 16*y])

No wonder the compiler said

Error 9 subscripted value is neither array nor pointer nor vector 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I obviously didn't read enough!