代码之家  ›  专栏  ›  技术社区  ›  fasseg

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

  •  2
  • fasseg  · 技术社区  · 15 年前

    我有一个LCD,连接到一个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++);
        }
    }
    

    这只会让我的液晶屏上出现乱码,表明ASCII值已经远离了。当我试图传递空字符串时( send_string("") )液晶显示器上至少显示三个乱七八糟的字符。

    4 回复  |  直到 13 年前
        1
  •  3
  •   Peter Mortensen Pieter Jan Bonestroo    14 年前

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

    所有这些和更多都被很好地解释了 here . 我也建议你试试 AVR Freaks 这些问题的论坛。在这些问题上,那里的人肯定比StackOverflow用户更有经验,并且总是乐于提供帮助。

        2
  •  1
  •   Keith Randall    15 年前

    我看不出你的代码有什么明显的问题(不是说我知道如何与Atmega32对话)。尝试在调试器下运行它并打印 c 每次调用 send_char ,或者只是 printf("%d\n", (int)c); 作为第一行 发送字符 .

        3
  •  1
  •   Peter Mortensen Pieter Jan Bonestroo    14 年前

    这对我有效:

    #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() 打电话看看它是否改变了你观察到的行为。

        4
  •  1
  •   Peter Mortensen Pieter Jan Bonestroo    14 年前

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

    首先,必须通过PROGMEM from将文本添加到ROM中 <avr/pgmspace.h> :

    const char msg[] PROGMEM = "Test";
    

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

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

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