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

Posted

技术标签:

【中文标题】使用 ATmega32 在 LCD 上显示阵列中的 ASCII 字符【英文标题】:Displaying ASCII characters from an array on a LCD with ATmega32 【发布时间】:2010-11-23 19:12:29 【问题描述】:

我有一个 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++);
    

这只会在我的 LCD 上显示乱码,表明 ASCII 值已经很远了。当我尝试传递一个空字符串 (send_string("")) 时,LCD 上至少会显示三个乱码。

【问题讨论】:

使用空字符串发送应该是什么都不做,因为*msg == '\0'。在此之后执行的代码是否可能会使您的显示出现乱码?显示是否正确初始化? 显示似乎已正确初始化,因为我可以使用 send_char() 发送任意数量的字符,一切都很好,除了从 send_char 更新光标位置之外,没有其他任何东西可以发送到显示。 【参考方案1】:

首先,您似乎正在使用 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 论坛来解决这类问题。那里的人在这些问题上肯定会比 *** 用户更有经验,并且总是乐于提供帮助。

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

这对我有用:

#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("***!");

    return 0;

在您的代码中,在send_char() 调用之后插入sleep(1);,看看它是否会改变您观察到的行为。

【讨论】:

【参考方案4】:

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

第一个必须通过 PROGMEM 从&lt;avr/pgmspace.h&gt; 将文字添加到 ROM:

const char msg[] PROGMEM = "Test";

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

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

现在send_string(msg)可以正常使用了..

【讨论】:

你没有告诉我们事先是如何定义 msg 的,你是如何调用 send_string() @limubs:就像我在我调用 send_string("") 的问题中写的那样。即使是空字符串,我也会得到乱码...... @caf:因为它与 const char msg="Test" 相同,但在 Atmega32 中,char 数组必须首先在 ROM 中,这不起作用。 @smeg4brains: char buf[] = "Test" 将在数据空间中创建buf,就像char buf[strlen(msg)]; 一样。 @smeg4brains:这看起来像个错误——char buf[1] = ""; 做了什么? char buf[1] = 0 ;呢?

以上是关于使用 ATmega32 在 LCD 上显示阵列中的 ASCII 字符的主要内容,如果未能解决你的问题,请参考以下文章

Atmega8独立工作必备电路

AVR Atmega168 I2C LCD 不想初始化

AVRDUDE 在 atmega32 上缓慢上传

用STM32进行编程在lcd上显示,但在LCD上显示的字体为啥反了?显示的是左边的上,这是啥问题?

stm32中的步进电机驱动和lcd显示问题

3.stm32 LCD