找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5218|回复: 5
打印 上一主题 下一主题
收起左侧

一个关于LCD1602延时的问题

[复制链接]
跳转到指定楼层
楼主
ID:692603 发表于 2020-2-12 22:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请问一下各位大神,我看LCD1602的说明文档上面写的延时都是ns级别的,我用的单片机是12M晶振的,所以我在写数据的时候没有用延时,但是LCD上就显示不出数据来,我加了延时之后,LCD上就有数据了,而且不同的延时,LCD上显示的数据还不同,这是怎么回事啊?
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:235200 发表于 2020-2-13 13:26 | 只看该作者
是传送数据的时序不符合,特别是应答的时序
回复

使用道具 举报

板凳
ID:692603 发表于 2020-2-13 20:56 | 只看该作者
csmyldl 发表于 2020-2-13 13:26
是传送数据的时序不符合,特别是应答的时序

我是按照教程上面写的,但是我看LCD1602的说明文档上面写的ns,所以我就想应该可以不用延时,于是我就用短的延时和长的延时分别对比了一下,发现有很大差异
回复

使用道具 举报

地板
ID:476390 发表于 2020-2-14 13:41 | 只看该作者
应该是时序问题,传一个验证过的程序给你参考。程序中用NOP短延时你也可以去掉或加长延时测试。
void LCMInit(void) //LCM初始化
{
        WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号 设置8位格式,2行,5*7
        WriteCommandLCM(0x3c,1); //显示模式设置,开始要求每次检测忙信号 设置8位格式,2行,5*10

//4         显示开/关控制         0 0 0 0   1 D C B         D=0关显示  D=1开显示  C=0无光标   C=1有光标   B=0光标不闪烁                B=1光标闪烁

        WriteCommandLCM(0x08,1); //显示关
        WriteCommandLCM(0x06,1); //显示光标移动设置 不移位
        WriteCommandLCM(0x0E,1); //显示开、有光标、光标不闪烁
        WriteCommandLCM(0x01,1); //清除屏幕显示
}

//写数据
void WriteDataLCM(unsigned char WDLCM)
{
        ReadStatusLCM(); //检测忙
        LCM_Data = WDLCM;
        LCM_RS = 1;
        LCM_RW = 0;

        LCM_E = 0;
        _nop_();_nop_();_nop_();//延时
        LCM_E = 1;
}

//写指令
void WriteCommandLCM(unsigned char WCLCM, bit BuysC) //BuysC为0时忽略忙检测
{
        if (BuysC==1){ ReadStatusLCM();} //根据需要检测忙
        LCM_Data = WCLCM;
        LCM_RS = 0;
        LCM_RW = 0;

        LCM_E = 0;
        _nop_();_nop_();_nop_();//延时
        LCM_E = 1;
}

//读数据
unsigned char ReadDataLCM(void)
{
        LCM_RS = 1;
        LCM_RW = 1;

        LCM_E = 0;
        _nop_();_nop_();_nop_();//延时
        LCM_E = 1;

        return(LCM_Data);
}


unsigned char ReadStatusLCM(void)// 读状态
{
        LCM_Data = 0xFF;
        LCM_RS = 0;
        LCM_RW = 1;

        LCM_E = 0;
        _nop_();_nop_();_nop_();//延时
        LCM_E = 1;

        while (LCM_Data & 0x80); //检测忙信号  忙时一直等待
        return(LCM_Data);
}



//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
        unsigned char ListLength=0;

        Y &= 0x1;        //限制 X不能大于15
        X &= 0xF;        //限制 Y不能大于1

        while (DData[ListLength]!=0) //若到达字串尾则退出
          {
                   if (X <= 20) //X坐标应小于0xF
            {
                     DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符                    
            }
                X++;        ListLength++;
          }
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
        Y &= 0x1;        //限制 X不能大于15
        X &= 0xF;        //限制 Y不能大于1

        if (Y==1) { X |= 0x40; }//当要显示第二行时地址码+0x40;
        X |= 0x80; // 算出指令码  写入显示地址时要求最高位D7恒定为高电平1

        WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码 X值>=0x80
        WriteDataLCM(DData);
}







