oufuqiang 发表于 2010-4-2 23:20:55

LCD1602字符液晶驱动程序 STC89C51RC 12MHz 12T 每一行都有注释,与菜鸟共勉。

方便保存交流,打印成PDF
点击此处下载 ourdev_543334.pdf(文件大小:55K) (原文件名:a89c51+lcd1602@12MHz.pdf)
http://cache.amobbs.com/bbs_upload782111/files_28/ourdev_543335.PNG
(原文件名:temp.PNG)

LCD1602 2×16 字符型液晶驱动程序的研究与试写2010-04-02 23:31       这段时间放假,因此终于有时间来做些小东西了,最近准备做一个恒温烙铁,要用到LCD液晶,由于以前买了一个一直没用过,所以在液晶模块编程方面的经验为0.刚好了,今天花了半天的时间研究终于有了研究成果。

      本人研究步骤如下:

      1、翻箱底,找出多年前买的液晶模块。

      2、查询模块的数据手册(datasheet),确定信号引脚

      3、根据手册信息建立供电电路连接和数据信号的链接

      4、阅读模块手册中的时序操作,编写出读写底层函数

      5、阅读命令控制字描述,确定控制字数值

      6、参考网络上其他人的程序,验证自己的阅读结果是否有方向性错误

      7、编写测试程序,让液晶模块显示出想要显示的数值、

以下即为研究结果。

#include <reg51.h>
sbit rs=P3^3;//指令数据选择
sbit rw=P3^4;//读写选择
sbit clk=P3^5;//使能脉冲
unsigned char code Code1[]="0123456789ABCDEF";//文字数组
sbit clear = P2^0;//清屏按钮
sbit key1 = P2^1;//写第一行按钮
sbit key2 = P2^2;//写第二行按钮
sbit key3 = P2^3;//显示模式变更测试按钮

void delay2ms()//2064周期延时
{
unsigned char temp1;
while(--temp1);
while(--temp1);
while(--temp1);
while(--temp1);
}

void check_busy()//忙检测
{
unsigned char busy;//临时字节
do
{
rs=0;//选择寄存器
rw=1;//读取
clk=1;//LCD将数据放到总线
busy=P1;//读入总线数据
clk=0;//关闭总线
busy=busy&0x80;//保留最高位
}while(busy);//判断是否为忙
}

void instructions(unsigned char INS)//写指令函数
{
check_busy();//写之前检测忙
rs=0;//选择指令寄存器
rw=0;//写操作
clk=1;//准备下降沿
P1=INS;//数据放到总线上
clk=0;//下降沿,数据写入LCD
}

void write_data(unsigned char dat)//写数据函数
{
check_busy();//写之前检测忙
rs=1;//选择数据寄存器
rw=0;//写操作
clk=1;//准备下降沿
P1=dat;//数据放到总线上
clk=0;//下降沿,数据写入LCD
}
void lcd_clear()//清除显示函数
{
instructions(0x01);//清除显示
delay2ms();//清屏后,按手册至少应延时1.53ms
}
void lcd_init()
{
rw=0;//写操作
instructions(0x38);//设置显示模式为2行,16字符,5×8点阵
delay2ms();//按手册应至少延时39us,但由于执行次数不多,统一使用2ms延时
instructions(0x0f);//设置输入模式为8位数据总线,光标增量移动,显示不移位
delay2ms();//按手册应至少延时39us,但由于执行次数不多,统一使用2ms延时
instructions(0x06);//开显示,关闭光标,不闪烁
delay2ms();//按手册应至少延时39us,但由于执行次数不多,统一使用2ms延时
}

void main()
{
unsigned char m;//辅助寻址指针变量
lcd_init();//LCD初始化
while(1)
{
if(!key1)//判断按键是否按下
    {
instructions(0x80+0x00);//写入显示缓冲区起始地址为1行1列
    delay2ms();//按手册应至少延时39us,但由于执行次数不多,统一使用2ms延时
for(m=0;m<16;m++)//将预先定义好的字符连续发送到LCD
   {
   write_data(Code1);//通过辅助变量查询数组并写入LCD
   }
}
if(!key2)//判断按键是否按下
    {
instructions(0x80+0x40);//写入显示缓冲区起始地址为2行1列
    delay2ms();//按手册应至少延时39us,但由于执行次数不多,统一使用2ms延时
for(m=0;m<16;m++)//将预先定义好的字符连续发送到LCD
   {
   write_data(Code1);//通过辅助变量查询数组并写入LCD
   }
}
if(!clear)//判断按键是否按下
    {
lcd_clear();//调用清屏函数
}
if(!key3)//判断按键是否按下
    {
instructions(0x0c);//改变显示模式
    delay2ms();//按手册应至少延时39us,但由于执行次数不多,统一使用2ms延时
}
}
}

oufuqiang 发表于 2010-4-3 01:01:15

视频:WMV格式,如果双击打不开就把后缀改回WMV
点击此处下载 ourdev_543347.avi视频文件大小:1.94M) (原文件名:1602LCD.avi)

xshui 发表于 2010-4-3 09:49:01

不错,用Proteus仿真了一下,可以运行,但数字1未显示出来。

xshui 发表于 2010-4-3 09:51:18

仿真图如下:
http://cache.amobbs.com/bbs_upload782111/files_28/ourdev_543373.JPG
(原文件名:k.JPG)

undeadhuman 发表于 2010-4-3 10:00:44

恒温烙铁的话,用数码管显示更好点。一个建议。

oufuqiang 发表于 2010-4-4 00:07:18

http://cache.amobbs.com/bbs_upload782111/files_28/ourdev_543554.JPG
(原文件名:液晶.JPG)

http://cache.amobbs.com/bbs_upload782111/files_28/ourdev_543555.JPG
(原文件名:液晶2.JPG)

szwangyan 发表于 2010-4-4 00:29:49

mark

xpstudio2003 发表于 2010-4-4 00:51:48

注释并不是多了就好..

注释也建议去排版

zhc7302 发表于 2010-4-4 18:19:50

mark

greenboys 发表于 2010-4-8 14:10:23

我仿真了 但是什么都没看到 只是有个光标在闪~~

lyk07351 发表于 2010-11-30 10:16:54

菜鸟来了,谢谢

newperson 发表于 2010-12-1 10:01:41

呵呵,好。。。

hweiyu 发表于 2010-12-12 15:33:40

不错,玩玩

wantone 发表于 2010-12-13 12:06:43

mark

zhangli2020 发表于 2010-12-14 16:58:02

DING!

beiguoqishi 发表于 2010-12-14 23:10:02

顶一下

wzr200408 发表于 2010-12-15 16:26:41

支持MARK

wjsh0826 发表于 2011-1-27 17:21:07

菜鸟来学习啦!

kouxiangtang 发表于 2011-1-27 19:30:31

mark

downtoearth 发表于 2011-1-27 20:35:48

mark

lcmdw 发表于 2011-8-23 14:55:02

mark

wit_stel 发表于 2011-8-23 15:47:36

if(key1==0)
{
delay(10); //延时消抖
if(key1==0)
{
    while(!key); //检测按键松开
   }
}

与if(!key1){}效果一样么???

ddcchh 发表于 2012-12-24 11:35:48

支持MARK!

flashria 发表于 2012-12-24 13:24:13

mark谢谢分享

boshi1987 发表于 2013-1-8 15:23:58

大哥 注释对其啊
页: [1]
查看完整版本: LCD1602字符液晶驱动程序 STC89C51RC 12MHz 12T 每一行都有注释,与菜鸟共勉。