我有一个液晶屏,连接到Atmega32上,使用这个函数处理单字符:
void send_char(uint8_t c){
PORTD = c; // set the output pins to the ascii value of the char
PORTB |= 0x05;
_delay_us(1);
PORTB &= 0xfa;
_delay_us(60);
PORTD = 0x00;
update_cursor();
}
我可以用一个字符作为参数来调用它:send_char('a');
,它可以工作。
然后我尝试在它周围包装一个send_string函数:
void send_string(const char * msg){
while (*msg != '\0'){
send_char(*msg++);
}
}
这只会在我的LCD上显示乱码,表明ASCII值已经很远了。当我尝试传递一个空字符串(send_string("")
)时,液晶屏上至少会显示三个乱码。
发布于 2010-11-26 22:42:23
首先,看起来您使用的是avr-gcc编译器。在为嵌入式设备提问时,您总是需要说明您使用的是哪种编译器。
现在,我将尝试帮助您了解代码的错误之处以及为什么您的解决方案有效。您定义的函数:
void send_string(const char * msg);
RAM中需要字符串指针。使用const
关键字并不重要,编译器仍然希望字符串在内存中。所以如果你在ROM中有一个字符串:
const char msg[] PROGMEM = "Test";
并尝试在您的函数中传递它:
send_string(msg);
它只是将一个无效的地址传递给它,因此会显示胡言乱语。相反,如果您首先将其复制到RAM,就像您在解决方案中所做的那样,它可以很好地工作:
char buf[strlen(msg)];
strcpy_P(buf,msg);
send_string(buf);
如果你想定义一个直接读取ROM字符串的函数,你可以这样做:
void send_string_P(const char *data)
{
while (pgm_read_byte(data) != 0x00)
send_char(pgm_read_byte(data++));
}
请注意_P
后缀。这是用于区分在ROM上操作的函数和在RAM上操作的函数的通用约定。
所有这些和更多都很好地解释了here。我还建议你尝试在论坛上解决这些问题。那里的人肯定比Stack和Overflow用户在这些问题上更有经验,并且总是乐于帮助。
发布于 2010-11-24 03:21:32
我看不出你的代码有什么明显的错误(不是说我知道如何与Atmega32对话)。尝试在调试器下运行它,并在每次调用时将c
输出到send_char
,或者只是将printf("%d\n", (int)c);
作为send_char
的第一行。
发布于 2010-11-24 03:29:03
这对我来说很有效:
#include <stdio.h>
#include <stdint.h>
void send_char(uint8_t c)
{
printf("%c", c);
}
void send_string(const char * msg)
{
while (*msg != '\0')
{
send_char(*msg++);
}
}
int main()
{
send_string("Stackoverflow!");
return 0;
}
在您的代码中,在send_char()
调用之后插入sleep(1);
,看看它是否会更改您正在观察的行为。
https://stackoverflow.com/questions/4259819
复制相似问题