3342|13

3401

帖子

0

TA的资源

五彩晶圆(中级)

楼主
 

LCD1602字符液晶滚动演示程序 [复制链接]

 

/* 名称:LCD1602字符液晶滚动演示程序

说明:K1~K3按钮分别实现液晶垂直或水平滚动显示及暂停与继续控制。

*/

#include<reg51.h>

#include<string.h>

#define uchar unsigned char

#define uint unsigned int

void Initialize_LCD();

void DelayMS(uint ms);

void ShowString(uchar,uchar,uchar *);

sbit K1=P3^0;

sbit K2=P3^1;

sbit K3=P3^2;

uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";

//待滚动显示的信息段落,每行不超过80个字符,共6

uchar const Line_Count=6;

uchar code Msg[][80]=

{

"Many CAD users dismiss schematic capture as a necessary evil in the ",

"process of creating PCB layout but we have always disputed this point ",

"of view. With PCB layout now offering automation of both component ",

"can often be the most time consuming element of the exercise.",

"And if you use circuit simulation to develop your ideas, ",

"you are going to spend even more time working on the schematic."

};

//显示缓冲(2行)

uchar Disp_Buffer[32];

//垂直滚动显示

void V_Scroll_Display()

{

uchar i,j,k=0;

uchar *p=Msg[0];

uchar *q=Msg[Line_Count]+strlen(Msg[Line_Count]);

//以下仅使用显示缓冲的前16字节空间

while(p<q)

{

for(i=0;i<16&&p<q;i++)

{ //消除显示缓冲中待显示行首尾可能出现的空格

if((i==0||i==15)&&*p==' ') p++;

if(*p!='\0')

{

Disp_Buffer[i]=*p++;

}

else

{

if(++k>Line_Count) break;

p=Msg[k]; //p指向下一串的首地址

Disp_Buffer[i]=*p++;

}

}

//不足16个字符时空格补充

for(j=i;j<16;j++) Disp_Buffer[j]=' ';

//垂直滚动显示

while(F0) DelayMS(5);

ShowString(0,0,"                 ");

DelayMS(150);

while(F0) DelayMS(5);

ShowString(0,1,Disp_Buffer);

DelayMS(150);

while(F0) DelayMS(5);

ShowString(0,0,Disp_Buffer);

ShowString(0,1,"                 ");

DelayMS(150);

}

//最后清屏

ShowString(0,0,"                 ");

ShowString(0,1,"                 ");

}

//水平滚动显示

void H_Scroll_Display()

{

uchar i,j,k=0,L=0;

uchar *p=Msg[0];

uchar *q=Msg[Line_Count]+strlen(Msg[Line_Count]);

//32个字符的显示缓冲前16个字符设为空格

for(i=0;i<16;i++) Disp_Buffer[i]=' ';

while(p<q)

{

//忽略缓冲中首尾可能出现的空格

if((i==16||i==31)&&*p==' ') p++;

for(i=16;i<32&&p<q;i++)

{

if(*p!='\0')

{

Disp_Buffer[i]=*p++;

}

else

{

if(++k>Line_Count) break;

p=Msg[k]; //p指向下一串的首地址

Disp_Buffer[i]=*p++;

}

}

//不足32个字符时空格补充

for(j=i;j<32;j++) Disp_Buffer[j]=' ';

//水平滚动显示

for(i=0;i<=16;i++)

{

while(F0) DelayMS(5);

ShowString(0,L,Disp_Buffer+i);

while(F0) DelayMS(5);

DelayMS(20);

}

L=(L==0)?1:0; //行号在01间交替

DelayMS(300);

}

//如果显示结束时停留在第0行,则清除第1行的内容

if(L==1) ShowString(0,1,"                 ");

}

//外部中断0,由K3控制暂停与继续显示

void EX_INT0() interrupt 0

{

F0=!F0; //暂停与继续显示控制标志位

}

//主程序

void main()