//-----------------------------------------------------------------
//将8字节自定义字符的字模写到CGRAM中
void write_pic(unsigned char add, unsigned char *pic_num)
{
        unsigned char i;

        add=add<<3;
        for(i=0;i<8;i++)
        {
                WriteCommandLCM(0x40|add+i,1); //D7D6=01  D5~D3显示自定义字符时的字符号  D2~D0行号
                WriteDataLCM(*pic_num++);
        }
        ReadStatusLCM(); //检测忙或延时一段时间  此行一定要,否则执行完立即显示该字符时会不显示
}
回复

使用道具 举报

5#
ID:476390 发表于 2020-2-14 13:43 | 只看该作者
这是LCD1602使用总结
//读状态 输入 RS=L,R/W=H,E=H  输出 D0—D7=状态字
//读数据 输入 RS=H,R/W=H,E=H  输出 D0—D7=数据
//写数据 输入 RS=H,R/W=L,D0—D7=数据,E=高脉 冲 输出 无
//写指令 输入 RS=L,R/W=L,D0—D7=指令码,E=高 脉冲  输出 无
//
//DDRAM-- 就是显示数据RAM存放待显示的字符代码共80个字节
//CGROM-- 字模存储器内置192个常用字符的字模
//CGRAM-- 自定义的字符产生RAM  字符代码0~F 为用户自定义字符图形RAM

//1602液晶模块内部的控制器共有11条控制指令,如表10-14所示:
//序号         指令                                         RS R/W         D7 D6 D5 D4 D3 D2 D1 D0
//1         清显示                                         0         0         0 0 0 0 0 0 0 1                         执行时间1.64ms 清屏即将DDRAM全部填充为20H
//2         光标返回                                 0         0         0 0 0 0 0 0 1 *                         执行时间1.64ms 将光标定位到屏幕左上角
//3         置输入模式                                 0         0         0 0 0 0 0 1 I/D S                         执行时间40us   I/D=0写入数据后光标左移  I/D=1写入数据后光标右移  S=0写入数据后显示屏不移动  S=1写入数据后显示屏右移1字符
//4         显示开/关控制                         0         0        0 0 0 0 1 D C B                                执行时间40us   D=0关显示  D=1开显示  C=0无光标   C=1有光标   B=0光标不闪烁                B=1光标闪烁
//5         光标或字符移位                         0         0         0 0 0 1 S/C R/L * *                 执行时间40us   S/C R/L=00光标左移1格且AC减1         S/C R/L=01光标右移1格且AC加1 S/C R/L=10光标不动字符全部左移一格  S/C R/L=10光标不动字符全右移一格
//6         功能设定                                 0         0         0 0 1 DL N F * *                          执行时间40us   DL=0数据总线为4位 DL=1数据总线为8位 N=0显示1行 N=1显示2行 F=0时字符5*7点阵 F=1时字符5*10点阵
//7         置字符发生存贮器地址         0         0         0 1 字符发生存贮器地址                 执行时间40us   D5~D3显示自定义字符时的字符号  D2~D0行号
//8         置数据存贮器地址                 0         0         1 显示数据存贮器地址                 执行时间40us   设定一个要存入数据的DDRAM地址
//9         读忙标志或地址                         0         1         BF 计数器地址                                 执行时间40us   BF=1表示液晶屏忙暂无法接收数据或命令
//10         写数到CGRAM或DDRAM                 1         0         要写的数据内容                                 执行时间40us   将数据写入DDRAM或CGRAM
//11          从CGRAM或DDRAM读数                 1         1         读出的数据内容                                执行时间40us   读取DDRAM或CGRAM中的内容
回复

使用道具 举报

6#
ID:561669 发表于 2020-2-14 17:29 | 只看该作者
LCD1602模块的时序图决定了它的正常显示,时序图里有延时时间
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表