avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] Strange behaviour of program-space


From: E. Weddington
Subject: Re: [avr-libc-dev] Strange behaviour of program-space
Date: Sat, 19 Feb 2005 17:05:08 -0700
User-agent: Mozilla Thunderbird 0.7.3 (Windows/20040803)

Florian Bantner wrote:

Hi List,

I don't know if this is the right list to ask this question, but the
other one (avr-chat) doesn't seem right either. Whatever...
Really, the avr-gcc-list would be best. You can find it here:
<http://savannah.nongnu.org/mail/?group=avr>


My question is this: I'm trying out (as a first step) the example in
the FAQ for putting strings in program-space. My program looks like
this and doesn't work. It just outputs garbage:

-- snip: does not work ----------

#include "avr/pgmspace.h"

const char string1[] PROGMEM = "Test eins";
const char string2[] PROGMEM = "Test zwei";

PGM_P array[2] PROGMEM = { string1, string2 };

The above is all correct.

void delay();

int main(){

       uint8_t i;
       PGM_P c;

       lcdInit();

       for( ever ){

               lcdPut( '\n' );

               for( i=0; i<2; i++ ){

                       for( c = array[ i ]; pgm_read_byte_near( c ) != '\0'; 
c++ ){

                               lcdPut( (char) pgm_read_byte_near( c ) );
                       }
               }
               delay();
       }
}


Several things here:

- Don't forget that you've put the *array* itself into the Program Space. So to get the beginning address of the string, you'll have to read the array from Program Space. - You generally don't have to expressly use the *_near() macros. Unless you're using a mega128, using the pgm_read_byte() will work as the _near version of the macro. - The easiest way to think about, is express the access of the object that is stored in program space as you normally would, then take the address of it (if it's not already an address), and pass it to the pgm_read_*() macros to read it from program memory. - Try not to read the same value from program memory more than once, it will be terribly inefficient in the code. - Remember that pgm_read*() are MACROS, so be careful about potential side effects, i.e. try not to do auto-increments of the parameter variable.

for(i = 0; i < 2; i++)
{
// Get the beginning address of the string from the array in Program Space. // string will contain the adress of the string store in Program Space.
   string = pgm_read_word(&(array[i]));

   do
   {
      // Read the byte at address stored in string.
       byte = pgm_read_byte(string);
       if(byte != 0)
       {
          lcdPut(byte);
       }
      // Increment the Program Space address.
       string++;
   } while(byte);   // Check for end of string.
}

Note that the above example has not been tested. Let me know if this works for you.

Eric





reply via email to

[Prev in Thread] Current Thread [Next in Thread]