{

uint Count=0;

IE=0x81; //允许外部中断0

IT0=1; //下降沿触发

F0=0; //暂停与继续显示控制标志位

Initialize_LCD();

ShowString(0,0,Prompt);

ShowString(0,1,Prompt+16);

while(1)

{

if(K1==0)

{

V_Scroll_Display();

DelayMS(300);

}

else

if(K2==0)

{

H_Scroll_Display();

DelayMS(300);

}

}

}

//LCD1602.c

/* 名称:液晶控制与显示程序

说明:本程序是通用的1602液晶控制程序。

*/

#include<reg51.h>

#include<intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit RS=P2^0;

sbit RW=P2^1;

sbit EN=P2^2;

//延时

void DelayMS(uint ms)

{

uchar i;

while(ms--) for(i=0;i<120;i++);

}

//忙检查

uchar Busy_Check()

{

uchar LCD_Status;

RS=0; //寄存器选择

RW=1; //读状态寄存器

EN=1; //开始读

DelayMS(1);

LCD_Status=P0;

EN=0;

return LCD_Status;

}

//LCD命令

void Write_LCD_Command(uchar cmd)

{

while((Busy_Check()&0x80)==0x80); //忙等待

RS=0; //选择命令寄存器

RW=0; //

EN=0;

P0=cmd;EN=1;DelayMS(1);EN=0;

}

//发送数据

void Write_LCD_Data(uchar dat)

{

while((Busy_Check()&0x80)==0x80); //忙等待

RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1);EN=0;

}

//LCD初始化

void Initialize_LCD()

{

Write_LCD_Command(0x38);DelayMS(1);

Write_LCD_Command(0x01);DelayMS(1); //清屏

Write_LCD_Command(0x06);DelayMS(1); //字符进入模式:屏幕不动,字符后移

Write_LCD_Command(0x0c);DelayMS(1); //显示开,光标关

}

//显示字符串

void ShowString(uchar x,uchar y,uchar *str)

{

uchar i=0;

if(y==0) Write_LCD_Command(0x80|x); //设置显示起始位置

if(y==1) Write_LCD_Command(0xc0|x);

for(i=0;i<16;i++) //输出字符串

{

Write_LCD_Data(str[i]);

}

}

 

图片1.png (25.03 KB, 下载次数: 0)

图片1.png
此帖出自51单片机论坛

最新回复

拉低D7,手册上有   详情 回复 发表于 2020-7-29 15:02
点赞 关注
 

回复
举报

3401

帖子

0

TA的资源

五彩晶圆(中级)

沙发
 
uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";--------------这条语句有作用不
此帖出自51单片机论坛
 
 
 

回复

3401

帖子

0

TA的资源

五彩晶圆(中级)

板凳
 

    while((Busy_Check()&0x80)==0x80);------------一个变量与上一个十六进制数,啥东东

此帖出自51单片机论坛

点评

单片机发送指令后,液晶内部操作不是立即完成的,所以需要读取状态,查询当前状态是否空闲。   这个时间最长是预知的(有两种,与指令有关),有时为了节约一个IO口,也可以用延时。  详情 回复 发表于 2020-7-29 08:39
 
 
 

回复

2万

帖子

340

TA的资源

版主

4
 

uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";

显示屏的提示信息,不要也可以,最好要上

 

此帖出自51单片机论坛

点评

我仿真都没看到有这个字符串啊  咋回事  没显示这个  显示的是大括号里面的那6行  详情 回复 发表于 2020-7-29 16:43
 
 
 

回复

2万

帖子

340

TA的资源

版主

5
 

uchar是无符号字符类型的数据类型,

看前面已经定义了,uchar Busy_Check()

和0x80相与,没有问题。

 

 

此帖出自51单片机论坛

点评

这样与以下我就看不懂了。。。为什么是与上1000 0000  详情 回复 发表于 2020-7-29 14:40
 
 
 

回复

1万

帖子

24

TA的资源

版主

6
 
QWE4562009 发表于 2020-7-28 17:59     while((Busy_Check()&0x80)==0x80);------------一个变量与上一个十六进制数,啥东东 ...

单片机发送指令后,液晶内部操作不是立即完成的,所以需要读取状态,查询当前状态是否空闲,只有空闲才能写入下一个指令。

 

