LCD 1602依旧还是那个1602,和51上的是没区别的。一定要注意其初始化的步骤和精确的毫秒级延时函数(晶振使用1MHz)。
LCD初始化步骤如下:
1、延时15ms
2、写指令38H(不检测忙信号)
3、(以后每次写指令、读/写数据操作均需要检测忙信号)
写指令38H:显示模式设置
4、写指令08H:显示关闭
5、写指令01H:显示清屏
6、写指令06H:显示光标移动设置
7、写指令0CH:显示开关光标设置
例程如下:
#include <iom16v.h>
#include <macros.h>
#define uint unsigned int
#define uchar unsigned char
#define RS_CLR PORTC&=~BIT(4) //类似51函数中的位定义
#define RS_SET PORTC|=BIT(4)
#define RS_OUT DDRC|=BIT(4)
#define RW_CLR PORTC&=~BIT(5)
#define RW_SET PORTC|=BIT(5)
#define RW_OUT DDRC|=BIT(5)
#define E_CLR PORTC&=~BIT(6)
#define E_SET PORTC|=BIT(6)
#define E_OUT DDRC|=BIT(6)
uchar table1[16]="0123456789876543";
uchar table2[16]="abcdefghijklmnop";
void delay_nms(uint timer) //毫秒级延时,并非准确的函数
{
uint a,b;
for(a=0;a<timer;a++)
{
for(b=0;b<300;b++);
}
}
void write_com(uchar com)
{
RS_SET;
RW_SET;
E_CLR;
RS_CLR;
RW_CLR;
PORTA=com;
delay_nms(1);
E_SET;
delay_nms(1);
E_CLR;
}
void write_data(uchar data)
{
RS_CLR;
RW_SET;
E_CLR;
RS_SET;
RW_CLR;
PORTA=data;
delay_nms(1);
E_SET;
delay_nms(1);
E_CLR;
}
void init(void)
{
DDRA=0XFF;
PORTA=0;
RS_OUT;
E_OUT;
RW_OUT;
delay_nms(20); //15即可
write_com(0x38);
delay_nms(5);
write_com(0x38);
delay_nms(5);
write_com(0x38);
write_com(0x38);
write_com(0x08);
write_com(0x01);
write_com(0x06);
write_com(0x0c);
}
void main(void)
{
uchar i;
init();
write_com(0x80);
for(i=0;i<16;i++)
{
write_data(table1[i]);
delay_nms(2);
}
write_com(0x80+0x40);
for(i=0;i<16;i++)
{
write_data(table2[i]);
delay_nms(2);
}
while(1);
}