找回密码
 立即注册

QQ登录

只需一步,快速开始

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

LCD1602液晶滚动字符串单片机程序详细讲解和实验现象视频

[复制链接]
跳转到指定楼层
楼主
这里通过三种方法实现了单片机控制字符串的滚动

方法一:向液晶写入字符串后,连续发送0x1c指令可以是整个屏幕向左滚动,0x18向右滚动这个方法在我上传的程序中没有用到

方法二:通过软件的方法让液晶的整个屏幕滚动,效果和方法一相同,实现较复杂,不建议使用这种方法在lcd.c文件中封装成了rolling_screen()函数

方法三:由于上两种方法会将屏幕的上下两行同时滚动,无法实现一行滚动一行静止不动,所以方法三通过:每次打印后对写入首地址的移动和对字符串指针的移动来实现字符串的滚动效果,这种方法在led.c文件中封装成了rolling_str()函数,这个函数仅作原理示范,不建议直接调用,
在我的程序中我把这个函数分解后放入了定时器,利用定时器完成每一次刷新,main()函数中使用的就是定时器刷新的方法

另注:time.c文件中定义了延时和定时器初始化函数,是lcd.c的支持文件
关于程序更详细的说明我放在了PPT中,版本支持位2013+
程序工程使用Keil4建立仿真使用Proteus7.8,连接方式见lcd.h文件关于底层端口的定义

视频预览:


PPT内容预览(内含关于1602液晶滚动显示源程序的详细讲解):




仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include "lcd.h"
  2. #include "timer.h"


  3. void lcd_init( void )
  4. {
  5. //========厂家复位代码=============
  6.         delay_ms(15);
  7.         write_cmd(0x38);
  8.         delay_ms(5);
  9.         write_cmd(0x38);
  10.         delay_ms(5);
  11.         write_cmd(0x38);
  12.         wait_busy();
  13.         write_cmd(0x38);
  14.         wait_busy();
  15.         write_cmd(0x08);
  16.         wait_busy();
  17.         write_cmd(0x01);
  18.         wait_busy();
  19.     write_cmd(0x06); //写字符后地址加1, 光标加1
  20.         wait_busy();
  21.     write_cmd(0x0c); //清屏
  22. //=======复位代码结束===============

  23. }

  24. void show_str(char* str, char x, char y)         //指定位置打印字符串函数
  25. {
  26.         char *p = str;
  27.         wait_busy();
  28.         write_cmd(0x06);                                                 //地址递增,不滚屏
  29.         wait_busy();
  30.         write_cmd(0x80+y*0x40+x);                                 //计算地址
  31.         while(*p)                                                                 //打印字符串
  32.         {
  33.                 wait_busy();
  34.                 write_data(*(p));
  35.                 p++;       
  36.         }
  37.        
  38. }
  39. void rolling_screen( char* str, row)
  40. {
  41.         char *p = str;                                                  //指针指向字符串
  42.         wait_busy();
  43.         write_cmd(0x07);                                          //地址递增,滚屏
  44.         row=0x80+row*0x40+16;                                  //计算地址
  45.         wait_busy();
  46.         write_cmd(row);                                              //写地址
  47.         while(1)
  48.         {
  49.                 wait_busy();
  50.                 write_data(*(p));                                  //写一个字符
  51.                 delay_ms(300);                                          //稍加延时
  52.                 p++;                                                          //指针加1
  53.                 if(*p ==0)                                                  //全部写完之后再从头开始
  54.                 {
  55.                         p=str;
  56.                         write_cmd(row);
  57.                 }       
  58.         }

  59. }

  60. void rolling_str( char* str, row)
  61. {
  62.         char *p = str;
  63.         char  offset=16,n=0;
  64.         wait_busy();
  65.         write_cmd(0x06);                          //地址加一,不滚屏
  66.         row = 0x80+row*0x40;                  //计算在哪一行
  67.         wait_busy();
  68.         write_cmd(row+offset);                  //设初始地址
  69.         while(1)
  70.         {
  71. //==============1打印一行字符串==================
  72.                 while(*p)                                    //打印一行字符
  73.                         {
  74.                                 write_data(*p);
  75.                                 p++;
  76.                         }
  77.                 write_data(' ');          //扫尾,否则最后一个字符会拖成一个长长的小尾巴                          
  78.                 delay_ms(200);                          //稍加延时
  79. //=============2将字符串打印的位置移动============
  80.                 if(offset>0)offset--;          //字符串整体左移
  81.                 else n++;                                  //当移到头了,把字符串的头去掉
  82.                 write_cmd(row+offset);          //设置当前地址          
  83.                 p=str+n;                                  //从第n个字符开始打印,就是去掉字符串的头

  84.                 if(*p==0)                                  //字符串打印完了
  85.                 {
  86.                         write_data(' ');      //扫尾                               
  87.                         n=0;                                  //n归零
  88.                         p=str;                                  //重新载入字符串
  89.                         offset=16;
  90.                         write_cmd(row+offset);//重置偏置
  91.                 }                                        
  92.                                          
  93.         }       
  94. }

  95. void write_cmd( unsigned char cmd)
  96. {
  97.         RS = 0;                    //写命令
  98.         RW = 0;
  99.         DB = cmd;
  100.     LcdEN = 1;
  101.         delay_us(2);
  102.     LcdEN = 0;
  103. }
  104. void write_data(unsigned char dat)
  105. {
  106.     RS = 1;
  107.         RW = 0;
  108.     DB = dat;
  109.     LcdEN = 1;
  110.         delay_us(2);
  111.         LcdEN = 0;
  112. }

  113. void wait_busy( void )
  114. {
  115.         unsigned char sta=0x80;
  116.         DB = 0xff;                        //要先拉高
  117.         do
  118.         {
  119.                   RS = 0;
  120.                 RW = 1;
  121.             LcdEN = 1;
  122.                 delay_us(2);
  123.                 sta=DB;
  124.                 LcdEN = 0;
  125.                 _nop_();
  126.         }
  127.         while(sta&0x80);
  128. }


  129. void timer0() interrupt 1
  130. {
  131.         static bit ft0 = 1;                         //flag标记进来的是奇数次还是偶数次
  132.         static char *p;                                 //字符串指针,指向字符串的某个位置
  133.         static char offset=16,n=0;         //offse是在某一行的偏移地址,n与P配合
  134.         extern char *ss;                         //使用外部的字符串

  135.         TH0 = (65536-50000)/256;
  136.         TL0 = (65536-50000)%256;
  137. //=============1打印一行字符串========================
  138.         if(ft0)
  139.         {
  140.                 ft0 = 0;                                 //取反
  141.                 while(*p)                                   //打印一行字符
  142.                         {
  143.                                 write_data(*p);
  144.                                 p++;
  145.                         }
  146.                 write_data(' ');          //扫尾,否则最后一个字符会拖成一个长长的小尾巴                          
  147.         }
  148. //===========2对字符串进行移位==========================
  149.         else                                                  //将字符串移动到一个位置显示
  150.         {
  151.                 ft0 = 1;
  152.                 if(offset>0)offset--;          //字符串整体左移
  153.                 else n++;                                  //当移到头了,把字符串的头去掉

  154.                 write_cmd(0xc0+offset);          //设置当前地址          
  155.                 p=ss+n;                                  //从第n个字符开始打印,就是去掉字符串的头

  156.                 if(*p==0)                                  //字符串打印完了
  157.                 {
  158.                         write_data(' ');      //扫尾                               
  159.                         n=0;                                  //n归零
  160.                         p=ss;                                  //重新载入字符串
  161.                         offset=16;
  162.                         write_cmd(0xc0+offset);//重置偏置
  163.                 }
  164.         }
  165. }
复制代码


所有资料51hei提供下载:
ppt(程序详细讲解和实验现象视频).rar (3.46 MB, 下载次数: 22)
程序和仿真.rar (67.66 KB, 下载次数: 18)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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