单片机源程序如下:
- //main.c
- /* 名称: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; //行号在0,1间交替
- 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]);
- }
- }
复制代码
|