LCD1602 四线驱动程序
只用4条数据线就可以驱动1602液晶屏。见有朋友寻找这种方案,特贴出来。源程序来源于网上,但经本人修改验证并加上注释。
其中的RS、RW、E与8线驱动一样。此方案可以省出4条单片机的管脚作别的用途,对于管脚紧张的项目,很有价值。
如果认为好,请加分。
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - 接口定义
# define LCD_DB P2 //
sbit LCD_RS=P0^7; //
sbit LCD_RW=P0^6; //
sbit LCD_E=P0^5; //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - 自定义数据类型
# define uchar unsigned char
# define uint unsigned int
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - 定义子程序函数
void LCD_init(void); // - - 初始化LCD1602函数
void LCD_write_H4bit_command(uchar dat);
void LCD_write_L4bit_command(uchar dat);
void LCD_delay_10us(uint n); // - - 10微秒的延时子程序
void LCD_delay_50us(uint n); // - - 50微秒的延时子程序
void LCD_write_4bit_command(uchar command); // - - 向LCD1602写指令函数
void LCD_write_4bit_data(uchar dat); // - - 向LCD1602写数据函数
/ - - 初始化LCD1602
void LCD_init(void)
{
LCD_delay_50us(20);
LCD_RS=0; // - - 指令
LCD_RW=0; // - - 写入
LCD_E=0; // - - 使能
LCD_write_L4bit_command(0x03); // - - 设置4位格式,2行,5x7
LCD_delay_50us(2);
LCD_write_L4bit_command(0x03); // - - 设置4位格式,2行,5x7
LCD_delay_50us(10);
LCD_write_L4bit_command(0x03); // - - 设置4位格式,2行,5x7
LCD_delay_50us(2);
LCD_write_L4bit_command(0x02); // - - 设置4位格式,2行,5x7
LCD_delay_50us(2);
LCD_write_4bit_command(0x28); // - - 设置4位格式,2行,5x7
LCD_delay_10us(10);
LCD_write_4bit_command(0x0c); // - - 整体显示,关光标,不闪烁
LCD_delay_10us(10);
LCD_write_4bit_command(0x06); // - - 设定输入方式,增量不移位
LCD_delay_10us(10);
LCD_write_4bit_command(0x01); // - - 清除屏幕显示
LCD_delay_50us(40);
}
/*
上面初始化程序最重要的是连续三次写入0x03,在液晶控制器的技术手册中已经有说明,特别是在电压不足的时候,以这样的方法进行初始化,
容易成功。*/
//*******************************
// - - 向LCD1602写数据或指令
特别注意:
//LCD_DB:其实就是P2口,且只用了高四位,这样低四位可用于别的用途;
//(LCD_DB&0x0F)的结果是保留P2口现存内容的低四位,只有这样,才不会影响低四位状态,方便别的应用;
//(dat&0xF0)的结果是屏蔽dat低四位,保留高四位
//(LCD_DB&0x0F)|(dat&0xF0)的结果是将保留的高四位与低四位拼接成8位给P2
void LCD_write_H4bit_command(uchar dat)
{ //调用本函数只能将dat的高四位写入1602
LCD_delay_10us(10);//延时
LCD_DB=(LCD_DB&0x0F)|(dat&0xF0);
LCD_delay_10us(10);
LCD_E=1; // - - 允许
LCD_delay_10us(10);
LCD_E=0;
}
// 向LCD1602写低四位指令
void LCD_write_L4bit_command(uchar dat)
{//调用本函数只能将dat的低四位写入1602
dat<<=4;//首先,将dat低四位移动到高四位
LCD_delay_10us(10);
LCD_DB=(LCD_DB&0x0F)|(dat&0xF0);
LCD_delay_10us(10);
LCD_E=1; // - - 允许
LCD_delay_10us(10);
LCD_E=0;
}
// - - 向LCD1602写指令
void LCD_write_4bit_command(uchar dat)
{
LCD_delay_10us(10);
LCD_RS=0; // - - 指令
LCD_RW=0; // - - 写入
LCD_write_H4bit_command(dat);//高四位写入
LCD_write_L4bit_command(dat);//低四位写入
}
// - - 向LCD1602写数据
void LCD_write_4bit_data(uchar dat)
{
LCD_delay_10us(10);
LCD_RS=1; // - - 数据
LCD_RW=0; // - - 写入
LCD_write_H4bit_command(dat);
LCD_write_L4bit_command(dat);
}
void LCD_delay_10us(uint n) // - - 10微秒的延时子程序
{
uint i,j;
for(i=n*10;i>0;i--) // - - 晶振及单片机修改设置
for(j=2;j>0;j--);
}
void LCD_delay_50us(uint n) // - - 50微秒的延时子程序
{
uint i,j;
for(i=n*10;i>0;i--) // - - 晶振及单片机修改设置
for(j=22;j>0;j--);
}
|