《单片机原理及应用》第二版 例5-9
用单片机控制LCD1602液晶显示模块,使其显示两行文字:“Welcome To”与“Jian China”,如下图所示,在Proteus中,LCD1602液晶显示模块的对应仿真模型为LM016L。
LM016L的属性如下:
1.每行字符数位16,行数为2。
2.时钟为250KHZ。
3.第1行字符的地址为80H~8FH
4.第2行字符的地址为C0H~CFH
参考代码:
#include <REGX52.H>
#include<intrins.h> //包含_nop_()空函数指令的头文件
#define uchar unsigned char
#define uint unsigned int
#define out P2
sbit RS=P3^0; //位变量
sbit RW=P3^1; //位变量
sbit E=P3^2; //位变量
void lcd_initial(void); //声明LCD初始化函数
void check_busy(void); //声明检查忙标志位函数
void write_command(uchar com); //声明写命令函数
void write_data(uchar dat); //声明写数据函数
void string(uchar ad,uchar* s); //声明显示字符串函数
void delay(uint j) //1ms延时函数
{
uchar i=250;
for(;j>0;j--)
{
while(--i);
i=249;
while(--i);
i=250;
}
}
void main()
{
lcd_initial(); //调用对LCD初始化函数
while(1)
{
string(0x85,"Welcome To"); //从左边第6个字符处开始,显示第1行字符串
string(0xC2,"Jian China"); //从左边第3个字符处开始,显示第2行字符串
delay(100); //延时
write_command(0x01); //写入清屏命令
delay(100); //延时
}
}
void check_busy(void) //检查忙标志位函数
{
uchar dt;
do
{
dt=0xff;
E=0;
RS=0; //按规定RS=0,E=1时才可以读标志位
RW=1; //读操作
E=1;
dt=out; //out为P2口,将P2口的状态送入dt中
}while(dt&0x80); //如果忙标志位BF=1,继续循环检测,等待BF=0时才能跳出循环
E=0;
}
void write_command(uchar com) //写命令函数
{
check_busy(); //写命令前先检查忙标志位BF
E=0;
RS=0; //按规定RS=0,RW=0时,才可以写入命令
RW=0; //写操作
out=com; //将命令com写入P2口
E=1; //写命令时,E应为正脉冲,即正跳变,所以前面先把E置0
_nop_(); //空操作一个机器周期,等待硬件反应
E=0;
delay(1);
}
void write_data(uchar dat) //写数据函数
{
check_busy(); //写数据前先检查忙标志位BF
E=0;
RS=1;
RW=0; //按规定RS=1,RW=0时,才可以写入命令
out=dat; //将数据dat从P2口输出,即写入LCD1602液晶显示模块
E=1; //写命令时,E应为正脉冲,即正跳变,所以前面先把E置0
_nop_(); //空操作一个机器周期,等待硬件反应
E=0; //E由高电平置为低电平,写数据操作结束
delay(1);
}
void lcd_initial(void) //LCD初始化函数
{
write_command(0x38); //写入命令0x38,即8位数据,两行显示,5*7点阵
write_command(0x0c); //写入命令0x0c,即开整体显示,光标关,无闪烁
write_command(0x06); //写入命令0x06,即光标右移
write_command(0x01); //写入命令0x01,即清屏
delay(1);
}
void string(uchar ad,uchar* s) //显示字符串函数
{
write_command(ad);
while(*s>0)
{
write_data(*s++);
delay(100);
}
}