这个时间最长是预知的(有两种,与指令有关),有时为了节约一个IO口,也可以用延时。

此帖出自51单片机论坛

点评

单片机查询液晶是否空闲?那是如何查询的呢  详情 回复 发表于 2020-7-29 14:41
 
 
 

回复

3401

帖子

0

TA的资源

五彩晶圆(中级)

7
 
qwqwqw2088 发表于 2020-7-28 19:46 uchar是无符号字符类型的数据类型, 看前面已经定义了,uchar Busy_Check() 和0x80相与,没有问题。 ...

这样与以下我就看不懂了。。。为什么是与上1000 0000

此帖出自51单片机论坛

点评

1000 0000最高位是1,,, 所以,与,就可以判断Busy_Check()的值最高位是0还是1了 设备忙闲检查  详情 回复 发表于 2020-7-29 14:59
就是判断一下最高位是否为1  详情 回复 发表于 2020-7-29 14:46
 
 
 

回复

3401

帖子

0

TA的资源

五彩晶圆(中级)

8
 
dcexpert 发表于 2020-7-29 08:39 QWE4562009 发表于 2020-7-28 17:59     while((Busy_Check()&0x80)==0x80);---------- ...

单片机查询液晶是否空闲?那是如何查询的呢

此帖出自51单片机论坛

点评

拉低D7,手册上有  详情 回复 发表于 2020-7-29 15:02
 
 
 

回复

6105

帖子

4

TA的资源

版主

9
 
本帖最后由 damiaa 于 2020-7-29 14:49 编辑
QWE4562009 发表于 2020-7-29 14:40 这样与以下我就看不懂了。。。为什么是与上1000 0000

就是判断一下Busy_Check()返回值的最高位是否为1    

 

 

while((Busy_Check()&0x80)==0x80);   

这样最好看懂

while((Busy_Check()&(1<<7))==(1<<7));  

此帖出自51单片机论坛

点评

你那个更抽象  哈哈。1<<7 是啥意思    详情 回复 发表于 2020-7-29 16:44
 
 
 

回复

2万

帖子

340

TA的资源

版主

10
 
QWE4562009 发表于 2020-7-29 14:40 这样与以下我就看不懂了。。。为什么是与上1000 0000

1000 0000最高位是1,,,

所以,与,就可以判断Busy_Check()的值最高位是0还是1了
设备忙闲检查

此帖出自51单片机论坛

点评

恩    这个解释我懂了  但是为什么是查找最高位就可以判断设备忙还是闲呢  详情 回复 发表于 2020-7-29 16:45
 
 
 

回复

4008

帖子

0

TA的资源

版主

11
 
QWE4562009 发表于 2020-7-29 14:41 单片机查询液晶是否空闲?那是如何查询的呢

拉低D7,手册上有

此帖出自51单片机论坛
 
 
 

回复

3401

帖子

0

TA的资源

五彩晶圆(中级)

12
 
qwqwqw2088 发表于 2020-7-28 19:37 uchar code Prompt[]="Press K1 - K3 To Start Demo Prog"; 显示屏的提示信息,不要也可以,最好要 ...

我仿真都没看到有这个字符串啊  咋回事  没显示这个  显示的是大括号里面的那6行

此帖出自51单片机论坛
 
 
 

回复

3401

帖子

0

TA的资源

五彩晶圆(中级)

13
 
damiaa 发表于 2020-7-29 14:46 QWE4562009 发表于 2020-7-29 14:40 这样与以下我就看不懂了。。。为什么是与上1000 0000 就是判断 ...

你那个更抽象  哈哈。1<<7 是啥意思  

此帖出自51单片机论坛
 
 
 

回复

3401

帖子

0

TA的资源

五彩晶圆(中级)

14
 
qwqwqw2088 发表于 2020-7-29 14:59 1000 0000最高位是1,,, 所以,与,就可以判断Busy_Check()的值最高位是0还是1了 设备忙闲检查

恩    这个解释我懂了  但是为什么是查找最高位就可以判断设备忙还是闲呢

此帖出自51单片机论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表