[英]Displaying ASCII characters from an array on a LCD with ATmega32
我有一个连接到Atmega32的LCD,使用此功能可以处理单个字符:
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("")
)时,LCD上至少会显示三个乱码。
首先,似乎您正在使用avr-gcc编译器。 当对嵌入式设备提出问题时,您总是需要说出您使用的是哪个编译器。
现在,我将尝试帮助您了解代码的问题以及解决方案起作用的原因。 您定义的函数:
void send_string(const char * msg);
在RAM中需要一个字符串指针。 不必使用const
关键字,编译器仍希望该字符串位于RAM中。 因此,如果您在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上运行的功能的通用约定。
所有这些以及更多内容都在这里得到了很好的解释。 我也建议您尝试AVR Freaks论坛以解决此类问题。 与Stack Overflow用户相比,那里的人们肯定会在这些问题上有更多的经验,并且总是乐于提供帮助。
我没有发现您的代码有任何明显的错误(不是我知道如何与Atmega32对话)。 尝试在调试器下运行它,并在每次调用send_char
打印c
,或者仅将printf("%d\\n", (int)c);
放入printf("%d\\n", (int)c);
作为send_char
的第一行。
这对我有用:
#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;
}
在您的代码中,插入sleep(1);
在send_char()
调用之后,查看它是否改变了您观察到的行为。
这可以在我的Atmel控制器上运行(尽管我不知道为什么):
首先必须通过<avr/pgmspace.h>
PROGMEM将文字添加到ROM中:
const char msg[] PROGMEM = "Test";
然后将文字复制到控制器RAM中的缓冲区中:
char buf[strlen(msg)];
strcpy_P(buf,msg);
现在可以按预期使用send_string(msg)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.