找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3339|回复: 1
收起左侧

[原创]开源采用vb上位机串口对时的单片机16*64LED条屏仿真程序

[复制链接]
ID:405708 发表于 2018-10-10 20:48 | 显示全部楼层 |阅读模式
附件内有上位机VB源码和上位机安装程序,图片左上角的小界面是上位机程序,可获取电脑的时间和日期发送到16*64LED上显示(需要安装虚拟串口)。

单片机16*64LED条屏仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
220817e7exuwgbu0x1kbba.png

0.png

单片机源程序如下:
  1. #include "reg51.h"                                                         //包含51单片机的端口和内部寄存器定义的头文件
  2. typedef unsigned char uint8;                                                               //定义字符型
  3. typedef unsigned int  uint16;                                                              //定义整型
  4. typedef unsigned long uint32;                                                              //定义长整型
  5. uint32  dx,dxx;                                                                                      //字符显示偏移量
  6. uint8  brk,flag;
  7. uint8 BUFFER[22];
  8. sbit RTC_RST     =                P3^5;
  9. sbit RTC_SCLK         =                 P3^6;
  10. sbit RTC_IO                 =                P3^7;
  11. uint8 bdata AA;                                                                                               //brk延时用
  12. uint8 const code dat_bit_up[]={0xF7,0xFB,0xFD,0xFE,0x7F,0xBF,0xDF,0xEF};   //列高位扫描数据
  13. uint8 const code dat_bit_down[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //列低位扫描数据
  14. sbit AA7 = AA^7;
  15. #define READ_SECOND     0x81
  16. #define WRITE_SECOND    0x80
  17. #define READ_MINE       0x83
  18. #define WRITE_MINE      0x82
  19. #define READ_HOUR       0x85
  20. #define WRITE_HOUR                 0x84
  21. #define READ_DAY                0x87
  22. #define WRITE_DAY                0x86
  23. #define READ_MONTH                0x89
  24. #define WRITE_MONTH                0x88
  25. #define READ_WEEK                0x8b
  26. #define WRITE_WEEK                0x8a
  27. #define READ_YEAR       0x8d
  28. #define WRITE_YEAR                0x8c
  29. uint8 const code NUM[][16]=
  30. {

  31. {0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,0x00},/*"0",0*/
  32. …………
  33. …………
  34. …………限于本文篇幅 余下代码请从51黑下载附件…………

  35. {0x00,0x00,0x10,0x81,0x28,0xC2,0x21,0x44,0x21,0x24,0x22,0x00,0x3E,0xFF,0x22,0x44,0x22,0x44,0x22,0x7C,0x3E,0x44,0x22,0x7C,0x22,0x44,0x22,0xFE,0x3E,0x44,0x00,0x44},/*"期",4*/

  36. {0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00},/*":",0*/



  37. };
  38. /*****************************************************************************************************************************
  39. /     端口定义
  40. ******************************************************************************************************************************/


  41. #define LED_PORTH P0          //列高位
  42. #define LED_PORTL P2          //列低位
  43. sbit SER_CP=P3^4;             //串行时钟线
  44. sbit SER_SDA=P3^3;            //串行数据线
  45. sbit SER_EN=P3^2;             //74595数据有效线
  46. /*****************************************************************************************************************************
  47. /   函数名称:Delay
  48. /   作用: 延时子程序主要用于LED的消隐
  49. ******************************************************************************************************************************/

  50. void Delay()                  //延时子程序
  51. {
  52.     uint16  i,j;
  53.     for(i=0;i<0x14;i++)
  54.     for(j=0;j<0x05;j++);
  55. }
  56. /*****************************************************************************************************************************
  57. /   函数名称:LED_Ser
  58. /   作用: 发送串行数据到74LS595
  59. /   入口参数:dat 为要发送的数据8位
  60. ******************************************************************************************************************************/

  61. void LED_Ser(uint16 dat)
  62. {
  63.     uint8 i;
  64.     for(i=0;i<16;i++)          //共8BYTE
  65.     {
  66.         SER_SDA=dat&0x01;     //把数据的最后一位放在数据线上
  67.         dat>>=1;              //向右移位共8下这样可以发送8位数据
  68.         SER_CP=0;                     //
  69.         SER_CP=1;             //产生上升沿发送数据1BYTE
  70.     }
  71. }
  72. void LED_Ser_8(uint8 dat)
  73. {
  74.     uint8 i;
  75.     for(i=0;i<8;i++)          //共8BYTE
  76.     {
  77.         SER_SDA=dat&0x01;     //把数据的最后一位放在数据线上
  78.         dat>>=1;              //向右移位共8下这样可以发送8位数据
  79.         SER_CP=0;                     //
  80.         SER_CP=1;             //产生上升沿发送数据1BYTE
  81.     }
  82. }

  83. /*****************************************************************************************************************************
  84. /   函数名称:LED_Ser_EN
  85. /   作用: 用于在SER_EN口线上产生上长沿使74595发送的数据有效
  86. ******************************************************************************************************************************/

  87. void LED_Ser_EN()
  88. {
  89.     SER_EN=0;                         //
  90.     SER_EN=1;                 //产生上升沿脉冲用于使74595发的数据有效
  91. }
  92. /*****************************************************************************************************************************
  93. /   函数名称:LED_Disp
  94. /   作用: 在LED上显示字符或BMP
  95. /   入口参数:*dat 为要显示的字符或BMP的数据的首地址指针
  96. ******************************************************************************************************************************/

  97. void  LED_Disp(uint16 *dat)
  98. {
  99.     uint16  tmp;
  100.         uint8  a,j,i;
  101.     for(j=0;j<16;)
  102.     {
  103.         for(i=0;i<16;i++)
  104.             {
  105.             for(a=0;a<4;a++)   //共四个字
  106.                 {        
  107.                 if(dx>15){dxx+=16;dx=0;}  //dx,dxx为显示偏移量
  108.                 tmp=((dat[i+dxx+a*16]>>dx)|(dat[i+dxx+(a+1)*16]<<(16-dx)));//移动一位最大可移动八位左
  109.                                 if(dat[i+(a+1)*16+dxx]==0x55aa){dxx=0;tmp=0;flag=1;}
  110.                 LED_Ser(~tmp);        //发送右
  111.                 }        
  112.             LED_Ser_EN();      //使发送的数据显示
  113.             if(j<8){LED_PORTH=dat_bit_up[j];LED_PORTL=0XFF;}   //上半列扫描
  114.             else{LED_PORTL=dat_bit_down[j-8];LED_PORTH=0XFF;}  //下半列扫描
  115.             Delay();                                                                        //延时
  116.             LED_PORTL=0XFF;                                                                //消隐
  117.             LED_PORTH=0XFF;                                                                //消隐        
  118.                         j++;
  119.             }
  120.     }
  121. }
  122. void RTC_Write(uint8 dat)
  123. {
  124.         uint8 i;         
  125.         for(i=0;i<8;i++)
  126.         {
  127.                 RTC_IO=(bit)(dat&0x01);
  128.                 RTC_SCLK=1;
  129.                 RTC_SCLK=0;
  130.                 dat>>=1;
  131.         }
  132. }

  133. uint8 RTC_Read()                                                
  134. {
  135.     uint8 i;
  136.     for(i=0; i<8; i++)
  137.     {
  138.         AA >>=1;                                 //相当于汇编中的 RRC
  139.         AA7 = RTC_IO;
  140.         RTC_SCLK = 1;
  141.         RTC_SCLK = 0;
  142.     }
  143.     return AA;
  144. }

  145. void RTC_Write_Byte(uint8 addr,uint8 dat)
  146. {
  147.         RTC_RST=0;
  148.         RTC_SCLK=0;
  149.         RTC_RST=1;
  150.         RTC_Write(addr);
  151.         RTC_Write(dat);
  152.         RTC_SCLK=1;
  153.         RTC_RST=0;
  154. }

  155. uint8 RTC_Read_Byte(uint8 addr)
  156. {
  157.         uint8 dat;
  158.         RTC_RST=0;
  159.         RTC_SCLK=0;
  160.         RTC_RST=1;
  161.         RTC_Write(addr|0x01);
  162.         dat=RTC_Read();
  163.         RTC_SCLK=1;
  164.         RTC_RST=0;
  165.         return dat;
  166. }


  167. typedef struct __SYSTEMTIME__
  168. {
  169.         uint8  Second;
  170.         uint8  Mine;
  171.         uint8  Hour;
  172.         uint8  Day;
  173.         uint8  Month;
  174.         uint8  Week;
  175.         uint8  Year;
  176. }SYSTEMTIME;


  177. SYSTEMTIME TIMETYPE;
  178. void CurrentTime(SYSTEMTIME *dat)
  179. {
  180.         uint8 TimeValue;
  181.         TimeValue=RTC_Read_Byte(READ_SECOND);
  182.         dat->Second=(((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f);
  183.         TimeValue=RTC_Read_Byte(READ_MINE);
  184.         dat->Mine=  (((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f);
  185.         TimeValue=RTC_Read_Byte(READ_HOUR);
  186.         dat->Hour=  (((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f);
  187.         TimeValue=RTC_Read_Byte(READ_DAY);
  188.         dat->Day=        (((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f);
  189.         TimeValue=RTC_Read_Byte(READ_MONTH);
  190.         dat->Month= (((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f);
  191.         TimeValue=RTC_Read_Byte(READ_WEEK);
  192.         dat->Week=        (TimeValue&0x0f);
  193.         TimeValue=RTC_Read_Byte(READ_YEAR);
  194.         dat->Year=        (((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f);
  195. }
  196. void  LED_Disp_Time_Year(SYSTEMTIME *dat)
  197. {
  198.         uint8  j,i;
  199.     for(j=0;j<16;)
  200.     {
  201.         for(i=0;i<16;i++)
  202.             {
  203.                                 LED_Ser_8(~HZ[0][i]);        //发送右
  204.                                 LED_Ser_8(~NUM[2][i]);        //发送右
  205.                                 LED_Ser_8(~NUM[0][i]);        //发送右
  206.                                 LED_Ser_8(~NUM[(dat->Year)/10][i]);        //发送右
  207.                                 LED_Ser_8(~NUM[(dat->Year)%10][i]);        //发送右
  208.                                 LED_Ser_8(~Date[0][i*2+1]);
  209.                                 LED_Ser_8(~Date[0][i*2]);
  210.                                 LED_Ser_8(~HZ[0][i]);        //发送右
  211.                                 


  212.             LED_Ser_EN();      //使发送的数据显示
  213.             if(j<8){LED_PORTH=dat_bit_up[j];LED_PORTL=0XFF;}   //上半列扫描
  214.             else{LED_PORTL=dat_bit_down[j-8];LED_PORTH=0XFF;}  //下半列扫描
  215.             Delay();                                                                        //延时
  216.             LED_PORTL=0XFF;                                                                //消隐
  217.             LED_PORTH=0XFF;                                                                //消隐        
  218.                         j++;
  219.             }
  220.     }
  221. }
  222. void  LED_Disp_Time_Month(SYSTEMTIME *dat)
  223. {
  224.         uint8  j,i;
  225.     for(j=0;j<16;)
  226.     {
  227.         for(i=0;i<16;i++)
  228.             {
  229.                                 LED_Ser_8(~NUM[dat->Month/10][i]);        //发送右
  230.                                 LED_Ser_8(~NUM[dat->Month%10][i]);        //发送右
  231.                                 LED_Ser_8(~Date[1][i*2+1]);        //发送右
  232.                                 LED_Ser_8(~Date[1][i*2]);        //发送右
  233.                                 LED_Ser_8(~NUM[dat->Day/10][i]);        //发送右
  234.                                 LED_Ser_8(~NUM[dat->Day%10][i]);
  235.                                 LED_Ser_8(~Date[2][i*2+1]);
  236.                                 LED_Ser_8(~Date[2][i*2]);        //发送右
  237.                                 


  238.             LED_Ser_EN();      //使发送的数据显示
  239.             if(j<8){LED_PORTH=dat_bit_up[j];LED_PORTL=0XFF;}   //上半列扫描
  240.             else{LED_PORTL=dat_bit_down[j-8];LED_PORTH=0XFF;}  //下半列扫描
  241.             Delay();                                                                        //延时
  242.             LED_PORTL=0XFF;                                                                //消隐
  243.             LED_PORTH=0XFF;                                                                //消隐        
  244.                         j++;
  245.             }
  246.     }
  247. }
  248. void  LED_Disp_Time_Week(SYSTEMTIME *dat)
  249. {
  250.         uint8  j,i;
  251.     for(j=0;j<16;)
  252.     {
  253.         for(i=0;i<16;i++)
  254.             {
  255.                                 LED_Ser_8(~HZ[0][i]);        //发送右
  256.                                 LED_Ser_8(~Date[3][i*2+1]);        //发送右
  257.                                 LED_Ser_8(~Date[3][i*2]);        //发送右
  258.                                 LED_Ser_8(~Date[4][i*2+1]);        //发送右
  259.                                 LED_Ser_8(~Date[4][i*2]);        //发送右
  260.                                 LED_Ser_8(~WEEK[dat->Week-1][i*2+1]);
  261.                                 LED_Ser_8(~WEEK[dat->Week-1][i*2]);
  262.                                 LED_Ser_8(~HZ[0][i]);        //发送右
  263.                                 


  264.             LED_Ser_EN();      //使发送的数据显示
  265.             if(j<8){LED_PORTH=dat_bit_up[j];LED_PORTL=0XFF;}   //上半列扫描
  266.             else{LED_PORTL=dat_bit_down[j-8];LED_PORTH=0XFF;}  //下半列扫描
  267.             Delay();                                                                        //延时
  268.             LED_PORTL=0XFF;                                                                //消隐
  269.             LED_PORTH=0XFF;                                                                //消隐        
  270.                         j++;
  271.             }
  272.     }
  273. }
  274. void  LED_Disp_Time_Time(SYSTEMTIME *dat)
  275. {
  276.         uint8  j,i;
  277.     for(j=0;j<16;)
  278.     {
  279.         for(i=0;i<16;i++)
  280.             {
  281.                                 LED_Ser_8(~NUM[dat->Hour/10][i]);        //发送右
  282.                                 LED_Ser_8(~NUM[dat->Hour%10][i]);        //发送右
  283.                                 LED_Ser_8(~Date[5][i]);        //发送右
  284.                                 LED_Ser_8(~NUM[dat->Mine/10][i]);        //发送右
  285.                                 LED_Ser_8(~NUM[dat->Mine%10][i]);        //发送右
  286.                                 LED_Ser_8(~Date[5][i]);
  287.                                 LED_Ser_8(~NUM[dat->Second/10][i]);
  288.                                 LED_Ser_8(~NUM[dat->Second%10][i]);        //发送右
  289.                                 


  290.             LED_Ser_EN();      //使发送的数据显示
  291.             if(j<8){LED_PORTH=dat_bit_up[j];LED_PORTL=0XFF;}   //上半列扫描
  292.             else{LED_PORTL=dat_bit_down[j-8];LED_PORTH=0XFF;}  //下半列扫描
  293.             Delay();                                                                        //延时
  294.             LED_PORTL=0XFF;                                                                //消隐
  295.             LED_PORTH=0XFF;                                                                //消隐        
  296.                         j++;
  297.             }
  298.     }
  299. }               
  300. /*****************************************************************************************************************************
  301. /   函数名称:ET0_INT
  302. /   作用: 定时器T0的中断服务程序用于延自加字符显示偏移量以产生字符滚动显示的效果
  303. ******************************************************************************************************************************/
  304. void ET0_INT() interrupt 1 using 0    //中断服务程序
  305. {
  306.     TH0=0x03;
  307.     TL0=0x04;
  308.     brk++;
  309.     if(brk==10)
  310.     {
  311.         brk=0;       //brk延时用
  312.         dx++;       //字符显示偏移量
  313.     }
  314. }
  315. void Char_to_time(uint8 *dat)
  316. {
  317.         uint8 year,month,day,week,hour,mine;
  318.     year=((dat[0]-'0')*16+(dat[1]-'0'));
  319.         month=((dat[3]-'0')*16+(dat[4]-'0'));
  320.         day=((dat[6]-'0')*16+(dat[7]-'0'));
  321.         hour=((dat[9]-'0')*16+(dat[10]-'0'));
  322.         mine=((dat[12]-'0')*16+(dat[13]-'0'));
  323.         week=(dat[15]-'0');
  324.         RTC_Write_Byte(0x8e,0x00); //写入允许
  325.     RTC_Write_Byte(0x80,WRITE_SECOND|0x80);
  326.         RTC_Write_Byte(0x8e,0x80); //禁止写入
  327.         RTC_Write_Byte(0x8e,0x00); //写入允许
  328.         RTC_Write_Byte(WRITE_YEAR,year); //写入新的秒数
  329.         RTC_Write_Byte(WRITE_MONTH,month); //写入新的秒数
  330.         RTC_Write_Byte(WRITE_DAY,day); //写入新的秒数
  331.         RTC_Write_Byte(WRITE_HOUR,hour); //写入新的秒数
  332.         RTC_Write_Byte(WRITE_MINE,mine&0x7f); //写入新的秒数
  333.         RTC_Write_Byte(WRITE_WEEK,week); //写入新的秒数
  334.         RTC_Write_Byte(0x8e,0x00); //写入允许
  335.         RTC_Write_Byte(0x80,WRITE_SECOND&0x7f);
  336.         RTC_Write_Byte(0x8E,0x80);
  337. }
  338.         
  339. void Serial_int() interrupt 4 using 0
  340. {
  341.         uint8 i;
  342.         for(i=0;i<17;i++)
  343.         {
  344.         //        RI=0;
  345.                 while(RI==0);
  346.                 RI=0;
  347.                 BUFFER[i]=SBUF;
  348.         }
  349.         Char_to_time(BUFFER);

  350. }
  351. /*****************************************************************************************************************************
  352. /   函数名称:main
  353. /   作用: 主程序
  354. ******************************************************************************************************************************/
  355. void main()
  356. {
  357. //   TMOD=0x01;      //定时器方式1
  358.     TH0=0x03;
  359.     TL0=0x04;
  360.                
  361.         TMOD=0x20;
  362.         TH1=0xfd;
  363.         TL1=0xfd;
  364.         SCON=0x50;
  365.         PCON&=0xef;
  366.         EA=1;           //开总中断
  367.     ET0=1;          //开定时器中断
  368.     TR0=1;          //开始定时
  369.         ES=1;
  370.         TR1=1;
  371.         RI=0;

  372.         while(1)
  373.         {
  374.                
  375.             while(!flag)
  376.                 {
  377.                         LED_Disp(HZ);
  378.                 }
  379.                 while(dx!=0x14)
  380.                 {
  381.                         CurrentTime(&TIMETYPE);
  382.                         LED_Disp_Time_Year(&TIMETYPE); //显示主程序

  383.                 }
  384.                 dx=0;
  385.                 while(dx!=0x14)
  386.                 {
  387.                         CurrentTime(&TIMETYPE);
  388.                         LED_Disp_Time_Month(&TIMETYPE);
  389.                 }
  390.                 dx=0;
  391.                 while(dx!=0x14)
  392.                 {
  393.                         CurrentTime(&TIMETYPE);
  394.                         LED_Disp_Time_Week(&TIMETYPE);
  395.                 }
  396.                 dx=0;
  397.                 while(dx!=0x6f)
  398.                 {
  399.                         CurrentTime(&TIMETYPE);
  400.                         LED_Disp_Time_Time(&TIMETYPE);
  401.                 }
  402.                 dx=0;
  403.                 flag=0;
  404.                 while(!flag)
  405.                 {
  406.                         LED_Disp(HZ1);
  407.                 }
  408.                 flag=0;
  409.         }
  410.    
  411. }   
复制代码
0.png

所有资料51hei提供下载:
HBLED.rar (3.53 MB, 下载次数: 47)

评分

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

查看全部评分

回复

使用道具 举报

ID:61840 发表于 2018-11-12 14:29 | 显示全部楼层
谢谢分享!收藏了!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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