标题:
一个关于LCD1602延时的问题
[打印本页]
作者:
290435619@qq
时间:
2020-2-12 22:28
标题:
一个关于LCD1602延时的问题
请问一下各位大神,我看LCD1602的说明文档上面写的延时都是ns级别的,我用的单片机是12M晶振的,所以我在写数据的时候没有用延时,但是LCD上就显示不出数据来,我加了延时之后,LCD上就有数据了,而且不同的延时,LCD上显示的数据还不同,这是怎么回事啊?
作者:
csmyldl
时间:
2020-2-13 13:26
是传送数据的时序不符合,特别是应答的时序
作者:
290435619@qq
时间:
2020-2-13 20:56
csmyldl 发表于 2020-2-13 13:26
是传送数据的时序不符合,特别是应答的时序
我是按照教程上面写的,但是我看LCD1602的说明文档上面写的ns,所以我就想应该可以不用延时,于是我就用短的延时和长的延时分别对比了一下,发现有很大差异
作者:
CZFMDZ
时间:
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(); //检测忙或延时一段时间 此行一定要,否则执行完立即显示该字符时会不显示
}
作者:
CZFMDZ
时间:
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中的内容
作者:
辰景
时间:
2020-2-14 17:29
LCD1602模块的时序图决定了它的正常显示,时序图里有延时时间
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1