找回密码
 立即注册

QQ登录

只需一步,快速开始

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

stc52+12864液晶屏+ds1302自动显示程序

[复制链接]
跳转到指定楼层
楼主
ID:259642 发表于 2017-12-9 23:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
液晶屏+ds1302自动显示

单片机源程序如下:
  1. /*头文件*/
  2. #include <reg52.h>      
  3. #include <intrins.h>
  4. #define uint unsigned int
  5. #define uchar unsigned char

  6. /*引脚端口定义*/
  7. sbit lcd_psb=P3^7;
  8. sbit LCD12864_RS_PORT=P3^5;  /*LCD12864引脚定义*/
  9. sbit LCD12864_RW_PORT=P3^6;
  10. sbit LCD12864_E_PORT=P3^4;
  11. #define        LCD12864_DA_PORT P0
  12. sbit dula=P2^6;     //数码管的段选信号

  13. sbit DQ=P2^2;       //定义DS18B20通信端口
  14. sbit Beep=P2^3;     //蜂鸣器通信端口

  15. sbit T_CLK=P1^7;    /*ds1302实时时钟时钟线引脚 */
  16. sbit T_IO=P2^4;     /*ds1302实时时钟数据线引脚 */
  17. sbit T_RST=P1^6;    /*ds1302实时时钟复位线引脚 */
  18. sbit ACC0=ACC^0;    /*ds1302位寻址寄存器*/
  19. sbit ACC7=ACC^7;
  20.        
  21. uchar code num_to_char[]={"0123456789"};/*数字转换为ASCII字符码*/
  22. uchar code Week1_to_char[]={"一"};
  23. uchar code Week2_to_char[]={"二"};
  24. uchar code Week3_to_char[]={"三"};
  25. uchar code Week4_to_char[]={"四"};
  26. uchar code Week5_to_char[]={"五"};
  27. uchar code Week6_to_char[]={"六"}; /*星期数字转换为汉字的ASCII码*/
  28. uchar code Week7_to_char[]={"日"};
  29. uchar hanzi_buff1[]={"    年  月  日  "};//0-15
  30. uchar hanzi_buff2[]={"    星期        "};
  31. uchar hanzi_buff3[]={"      :  :      "};
  32. uchar hanzi_buff4[]={"当前温度:   . 度"};
  33. uchar data time_data_buff[7]={0x00,0x00,0x12,0x01,0x12,0x06,0x17};/*格式为: 秒 分 时 日 月 星期 年 */
  34. /*1MS为单位的延时程序*/
  35. void delay_1ms(uchar x)
  36. {
  37.     uchar j;
  38.     while(x--){
  39.         for(j=0;j<125;j++)
  40.             {;}
  41.         }   
  42. }

  43. void beep()
  44. {
  45.     Beep=0;
  46.         delay_1ms(2000);
  47.     Beep=1;
  48. }
  49. ////////////////////以下是时钟读取程序/////////////////
  50. /********************************************************************
  51. 函 数 名:InputByte()
  52. 功    能:实时时钟写入一字节
  53. 说    明:往DS1302写入1Byte数据 (内部函数)
  54. 入口参数:d 写入的数据
  55. 返 回 值:无  
  56. ***********************************************************************/
  57. void InputByte(uchar d)
  58. {
  59.     uchar i;
  60.     ACC=d;
  61.     for(i=8;i>0;i--)
  62.     {
  63.         T_IO=ACC0;           /*相当于汇编中的 RRC */
  64.         T_CLK=1;
  65.         T_CLK=0;
  66.         ACC=ACC>>1;
  67.     }
  68. }
  69. /********************************************************************
  70. 函 数 名:OutputByte()
  71. 功    能:实时时钟读取一字节
  72. 说    明:从DS1302读取1Byte数据 (内部函数)
  73. 入口参数:无  
  74. 返 回 值:ACC
  75. ***********************************************************************/
  76. uchar OutputByte()
  77. {
  78.     uchar i;
  79.     for(i=8;i>0;i--)
  80.     {
  81.         ACC=ACC>>1;         /*相当于汇编中的 RRC */
  82.         ACC7=T_IO;
  83.         T_CLK=1;
  84.         T_CLK=0;
  85.     }
  86.     return(ACC);
  87. }
  88. /********************************************************************
  89. 函 数 名:W1302()
  90. 功    能:往DS1302写入数据
  91. 说    明:先写地址,后写命令/数据 (内部函数)
  92. 调    用:RTInputByte() , RTOutputByte()
  93. 入口参数:ucAddr: DS1302地址, ucData: 要写的数据
  94. 返 回 值:无
  95. ***********************************************************************/
  96. void W1302(uchar ucAddr, uchar ucDa)//先写命令字,再写数据
  97. {
  98.     T_RST=0;
  99.     T_CLK=0;
  100.     T_RST=1;
  101.     InputByte(ucAddr);       /* 地址,命令 */
  102.     InputByte(ucDa);         /* 写1Byte数据*/
  103.     T_CLK=1;
  104.     T_RST=0;
  105. }
  106. /********************************************************************
  107. 函 数 名:Set1302()
  108. 功    能:设置初始时间
  109. 说    明:先写地址,后读命令/数据(寄存器多字节方式)
  110. 调    用:W1302()
  111. 入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
  112.                                7Byte (BCD码)1B 1B 1B 1B 1B  1B  1B
  113. 返 回 值:无
  114. ***********************************************************************/
  115. void Set1302(uchar *pClock) //指针指向time_data_buff数组
  116. {
  117.     uchar i;
  118.     uchar ucAddr=0x80;
  119.         //EA=0;
  120.     W1302(0x8e,0x00);/*对写保护寄存器操作,0x8e写保护寄存器写命令字,0x00使该寄存器最高位WP=0时间日历寄存器可进行写操作*/
  121.         //W1302(0x90,0xa6);
  122.     for(i=7;i>0;i--)
  123.     {
  124.         W1302(ucAddr,*pClock);  //秒 分 时 日 月 星期 年 ucAddr先为0x80,此地址为秒寄存器写控制命令字
  125.         pClock++;
  126.         ucAddr+=2;  //每次加2分别进入分、时、日。。。年写命令字
  127.     }
  128.     W1302(0x8e,0x80);           /* 控制命令,WP=1,写保护,此后时钟寄存器不断变化*/
  129.         //EA = 1;
  130. }
  131. /********************************************************************
  132. 函 数 名:R1302()
  133. 功    能:读取DS1302某地址的数据
  134. 说    明:先写地址,后读命令/数据 (内部函数)
  135. 调    用:RTInputByte() , RTOutputByte()
  136. 入口参数:ucAddr: DS1302地址
  137. 返 回 值:ucData :读取的数据
  138. ***********************************************************************/
  139. uchar R1302(uchar ucAddr)//先写命令字,再读数据
  140. {
  141.     uchar ucData;
  142.     T_RST=0;
  143.     T_CLK=0;
  144.     T_RST=1;
  145.     InputByte(ucAddr);             /* 地址,命令 */
  146.     ucData=OutputByte();         /* 读1Byte数据 */
  147.     T_CLK=1;
  148.     T_RST=0;
  149.     return(ucData);
  150. }
  151. /********************************************************************
  152. 函 数 名:Now1302()
  153. 功    能:读取DS1302当前时间
  154. 说    明:
  155. 调    用:R1302()
  156. 入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
  157.                                         7Byte (BCD码)   1B 1B 1B 1B 1B  1B  1B
  158. 返 回 值:无
  159. ***********************************************************************/
  160. void Now1302(uchar ucCurtime[])
  161. {
  162.     uchar i;
  163.     uchar ucAddr=0x81;
  164.         //EA=0;
  165.     for (i=0;i<7;i++)
  166.     {
  167.         ucCurtime[i]=R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */
  168.         ucAddr+=2;
  169.     }
  170.         //EA=1;//考虑保持总中断开启
  171. }







  172. void delay(uint i)
  173. {
  174.         while(i--);
  175. }








  176. //////////////////以下是DS18B20驱动程序////////////////
  177. void Init_DS18B20()//初始化函数
  178. {
  179.         unsigned char x=0;
  180.         DQ = 1; //DQ复位
  181.         delay(8); //稍做延时
  182.         DQ = 0; //单片机将DQ拉低
  183.         delay(80); //精确延时 大于 480us
  184.         DQ = 1; //拉高总线
  185.         delay(14);
  186.         x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  187.         DQ=1;
  188. }

  189. uchar ReadOneChar()//读一个字节
  190. {
  191.         uchar i;
  192.         uchar dat=0;
  193.         for(i=8;i>0;i--)
  194.         {
  195.                 DQ=0; // 给脉冲信号
  196.                 dat>>=1;
  197.                 DQ=1; // 给脉冲信号
  198.                 if(DQ)  
  199.                 dat|=0x80; //利用0x80将温度数据赋给dat
  200.                 delay(4);
  201.         }
  202.         return(dat);
  203. }

  204. void WriteOneChar(unsigned char dat)//写一个字节
  205. {
  206.         uchar i=0;
  207.         for (i=8;i>0;i--){
  208.                 DQ=0;
  209.                 DQ=dat&0x01;
  210.                 delay(5);
  211.                 DQ=1;
  212.                 dat>>=1;
  213.                 }
  214. }

  215. uint ReadTemperature()//读取温度,注意返回值为16bit
  216. {
  217.         uchar a=0;
  218.         uchar b=0;
  219.         uint t=0;
  220.         float tt=0;
  221.         Init_DS18B20();
  222.         WriteOneChar(0xCC); // 跳过读序号列号的操作
  223.         WriteOneChar(0x44); // 启动温度转换
  224.         Init_DS18B20();
  225.         WriteOneChar(0xCC); //跳过读序号列号的操作
  226.         WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  227.         a=ReadOneChar();
  228.         b=ReadOneChar();
  229.         t=b;
  230.         t<<=8;
  231.         t=t|a; //将温度的高位与低位合并
  232.         tt=t*0.0625;
  233.         t=tt*10+0.5; //对结果进行4舍5入
  234.         return(t);
  235. }






  236. //////////////////以下是LCD12864驱动程序////////////////
  237. void LCD12864_WaitIdle()
  238. //LCD12864  忙 信号检测
  239. {
  240.         LCD12864_DA_PORT = 0xff;
  241.         LCD12864_RS_PORT = 0;
  242.         LCD12864_RW_PORT = 1;
  243.         LCD12864_E_PORT = 1;
  244.         while((LCD12864_DA_PORT&0x80)==1); /*等待BF 不为1*/
  245.         LCD12864_E_PORT = 0;
  246. }

  247. void LCD12864_COM_Write( uchar com_da) /* 检测忙信号写入命令字 com_da 为待写入的命令字*/       
  248. {
  249.         LCD12864_WaitIdle();
  250.         LCD12864_RS_PORT = 0;
  251.         LCD12864_RW_PORT = 0;
  252.         LCD12864_DA_PORT = com_da;
  253.         LCD12864_E_PORT = 1;
  254.     delay_1ms(1);
  255.         LCD12864_E_PORT = 0;       
  256. }

  257. void LCD12864_NoWaitIdle_COM_Write(uchar com) /*不检测忙信号写入命令字,com_da 为待写入的命令字*/       
  258. {
  259.         LCD12864_RS_PORT=0; //0写命令
  260.         LCD12864_RW_PORT=0;
  261.         LCD12864_E_PORT=0;
  262.         LCD12864_DA_PORT=com;
  263.     delay_1ms(1);
  264.         LCD12864_E_PORT=1;
  265.     delay_1ms(1);
  266.     LCD12864_E_PORT=0;       
  267. }

  268. void LCD12864_Data_Write(uchar da) /*数据写入 da为待写入8位数据*/
  269. {
  270.         LCD12864_WaitIdle(); /*检测忙信号*/
  271.         LCD12864_RS_PORT = 1; //写数据
  272.         LCD12864_RW_PORT = 0;
  273.         LCD12864_DA_PORT = da;
  274.         LCD12864_E_PORT = 1;
  275.     delay_1ms(1);
  276.         LCD12864_E_PORT = 0;       
  277. }

  278. void LCD12864_init()  /*LCD12864初始化*/
  279. {
  280.         lcd_psb=1;
  281.         LCD12864_NoWaitIdle_COM_Write(0x30); /*基本指令操作*/
  282.         delay_1ms(10);
  283.         LCD12864_NoWaitIdle_COM_Write(0x0c); /*显示开及光标设置*/
  284.         delay_1ms(10);
  285.         LCD12864_NoWaitIdle_COM_Write(0x01); /*显示清屏*/
  286.         delay_1ms(10);
  287.         LCD12864_NoWaitIdle_COM_Write(0x06); /*DDRAM的地址计数器(AC)加1*/
  288.         delay_1ms(10);       
  289. }

  290. void LCD12864_HAIZI_WRITE(uchar x,uchar y,uchar daH,uchar daL) //汉字16bit写入 x写入的X位置 y写入的Y位置 daH写入汉字高八位 daL写入汉字低八位
  291. {
  292.         uchar xy;
  293.         if((x>=8)||(y>=4)) return; /*X位置超出显示范围退出*/
  294.         if(y==0)      xy=0x80+x;
  295.         else if(y==1) xy=0x90+x; /*计算转换地址*/
  296.         else if(y==2) xy=0x88+x;
  297.         else if(y==3) xy=0x98+x;
  298.         LCD12864_COM_Write(xy); /*写地址*/
  299.         delay_1ms(1);
  300.         LCD12864_Data_Write(daH); /*写高八位数据*/
  301.         delay_1ms(1);
  302.         LCD12864_Data_Write(daL); /*写低八位数据*/
  303.         delay_1ms(1);
  304. }








  305. //键盘扫描函数,低电位按下

  306. /*void keyscan()
  307. {
  308.         int s1num;
  309.         rd=0;
  310.         if(key1==0)
  311.         {
  312.                 delay_1ms(5);
  313.             if(key1==0)
  314.             {
  315.                      Set1302(time_data_buff);
  316.                          W1302(0x8e,0x00);
  317.                  W1302(0x80,0x80);
  318.                          W1302(0x8e,0x80);
  319.                      s1num++;
  320.                      while(!key1);
  321.                      if(s1num==1)
  322.                      {                       
  323.                     //LCD12864_COM_Write(0x81);年
  324.                              if(key2==0)
  325.                              {
  326.                                       delay_1ms(5);
  327.                                       if(key2==0)
  328.                                       {
  329.                                           while(!key2);
  330.                                               time_data_buff[6]++;
  331.                                       }
  332.                              }
  333.                      }
  334.                 /*if(s1num==2)
  335.                 {
  336.             LCD12864_COM_Write(0x83);//月
  337.                 }
  338.                 if(s1num==3)
  339.                 {
  340.                         LCD12864_COM_Write(0x85);//日
  341.                 }
  342.                 if(s1num==4)
  343.                 {
  344.                         LCD12864_COM_Write(0x8a);//时
  345.                 }
  346.                 if(s1num==5)
  347.                 {
  348.                         LCD12864_COM_Write(0x88+)/////////////////
  349.                 }
  350.                 if(s1num==6)
  351.                 {
  352.                         LCD12864_COM_Write(0x8d);//秒
  353.                 }*/
  354.         /*     if(s1num==2)
  355.                      {
  356.                                s1num=0;
  357.                                    W1302(0x8e,0x00);
  358.                                W1302(0x80,0x00);
  359.                                    W1302(0x8e,0x80);
  360.                      }
  361.         //W1302(0x80,此处应为修改的秒值);       
  362.                
  363.            }
  364.         }
  365. }
  366. */

  367. void main()//主函数
  368. {
  369.         uchar i;
  370.         uint temp_buff;

  371.         P0=0x00;//关掉数码管位选信号。阻止数码管受到P0口信号的影响。
  372.         dula=1;
  373.         delay_1ms(1);
  374.         dula=0;
  375.         delay_1ms(1);
  376.        
  377.         LCD12864_init(); /*LCD初始化*/

  378.         LCD12864_DA_PORT = 0xff;  /*释放P0端口*/
  379.        
  380.         Set1302(time_data_buff);

  381.         while(1){
  382.                
  383. //                keyscan();
  384.        
  385.                 Now1302(time_data_buff);
  386.                 hanzi_buff1[2] = num_to_char[time_data_buff[6]/0x10];
  387.                 hanzi_buff1[3] = num_to_char[time_data_buff[6]%0x10]; /*年*/
  388.                 hanzi_buff1[6] = num_to_char[time_data_buff[4]/0x10];
  389.                 hanzi_buff1[7] = num_to_char[time_data_buff[4]%0x10]; /*月*/
  390.                 hanzi_buff1[10] = num_to_char[time_data_buff[3]/0x10];
  391.                 hanzi_buff1[11] = num_to_char[time_data_buff[3]%0x10]; /*日*/
  392.                 hanzi_buff3[4] = num_to_char[time_data_buff[2]/0x10];
  393.                 hanzi_buff3[5] = num_to_char[time_data_buff[2]%0x10]; /*时*/
  394.                 hanzi_buff3[7] = num_to_char[time_data_buff[1]/0x10];
  395.                 hanzi_buff3[8] = num_to_char[time_data_buff[1]%0x10]; /*分*/
  396. ……………………

  397. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
test_2_3.zip (40.99 KB, 下载次数: 28)


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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