avr-gcc-list
[Top][All Lists]
Advanced

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

Re: [avr-gcc-list] Bizarre string problem


From: Ned Konz
Subject: Re: [avr-gcc-list] Bizarre string problem
Date: Mon, 6 Sep 2004 07:26:48 -0700
User-agent: KMail/1.7

On Sunday 05 September 2004 10:30 pm, André - BOL wrote:
> For example: (I'm ommiting a lot of code, of course)
> chat t = 'T';
> UDR = t;  
> ==> this correctly prints T in my HyperTerminal
>  
> char t[1] = "T";
> UDR = t[0];
> ==> this prints nothing (Blank space)
>  
> I realized writing t[0] to any PORT lights test leds showing that the
> value is always 0xff !!!  This problem is giving me a huge head-ache.
> There's nothing wrong with this code (from C's point of view). Is there
> anything special I should be doing?
>  

Well, is your "T" supposed to be a constant string (that is, are you modifying 
the contents of t[] after initialization)?

If it is constant (that is, if you're just sending fixed strings), then you 
shouldn't be sticking it in RAM (which is what 'char t[1]' does).

Instead you should be putting it into program memory.

Think about what happens here:

char a[2]; // reserves space in RAM (if global) or in the space for auto vars 
(perhaps the stack); lets you change its contents

char b[2] = "T"; // reserves space as above; also sticks the characters 
{ 'T','\0' } into ROM to be copied into b[] at initialization time (only the 
first character is copied); you can change it later

const char c[2] = "T"; // as above, but doesn't let you change c[] later

However, if you 
#include <avr/pgmspace.h>

you can then say:

prog_char d[2] = "T"; // d[] is 2 bytes in ROM; you can't change it.


Why the [2] and not the [1]? C has a very weak definition of character strings 
that may be helpful here (you probably know this): it sticks a NUL character 
('\0' or 0) at the end of strings. If you're copying strings out of ROM or 
RAM and want to know when to stop (and aren't passing the lengths around), 
you may want to use this fact. So you have to leave space for the trailing 
NUL character.

Rather than counting, of course, you could just go:

const char e[] = "abcdef"; // e gets 7 bytes reserved in RAM and is 
initialized to { 'a', 'b', 'c', 'd', 'e', 'f', '\0' }

or

prog_char f[] = "ghi";

Note also that since the AVR micros have separate RAM and ROM (PROGMEM) memory 
spaces, there are two versions of each of the string functions:

char dest[4];
char src[4] = "abc";
prog_char romsrc[4] = "def";

strcpy(dest, src);
strcpy_P(dest, romsrc);

So you'd have a different subroutine for sending PROGMEM and RAM strings, too.

Take a look at avr/pgmspace.h and the enclosed files.

-- 
Ned Konz
http://bike-nomad.com

Attachment: test3.lst
Description: Text document

Attachment: test3.map
Description: Text document


reply via email to

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