找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2023|回復(fù): 0
收起左側(cè)

LCD1602字符液晶滾動演示程序

[復(fù)制鏈接]
ID:799504 發(fā)表于 2020-7-8 09:22 | 顯示全部樓層 |閱讀模式

LCD1602字符液晶滾動演示

LCD1602字符液晶滾動演示


單片機源程序如下:
  1. //main.c
  2. /*        名稱:LCD1602字符液晶滾動演示程序
  3.         說明:K1~K3按鈕分別實現(xiàn)液晶垂直或水平滾動顯示及暫停與繼續(xù)控制。
  4. */
  5. #include<reg51.h>
  6. #include<string.h>
  7. #define uchar unsigned char
  8. #define uint unsigned int
  9. void Initialize_LCD();
  10. void DelayMS(uint ms);
  11. void ShowString(uchar,uchar,uchar *);
  12. sbit K1=P3^0;
  13. sbit K2=P3^1;
  14. sbit K3=P3^2;
  15. uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";
  16. //待滾動顯示的信息段落,每行不超過80個字符,共6行
  17. uchar const Line_Count=6;        
  18. uchar code Msg[][80]=
  19. {
  20.         "Many CAD users dismiss schematic capture as a necessary evil in the ",
  21.         "process of creating PCB layout but we have always disputed this point ",
  22.         "of view. With PCB layout now offering automation of both component ",
  23.         "can often be the most time consuming element of the exercise.",
  24.         "And if you use circuit simulation to develop your ideas, ",
  25.         "you are going to spend even more time working on the schematic."
  26. };
  27. //顯示緩沖(2行)
  28. uchar Disp_Buffer[32];
  29. //垂直滾動顯示
  30. void V_Scroll_Display()
  31. {
  32.         uchar i,j,k=0;
  33.         uchar *p=Msg[0];
  34.         uchar *q=Msg[Line_Count]+strlen(Msg[Line_Count]);
  35.         //以下僅使用顯示緩沖的前16字節(jié)空間
  36.         while(p<q)
  37.         {
  38.                 for(i=0;i<16&&p<q;i++)
  39.                 {        //消除顯示緩沖中待顯示行首尾可能出現(xiàn)的空格
  40.                         if((i==0||i==15)&&*p==' ') p++;
  41.                         if(*p!='\0')
  42.                         {
  43.                                 Disp_Buffer[i]=*p++;
  44.                         }
  45.                         else
  46.                         {
  47.                                 if(++k>Line_Count) break;
  48.                                 p=Msg[k];                                        //p指向下一串的首地址
  49.                                 Disp_Buffer[i]=*p++;
  50.                         }
  51.                 }
  52.                 //不足16個字符時空格補充
  53.                 for(j=i;j<16;j++) Disp_Buffer[j]=' ';
  54.                 //垂直滾動顯示
  55.                 while(F0) DelayMS(5);
  56.                 ShowString(0,0,"                 ");
  57.                 DelayMS(150);
  58.                 while(F0) DelayMS(5);
  59.                 ShowString(0,1,Disp_Buffer);
  60.                 DelayMS(150);
  61.                 while(F0) DelayMS(5);
  62.                 ShowString(0,0,Disp_Buffer);
  63.                 ShowString(0,1,"                 ");
  64.                 DelayMS(150);
  65.         }
  66.         //最后清屏
  67.         ShowString(0,0,"                 ");
  68.         ShowString(0,1,"                 ");
  69. }
  70. //水平滾動顯示
  71. void H_Scroll_Display()
  72. {
  73.         uchar i,j,k=0,L=0;
  74.         uchar *p=Msg[0];
  75.         uchar *q=Msg[Line_Count]+strlen(Msg[Line_Count]);
  76.         //將32個字符的顯示緩沖前16個字符設(shè)為空格
  77.         for(i=0;i<16;i++) Disp_Buffer[i]=' ';
  78.         while(p<q)
  79.         {
  80.                 //忽略緩沖中首尾可能出現(xiàn)的空格
  81.                 if((i==16||i==31)&&*p==' ') p++;
  82.                 for(i=16;i<32&&p<q;i++)
  83.                 {        
  84.                         if(*p!='\0')
  85.                         {
  86.                                 Disp_Buffer[i]=*p++;
  87.                         }
  88.                         else
  89.                         {
  90.                                 if(++k>Line_Count) break;
  91.                                 p=Msg[k];                                        //p指向下一串的首地址
  92.                                 Disp_Buffer[i]=*p++;
  93.                         }
  94.                 }
  95.                 //不足32個字符時空格補充
  96.                 for(j=i;j<32;j++) Disp_Buffer[j]=' ';
  97.                 //水平滾動顯示
  98.                 for(i=0;i<=16;i++)
  99.                 {
  100.                         while(F0) DelayMS(5);
  101.                         ShowString(0,L,Disp_Buffer+i);
  102.                         while(F0) DelayMS(5);
  103.                         DelayMS(20);
  104.                 }
  105.                 L=(L==0)?1:0;                //行號在0,1間交替
  106.                 DelayMS(300);
  107.         }
  108.         //如果顯示結(jié)束時停留在第0行,則清除第1行的內(nèi)容
  109.         if(L==1) ShowString(0,1,"                 ");        
  110. }
  111. //外部中斷0,由K3控制暫停與繼續(xù)顯示
  112. void EX_INT0() interrupt 0
  113. {
  114.         F0=!F0;                //暫停與繼續(xù)顯示控制標志位
  115. }
  116. //主程序
  117. void main()
  118. {
  119.         uint Count=0;
  120.         IE=0x81;                //允許外部中斷0
  121.         IT0=1;                        //下降沿觸發(fā)
  122.         F0=0;                        //暫停與繼續(xù)顯示控制標志位
  123.         Initialize_LCD();
  124.         ShowString(0,0,Prompt);
  125.         ShowString(0,1,Prompt+16);
  126.         while(1)
  127.         {
  128.                 if(K1==0)
  129.                 {
  130.                         V_Scroll_Display();
  131.                         DelayMS(300);
  132.                 }
  133.                 else
  134.                 if(K2==0)
  135.                 {        
  136.                         H_Scroll_Display();
  137.                         DelayMS(300);        
  138.                 }
  139.         }
  140. }
  141. //LCD1602.c
  142. /*        名稱:液晶控制與顯示程序
  143.         說明:本程序是通用的1602液晶控制程序。
  144. */
  145. #include<reg51.h>
  146. #include<intrins.h>
  147. #define uchar unsigned char
  148. #define uint unsigned int
  149. sbit RS=P2^0;
  150. sbit RW=P2^1;
  151. sbit EN=P2^2;
  152. //延時
  153. void DelayMS(uint ms)
  154. {
  155.         uchar i;
  156.         while(ms--) for(i=0;i<120;i++);
  157. }
  158. //忙檢查
  159. uchar Busy_Check()
  160. {
  161.         uchar LCD_Status;
  162.         RS=0;                                //寄存器選擇
  163.         RW=1;                                //讀狀態(tài)寄存器
  164.         EN=1;                                //開始讀
  165.         DelayMS(1);
  166.         LCD_Status=P0;
  167.         EN=0;
  168.         return LCD_Status;
  169. }
  170. //寫LCD命令
  171. void Write_LCD_Command(uchar cmd)
  172. {
  173.         while((Busy_Check()&0x80)==0x80);        //忙等待
  174.         RS=0;                //選擇命令寄存器
  175.         RW=0;                //寫
  176.         EN=0;        
  177.         P0=cmd;EN=1;DelayMS(1);EN=0;
  178. }
  179. //發(fā)送數(shù)據(jù)
  180. void Write_LCD_Data(uchar dat)
  181. {
  182.         while((Busy_Check()&0x80)==0x80);        //忙等待
  183.         RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1);EN=0;
  184. }
  185. //LCD初始化
  186. void Initialize_LCD()
  187. {
  188.         Write_LCD_Command(0x38);DelayMS(1);
  189.         Write_LCD_Command(0x01);DelayMS(1);        //清屏
  190.         Write_LCD_Command(0x06);DelayMS(1);        //字符進入模式:屏幕不動,字符后移
  191.         Write_LCD_Command(0x0c);DelayMS(1);        //顯示開,光標關(guān)
  192. }
  193. //顯示字符串
  194. void ShowString(uchar x,uchar y,uchar *str)
  195. {
  196.         uchar i=0;
  197.         if(y==0) Write_LCD_Command(0x80|x);        //設(shè)置顯示起始位置
  198.         if(y==1) Write_LCD_Command(0xc0|x);
  199.         for(i=0;i<16;i++)                                        //輸出字符串
  200.         {
  201.                 Write_LCD_Data(str[i]);
  202.         }
  203. }
復(fù)制代碼

回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表