使用ATmega32在LCD上显示阵列中的ASCII字符

时间:2010-11-23 19:12:29

标签: c gcc avr avr-gcc atmel

我有一台连接到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(""))时,液晶显示屏上会显示至少三个乱码。

4 个答案:

答案 0 :(得分:3)

首先,您似乎正在使用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上运行的不同函数的通用约定。

所有这些以及更多内容都得到了很好的解释here。我还建议你尝试 AVR Freaks 论坛来解决这些问题。那些人在这些问题上肯定比Stack Overflow用户更有经验,并且总是很乐意提供帮助。

答案 1 :(得分:1)

我没有看到任何明显错误的代码(不是我知道如何与Atmega32交谈)。尝试在调试器下运行它,并在每次调用c时打印send_char,或者只将printf("%d\n", (int)c);作为send_char的第一行。

答案 2 :(得分:1)

这对我有用:

#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(),看看它是否会改变您正在观察的行为。

答案 3 :(得分:1)

这适用于我的Atmel控制器(虽然我不知道为什么):

首先必须通过来自<avr/pgmspace.h>的PROGMEM将文字添加到ROM中:

const char msg[] PROGMEM = "Test";

然后将文字复制到控制器RAM中的缓冲区:

char buf[strlen(msg)];
strcpy_P(buf,msg);

现在可以按预期使用send_string(msg) ..