lcd与atmega16连接

时间:2014-06-16 15:44:12

标签: avr lcd

我尝试将lcd与atmega16接口,我的lcd是jhd 162A。我附加了代码以及原理图。每当我连接相应的引脚时,只看到黑点,而不是我想要显示的内容。我不知道我的问题是什么。我还附上了原理图。!

#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 8000000L

#define lcd_data    PORTC
#define control     PORTB
#define rs          PB2
#define rw          PB1
#define en          PB0

void lcd_init (void);
void lcd_command(unsigned char cmd);
void lcd_write(unsigned char data);
void lcd_string(unsigned char *str);
void dis_cmd(char cmd_value);
void dis_write(unsigned char data);

int main()
{
    DDRB = 0xFF;
    DDRC = 0xFF;

    lcd_init();
    _delay_ms(50);

    _delay_ms(1);
    lcd_str("PROGRAMMING");
    _delay_ms(50);
    dis_cmd(0xc0);
    lcd_str("IS FUN");
     return 0;
}

void lcd_init (void)
{
    dis_cmd(0x02); //initialises lcd  on 4 bits mode
    _delay_ms(1);
    dis_cmd(0x28); //initialises lcd to use 2 line and 5*7 matrix ie 16*2 lcd on 8 bits
    _delay_ms(1);
    dis_cmd(0x01);//clears lcd screen
    _delay_ms(1);
    dis_cmd(0x0E);//display ON cursor ON
    _delay_ms(1);
    dis_cmd(0x80);//cursor is set on the 1st line
    _delay_ms(1);
    return;

}

void lcd_command(unsigned char cmd)
{
    lcd_data =cmd;
    control = (0<<rs)| (0<<rw) | (1<<en); // setting rs to 0 is command mode when rw=0 write mode
    _delay_ms(1);
    control = (0<<rs)| (0<<rw) | (0<<en);
    _delay_ms(50);

    // 2ta control command is used for the high to low transition of enable as the code works on the falling 
    // edge of the enable en
    return;
}

void lcd_write(unsigned char data)
{
    lcd_data= data;
    control = (1<<rs)| (0<<rw) | (1<<en); // setting rs to 0 is command mode when rw=0 write mode
    _delay_ms(1);
    control = (1<<rs)| (0<<rw) | (0<<en);
    _delay_ms(50);
    return;
}

void dis_write(unsigned char data)
{
    char data1;

    data1 = data & 0xF0;        //mask lower nibble because PA4-PA7 pins are used. 
    lcd_write(data1);


    data1 = ((data<<4) & 0xF0); //shift 4-bit and mask
    lcd_write(data1);

    return;
                // send to LCD

}
void lcd_str(unsigned char *str)
{
    int i = 0;
    while(str[i] != '\0')
    {
        dis_write(str[i]);
        i++;

    }
    return;

}
void dis_cmd(char cmd_value)
{
    char cmd_value1;

    cmd_value1 = cmd_value & 0xF0;      //mask lower nibble because PB4-PA7 pins are used. 
    lcd_command(cmd_value1);            // send to LCD

    cmd_value1 = ((cmd_value<<4) & 0xF0);   //shift 4-bit and mask
    lcd_command(cmd_value1);            // send to LCD
}

3 个答案:

答案 0 :(得分:0)

我认为您没有执行所需的init序列。在lcd_init()中,您首先发送函数集。

然而,显示器在此之前等待一个序列:

enter image description here

我不确定如何使用4位接口处理这个问题,但我认为这就是DB3-0为什么不关心&#34;。您可能只需要在4位总线上应用DB7-4(阅读数据表)。

我会在启动时等待几百毫秒,以确保Vcc稳定。然后按照

等放松时间按照重置顺序

POWERON
等待200ms
发送说明
等待20ms
发送说明
等待5ms
发送说明
等待5ms
发送功能组
...

由于您没有轮询忙碌标志,我将在所有以下指令之间至少等待1ms。

答案 1 :(得分:0)

您在lcd_init中定义了四位模式,并且您的编程是针对8位模式的。

对于8位模式,请像这样使用

void lcd_init (void)
{
    dis_cmd(0x02); //initialises lcd  on 4 bits mode
    _delay_ms(1);
    dis_cmd(0x38); //initialises lcd to use 2 line and 5*7 matrix ie 16*2 lcd on 8 bits
    _delay_ms(1);
    dis_cmd(0x01);//clears lcd screen
    _delay_ms(1);
    dis_cmd(0x0E);//display ON cursor ON
    _delay_ms(1);
    dis_cmd(0x80);//cursor is set on the 1st line
    _delay_ms(1);
    return;

}

而且, PORTC有时会产生lcd问题,为此你必须禁用JTAG

答案 2 :(得分:0)

您的代码中存在两个问题: -

1)你正在使用命令&#34; dis_cmd(0×28);&#34;它定义了4位模式。如果你想使用8位模式改变它&#34; dis_cmd(0x38);&#34;

2)要么不将PORTC用于lcd数据,要么禁用JTAG。使用JTAG时,PORTC不会向lcd提供数据。我不知道背后的原因,但我已经了解了自己的经验。