找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4638|回复: 0
收起左侧

基于单片机的带温度显示的电子钟源码

[复制链接]
ID:317377 发表于 2018-4-27 10:56 | 显示全部楼层 |阅读模式
110857vrrdxzjv9rldim0r.png
单片机源程序如下:
  1. /*
  2. *******************************************************************************
  3. *                     《手把手教你学51单片机(C语言版)》
  4. *                    配套 KST-51 单片机开发板 示例源代码
  5. *
  6. * 文件名:main.c
  7. * 描  述:第16章 作业题4 带温度显示的电子钟
  8. * 版本号:v1.0.0
  9. * 备  注:在lesson15_3基础上添加温度,温度显示在第二行右端,原时间位置相应左移
  10. *******************************************************************************
  11. */

  12. #include <reg52.h>

  13. struct sTime {  //日期时间结构体定义
  14.     unsigned int  year;
  15.     unsigned char mon;
  16.     unsigned char day;
  17.     unsigned char hour;
  18.     unsigned char min;
  19.     unsigned char sec;
  20.     unsigned char week;
  21. };

  22. bit flag1s = 0;  //1s定时标志
  23. bit flag200ms = 1;  //200ms定时标志
  24. struct sTime bufTime;  //日期时间缓冲区
  25. unsigned char setIndex = 0;  //时间设置索引
  26. unsigned char T0RH = 0;  //T0重载值的高字节
  27. unsigned char T0RL = 0;  //T0重载值的低字节

  28. void ConfigTimer0(unsigned int ms);
  29. void RefreshTimeShow();
  30. void GetShowTemp();
  31. extern void InitDS1302();
  32. extern void GetRealTime(struct sTime *time);
  33. extern void SetRealTime(struct sTime *time);
  34. extern void KeyScan();
  35. extern void KeyDriver();
  36. extern void InitLcd1602();
  37. extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
  38. extern void LcdSetCursor(unsigned char x, unsigned char y);
  39. extern void LcdOpenCursor();
  40. extern void LcdCloseCursor();
  41. extern bit Start18B20();
  42. extern bit Get18B20Temp(int *temp);

  43. void main()
  44. {
  45.     unsigned char psec=0xAA;  //秒备份,初值AA确保首次读取时间后会刷新显示

  46.     EA = 1;           //开总中断
  47.     ConfigTimer0(1);  //T0定时1ms
  48.     Start18B20();     //启动DS18B20
  49.     InitDS1302();     //初始化实时时钟
  50.     InitLcd1602();    //初始化液晶
  51.    
  52.     //初始化屏幕上固定不变的内容
  53.     LcdShowStr(3, 0, "20  -  -  ");
  54.     LcdShowStr(1, 1, "  :  :    --`C");
  55.    
  56.     while (1)
  57.     {
  58.         KeyDriver();  //调用按键驱动
  59.         if (flag200ms && (setIndex == 0))
  60.         {                             //每隔200ms且未处于设置状态时,
  61.             flag200ms = 0;
  62.             GetRealTime(&bufTime);    //获取当前时间
  63.             if (psec != bufTime.sec)  //检测到时间有变化时刷新显示
  64.             {
  65.                 RefreshTimeShow();
  66.                 psec = bufTime.sec;   //用当前值更新上次秒数
  67.             }
  68.         }
  69.         if (flag1s && (setIndex == 0))  //每隔1s读取并显示温度
  70.         {
  71.             flag1s = 0;
  72.             GetShowTemp();
  73.         }
  74.     }
  75. }
  76. /* 将一个BCD码字节显示到屏幕上,(x,y)-屏幕起始坐标,bcd-待显示BCD码 */
  77. void ShowBcdByte(unsigned char x, unsigned char y, unsigned char bcd)
  78. {
  79.     unsigned char str[4];
  80.    
  81.     str[0] = (bcd >> 4) + '0';
  82.     str[1] = (bcd&0x0F) + '0';
  83.     str[2] = '\0';
  84.     LcdShowStr(x, y, str);
  85. }
  86. /* 获取并显示温度 */
  87. void GetShowTemp()
  88. {
  89.     int temp;
  90.     unsigned char str[4];
  91.    
  92.     if (Get18B20Temp(&temp))  //读取当前温度并判断是否成功
  93.     {   //读取成功时,刷新当前温度显示
  94.         temp >>= 4;  //右移4位以舍弃小数位
  95.         str[0] = temp/10 + '0';  //显示为两位十进制数字
  96.         str[1] = temp%10 + '0';
  97.         str[2] = '\0';
  98.         LcdShowStr(11, 1, str);
  99.     }
  100.     else
  101.     {   //读取失败时,提示错误信息
  102.         LcdShowStr(11, 1, "--");
  103.     }
  104.     Start18B20();  //重新启动下一次转换
  105. }
  106. /* 刷新日期时间的显示 */
  107. void RefreshTimeShow()
  108. {
  109.     ShowBcdByte(5,  0, bufTime.year);
  110.     ShowBcdByte(8,  0, bufTime.mon);
  111.     ShowBcdByte(11, 0, bufTime.day);
  112.     ShowBcdByte(1,  1, bufTime.hour);
  113.     ShowBcdByte(4,  1, bufTime.min);
  114.     ShowBcdByte(7,  1, bufTime.sec);
  115. }
  116. /* 刷新当前设置位的光标指示 */
  117. void RefreshSetShow()
  118. {
  119.     switch (setIndex)
  120.     {
  121.         case 1:  LcdSetCursor(5,  0); break;
  122.         case 2:  LcdSetCursor(6,  0); break;
  123.         case 3:  LcdSetCursor(8,  0); break;
  124.         case 4:  LcdSetCursor(9,  0); break;
  125.         case 5:  LcdSetCursor(11, 0); break;
  126.         case 6:  LcdSetCursor(12, 0); break;
  127.         case 7:  LcdSetCursor(1,  1); break;
  128.         case 8:  LcdSetCursor(2,  1); break;
  129.         case 9:  LcdSetCursor(4,  1); break;
  130.         case 10: LcdSetCursor(5,  1); break;
  131.         case 11: LcdSetCursor(7,  1); break;
  132.         case 12: LcdSetCursor(8,  1); break;
  133.         default:  break;
  134.     }
  135. }
  136. /* 递增一个BCD码的高位 */
  137. unsigned char IncBcdHigh(unsigned char bcd)
  138. {
  139.     if ((bcd&0xF0) < 0x90)
  140.         bcd += 0x10;
  141.     else
  142.         bcd &= 0x0F;
  143.    
  144.     return bcd;
  145. }
  146. /* 递增一个BCD码的低位 */
  147. unsigned char IncBcdLow(unsigned char bcd)
  148. {
  149.     if ((bcd&0x0F) < 0x09)
  150.         bcd += 0x01;
  151.     else
  152.         bcd &= 0xF0;
  153.    
  154.     return bcd;
  155. }
  156. /* 递减一个BCD码的高位 */
  157. unsigned char DecBcdHigh(unsigned char bcd)
  158. {
  159.     if ((bcd&0xF0) > 0x00)
  160.         bcd -= 0x10;
  161.     else
  162.         bcd |= 0x90;
  163.    
  164.     return bcd;
  165. }
  166. /* 递减一个BCD码的低位 */
  167. unsigned char DecBcdLow(unsigned char bcd)
  168. {
  169.     if ((bcd&0x0F) > 0x00)
  170.         bcd -= 0x01;
  171.     else
  172.         bcd |= 0x09;
  173.    
  174.     return bcd;
  175. }
  176. /* 递增时间当前设置位的值 */
  177. void IncSetTime()
  178. {
  179.     switch (setIndex)
  180.     {
  181.         case 1:  bufTime.year = IncBcdHigh(bufTime.year); break;
  182.         case 2:  bufTime.year = IncBcdLow(bufTime.year);  break;
  183.         case 3:  bufTime.mon  = IncBcdHigh(bufTime.mon);  break;
  184.         case 4:  bufTime.mon  = IncBcdLow(bufTime.mon);   break;
  185.         case 5:  bufTime.day  = IncBcdHigh(bufTime.day);  break;
  186.         case 6:  bufTime.day  = IncBcdLow(bufTime.day);   break;
  187.         case 7:  bufTime.hour = IncBcdHigh(bufTime.hour); break;
  188.         case 8:  bufTime.hour = IncBcdLow(bufTime.hour);  break;
  189.         case 9:  bufTime.min  = IncBcdHigh(bufTime.min);  break;
  190.         case 10: bufTime.min  = IncBcdLow(bufTime.min);   break;
  191.         case 11: bufTime.sec  = IncBcdHigh(bufTime.sec);  break;
  192.         case 12: bufTime.sec  = IncBcdLow(bufTime.sec);   break;
  193.         default:  break;
  194.     }
  195.     RefreshTimeShow();
  196.     RefreshSetShow();
  197. }
  198. /* 递减时间当前设置位的值 */
  199. void DecSetTime()
  200. {
  201.     switch (setIndex)
  202.     {
  203.         case 1:  bufTime.year = DecBcdHigh(bufTime.year); break;
  204.         case 2:  bufTime.year = DecBcdLow(bufTime.year);  break;
  205.         case 3:  bufTime.mon  = DecBcdHigh(bufTime.mon);  break;
  206.         case 4:  bufTime.mon  = DecBcdLow(bufTime.mon);   break;
  207.         case 5:  bufTime.day  = DecBcdHigh(bufTime.day);  break;
  208.         case 6:  bufTime.day  = DecBcdLow(bufTime.day);   break;
  209.         case 7:  bufTime.hour = DecBcdHigh(bufTime.hour); break;
  210.         case 8:  bufTime.hour = DecBcdLow(bufTime.hour);  break;
  211.         case 9:  bufTime.min  = DecBcdHigh(bufTime.min);  break;
  212.         case 10: bufTime.min  = DecBcdLow(bufTime.min);   break;
  213.         case 11: bufTime.sec  = DecBcdHigh(bufTime.sec);  break;
  214.         case 12: bufTime.sec  = DecBcdLow(bufTime.sec);   break;
  215.         default:  break;
  216.     }
  217.     RefreshTimeShow();
  218.     RefreshSetShow();
  219. }
  220. /* 右移时间设置位 */
  221. void RightShiftTimeSet()
  222. {
  223.     if (setIndex != 0)
  224.     {
  225.         if (setIndex < 12)
  226.             setIndex++;
  227.         else
  228.             setIndex = 1;
  229.         RefreshSetShow();
  230.     }
  231. }
  232. /* 左移时间设置位 */
  233. void LeftShiftTimeSet()
  234. {
  235.     if (setIndex != 0)
  236.     {
  237.         if (setIndex > 1)
  238.             setIndex--;
  239.         else
  240.             setIndex = 12;
  241.         RefreshSetShow();
  242.     }
  243. }
  244. /* 进入时间设置状态 */
  245. void EnterTimeSet()
  246. {
  247.     setIndex = 2;       //把设置索引设置为2,即可进入设置状态
  248.     LeftShiftTimeSet(); //再利用现成的左移操作移到位置1并完成显示刷新
  249.     LcdOpenCursor();    //打开光标闪烁效果
  250. }
  251. /* 退出时间设置状态,save-是否保存当前设置的时间值 */
  252. void ExitTimeSet(bit save)
  253. {
  254.     setIndex = 0;     //把设置索引设置为0,即可退出设置状态
  255.     if (save)         //需保存时即把当前设置时间写入DS1302
  256.     {
  257.         SetRealTime(&bufTime);
  258.     }
  259.     LcdCloseCursor(); //关闭光标显示
  260. }
  261. /* 按键动作函数,根据键码执行相应的操作,keycode-按键键码 */
  262. void KeyAction(unsigned char keycode)
  263. {
  264.     if  ((keycode>='0') && (keycode<='9'))  //本例中不响应字符键
  265.     {
  266.     }
  267.     else if (keycode == 0x26)  //向上键,递增当前设置位的值
  268.     {
  269.         IncSetTime();
  270.     }
  271.     else if (keycode == 0x28)  //向下键,递减当前设置位的值
  272.     {
  273.         DecSetTime();
  274.     }
  275.     else if (keycode == 0x25)  //向左键,向左切换设置位
  276.     {
  277.         LeftShiftTimeSet();
  278.     }
  279.     else if (keycode == 0x27)  //向右键,向右切换设置位
  280.     {
  281.         RightShiftTimeSet();
  282.     }
  283.     else if (keycode == 0x0D)  //回车键,进入设置模式/启用当前设置值
  284.     {
  285.         if (setIndex == 0)  //不处于设置状态时,进入设置状态
  286.         {
  287.             EnterTimeSet();
  288.         }
  289.         else                //已处于设置状态时,保存时间并退出设置状态
  290.         {
  291.             ExitTimeSet(1);
  292.         }
  293.     }
  294.     else if (keycode == 0x1B)  //Esc键,取消当前设置
  295.     {
  296.         ExitTimeSet(0);
  297.     }
  298. }
  299. /* 配置并启动T0,ms-T0定时时间 */
  300. void ConfigTimer0(unsigned int ms)
  301. {
  302. ……………………

  303. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
0.jpg
所有资料51hei提供下载:
温度检测.rar (41.24 KB, 下载次数: 72)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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