久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6038|回復: 4
打印 上一主題 下一主題
收起左側

藍橋杯任務基于單片機的電子鐘

[復制鏈接]
跳轉到指定樓層
樓主
基于單片機的電子鐘仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)

藍橋杯任務單片機源程序如下:
  1. #include <regx51.h>
  2. #include <intrins.h>

  3. sfr AUXR = 0x8e;
  4. /*數碼管顯示字符轉換表*/
  5. unsigned char tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40,0x39};
  6. signed char num[] = {10,10,10,10,10,10,10,10};   //數碼管顯示緩沖區
  7. signed char timeclock[] = {0,0,11,0,0,11,0,0};   //鬧鐘時間
  8. unsigned char TRH0,TRL0;  //T0重載值的高字節和低字節
  9. bit clock = 0;          //鬧鐘時間到標志位
  10. bit flag = 0;          //1s閃爍標志位
  11. bit flag200ms = 0;         //200ms定時標志位
  12. bit timesetup = 0;   //時間設置標志位
  13. bit clocksetup = 0;         //鬧鐘設置標志位
  14. unsigned position = 0;    //設置小時,分鐘,秒標志位(‘1’小時,‘2’分鐘,‘3’秒)
  15. unsigned char Temp;           //溫度值
  16. unsigned char Time[5];          //時間值

  17. void key();  //按鍵判斷執行函數
  18. void Ds1302_Display();          //時間顯示函數
  19. void Ds18b20_Display();          //溫度顯示函數

  20. extern void Ds1302_Init();          //DS1302初始化函數
  21. void Ds1302_Time(unsigned char *time);  //帶參數的向DS18B20寫時間
  22. extern void Write_Ds1302_Byte(unsigned char temp);          //向DS1302寫入數據
  23. extern unsigned char Read_Ds1302 (unsigned char address);          //從DS1302讀取數據
  24. extern unsigned char DS18B20_Temp();         //讀取DS18B20溫度值


  25. /*T0初始化函數 (ms = 中斷時間)*/
  26. void Time0_Init(unsigned char ms)
  27. {
  28.         unsigned long num;                //臨時變量
  29.         num = 12000000 / 12;     //12分頻  定時器計數頻率
  30.         num = (num * ms)/1000;          //計算所需的計數值
  31.         num = 65536 - num;                  //計算定時器重載值
  32.         TRH0 = (unsigned char)(num>>8);                //定時器重載值拆分為高低字節
  33.         TRL0 = (unsigned char)num;
  34.         TH0 = TRH0;           //加載T0重載值                 
  35.         TL0 = TRL0;
  36.         AUXR &= 0x7F;         
  37.         TMOD &= 0xf0;          //清零T0的控制位
  38.         TMOD |= 0x01;          //配置T0為模式1        
  39.         EA = 1;                //使能總中斷
  40.         ET0 = 1;        //使能T0中斷
  41.         TR0 = 1;        //啟動T0
  42. }

  43. void main()
  44. {
  45.         unsigned char i,k=0;

  46.         Time0_Init(1);         //初始化T0,定時時間為1ms
  47.         Ds1302_Init();         //初始化DS1302
  48.         while(1)
  49.         {
  50.                 key();        
  51.                 for(i=0;i<8;i++)
  52.                 {
  53.                         if(num[i]==timeclock[i])
  54.                                 k++        ;
  55.                         else
  56.                                 k = 0;
  57.                 }
  58.                 if(k == 8)
  59.                         clock = 1;                                
  60.                
  61.         }        
  62. }
  63. /*DS18B20顯示函數*/
  64. void Ds18b20_Display()
  65. {
  66.         unsigned char i;

  67.         if(flag200ms != 0)
  68.         {
  69.                 flag200ms = 0;
  70.                 Temp = DS18B20_Temp();
  71.         
  72.                 for(i=0;i<5;i++)
  73.                 {
  74.                         num[i] = 10;
  75.                 }
  76.         
  77.                 num[5] = Temp / 10;
  78.                 num[6] = Temp % 10;
  79.                 num[7] = 12;
  80.         }
  81. }
  82. /*DS1302顯示函數*/
  83. void Ds1302_Display()
  84. {
  85.         static unsigned char i;
  86.         static unsigned char pers = 0xaa;
  87.         

  88.         if(flag200ms != 0)
  89.         {
  90.                 flag200ms = 0;
  91.                 for(i=0;i<3;i++)
  92.                 {
  93.                         Time[i] = Read_Ds1302(i);  //每200ms獲取時間
  94.                 }
  95.                 if(pers != Time[0])          //判斷時間有沒有變化
  96.                 {        
  97.                         num[7] = Time[0] & 0x0f;   //秒
  98.                         num[6] = Time[0] >> 4;
  99.                         num[5] = 11;
  100.                         num[4] = Time[1] & 0x0f;   //分
  101.                         num[3] = Time[1] >> 4;
  102.                         num[2] = 11;
  103.                         num[1] = Time[2] & 0x0f;   //時
  104.                         num[0] = Time[2] >> 4;               

  105.                         pers = Time[0];                //將變化值重新寫入判斷值
  106.                 }
  107.         }        
  108. }
  109. /*數碼管顯示函數*/
  110. void Display()           
  111. {
  112.         static unsigned char we = 0;        
  113.         
  114.         P0 = 0x00;                //清除鬼影
  115.         P2 |= 0xff;

  116.         P2 &= ~(1<<we);          //位選擇
  117.         if(clocksetup)
  118.                 P0 = tab[timeclock[we]];
  119.         else
  120.                 P0 = tab[num[we]];          //顯示數選擇        
  121.         
  122.         if(flag)           //進入設置狀態
  123.         {
  124.                 switch(position) //判斷是那個設置位
  125.                 {
  126.                         case 1:         P2 |= 0xc0; break;         //秒
  127.                         case 2:         P2 |= 0x18; break;         //分
  128.                         case 3:         P2 |= 0x03; break;         //時
  129.                         default : position = 0; timesetup = 0; clocksetup = 0; break;
  130.                 }
  131.         }
  132.                
  133.         if(++we >= 8)  //八個數碼管         
  134.                 we = 0;        
  135. }

  136. /*T0中斷函數*/                                                           
  137. void Time0_inte() interrupt 1
  138. {
  139.         static unsigned char ms = 0;
  140.         static unsigned char flag1s = 0;
  141.         static unsigned char flag5s = 0;

  142.         TH0 = TRH0;         //加載T0重載值
  143.         TL0 = TRL0;

  144.         Display();        //數碼管顯示

  145.         if(++ms >= 200)
  146.         {
  147.                 flag200ms = 1;
  148.                 ms = 0;
  149.                 if(flag5s < 5 && clock)         //鬧鐘5秒時間判斷
  150.                 {
  151.                         P1_0 = ~P1_0;
  152.                 }
  153.                 else
  154.                 {
  155.                         clock = 0;
  156.                         P1_0 = 0;
  157.                 }
  158.                 if(++flag1s >= 5)
  159.                 {
  160.                         flag1s = 0;
  161.                         flag = ~flag;
  162.                         if(clock)
  163.                                 flag5s++;
  164.                         else
  165.                                 flag5s = 0;
  166.                 }
  167.         }        
  168. }
  169. //向DS1302寫入時間
  170. void TimeWeite()
  171. {
  172.         unsigned char ti[3];  
  173.         //將兩個分開的時間合成在一起
  174.         ti[0] = ((num[6]<<4) | num[7]);
  175.         ti[1] = ((num[3]<<4) | num[4]);
  176.         ti[2] = ((num[0]<<4) | num[1]);

  177.         Ds1302_Time(ti);
  178. }

  179. void key()
  180. {
  181.         if((P3_0==0||P3_1==0||P3_2==0||P3_3==0)&&clock==1)        //鬧鐘響應,進行關閉
  182.         {
  183.                 clock = 0;
  184.                 while(!P3_0);while(!P3_1);
  185.                 while(!P3_2);while(!P3_3);
  186.         }

  187.         if(timesetup!=1 && clocksetup!=1 && P3_0==1)        //按下顯示溫度值,松開顯示時間
  188.         {
  189.                 Ds1302_Display();
  190.         }else if(timesetup!=1 && clocksetup!=1 &&P3_0 == 0)
  191.         {
  192.                 Ds18b20_Display();        
  193.         }
  194.         if(clocksetup !=1 && P3_3 == 0)                //進入時間設置
  195.         {
  196.                 timesetup = 1;
  197.                 position++;
  198.                 if(position == 4)        //向DS1302重新寫入時間
  199.                 {
  200.                         TimeWeite();
  201.                 }
  202.                 while(!P3_3);
  203.         }
  204.         if(timesetup !=1 && P3_2 == 0)           //進入鬧鐘時間設置
  205.         {
  206.                 clocksetup = 1;
  207.                 position++;
  208.                 clock = 0;
  209.                 while(!P3_2);
  210.         }
  211.         if((timesetup==1||clocksetup==1) && P3_0 == 0)        //進入時間設置, 時間+1
  212.         {         
  213.           if(timesetup)                //實時時鐘設置
  214.           {
  215.                   if(position == 1)          //秒
  216.                 {
  217.                         if(++num[7] >= 10)
  218.                         {
  219.                                 num[7] = 0;
  220.                                 if(++num[6] >=6)
  221.                                         num[6] = 0;
  222.                         }
  223.                 }else
  224.                 if(position == 2)         //分
  225.                 {
  226.                         if(++num[4] >= 10)
  227.                         {
  228.                                 num[4] = 0;
  229.                                 if(++num[3] >=6)
  230.                                         num[3] = 0;
  231.                         }
  232.                 }else
  233.                 if(position == 3)         //時
  234.                 {
  235.                         if(num[0] == 2)
  236.                         {
  237.                                 if(++num[1] >= 5)
  238.                                 {
  239.                                         num[1] = 0;
  240.                                         num[0] = 0;
  241.                                 }        
  242.                         }else
  243.                         if(++num[1] >= 10)
  244.                         {
  245.                                 num[1] = 0;
  246.                                 if(++num[0] >=3)
  247.                                         num[0] = 0;
  248.                         }
  249.                 }
  250.           }else if(clocksetup)          //鬧鐘時間設置
  251.           {
  252.                   if(position == 1)          //秒
  253.                 {
  254.                         if(++timeclock[7] >= 10)
  255.                         {
  256.                                 timeclock[7] = 0;
  257.                                 if(++timeclock[6] >=6)
  258.                                         timeclock[6] = 0;
  259.                         }
  260.                 }else
  261.                 if(position == 2)         //分
  262.                 {
  263.                         if(++timeclock[4] >= 10)
  264.                         {
  265.                                 timeclock[4] = 0;
  266.                                 if(++timeclock[3] >=6)
  267.                                         timeclock[3] = 0;
  268.                         }
  269.                 }else
  270.                 if(position == 3)         //時
  271.                 {
  272.                         if(timeclock[0] == 2)
  273.                         {
  274.                                 if(++timeclock[1] >= 4)
  275.                                 {
  276.                                         timeclock[1] = 0;
  277.                                         timeclock[0] = 0;
  278.                                 }        
  279.                         }else
  280.                         if(++timeclock[1] >= 10)
  281.                         {
  282.                                 timeclock[1] = 0;
  283.                                 if(++timeclock[0] >=3)
  284.                                         timeclock[0] = 0;
  285.                         }
  286.                 }        
  287.           }
  288.           while(!P3_0);
  289.         }
  290.         if((timesetup==1||clocksetup==1) && P3_1 == 0)         //進入時間設置, 時間-1
  291.         {        
  292.                 if(timesetup)           //實時時鐘設置
  293.           {
  294.                   if(position == 1)        //秒
  295.                 {
  296.                         if(--num[7] < 0)
  297.                         {
  298.                                 num[7] = 9;
  299.                                 if(--num[6] < 0)
  300.                                         num[6] = 5;
  301.                         }
  302.                 }else
  303.                 if(position == 2)        //分
  304.                 {
  305.                         if(--num[4] < 0)
  306.                         {
  307.                                 num[4] = 9;
  308.                                 if(--num[3] < 0)
  309.                                         num[3] = 5;
  310.                         }
  311.                 }else
  312.                 if(position == 3)  //時
  313.                 {
  314.                         if(--num[1] < 0)
  315.                         {
  316.                                 num[1] = 9;
  317.                                 if(--num[0] < 0)
  318.                                 {
  319.                                         num[0] = 2;
  320. ……………………

  321. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
基于單片機的電子鐘.zip (84.07 KB, 下載次數: 115)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:171060 發表于 2017-12-23 22:05 來自手機 | 只看該作者
感謝分享。
回復

使用道具 舉報

板凳
ID:368508 發表于 2018-7-11 14:18 | 只看該作者
感謝大佬!!!!
回復

使用道具 舉報

地板
ID:471752 發表于 2019-1-22 17:07 | 只看該作者
厲害,謝謝樓主
回復

使用道具 舉報

5#
ID:544311 發表于 2020-11-29 16:47 | 只看該作者
謝謝大佬的分享,給了我很大幫助。
回復

使用道具 舉報

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

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 99tv | 久久久国产一区二区 | 天天干夜夜操视频 | 免费观看a级毛片在线播放 黄网站免费入口 | 亚洲国产精品成人久久久 | 国产在线看片 | 一区二区视频在线观看 | 久久av一区 | 久久精品免费 | 亚洲精品日韩欧美 | 久久99精品久久久 | 香蕉久久a毛片 | 在线成人精品视频 | 啪视频在线| 高清一区二区视频 | 国产一级片久久久 | 亚洲在线观看视频 | 日本视频一区二区三区 | 国产精品高潮呻吟久久av黑人 | 国产精品亚洲一区二区三区在线 | 亚洲成av人片在线观看无码 | 日本欧美黄色片 | 久久久人成影片一区二区三区 | 国产日韩精品视频 | 免费a国产| 亚洲高清成人 | 自拍偷拍亚洲一区 | 亚洲精品小视频在线观看 | 羞羞视频在线观看 | 国产福利观看 | 91精品国产一区二区三区 | 久久亚洲视频 | 精品免费国产一区二区三区四区 | 国产视频二区在线观看 | 精品国产一区二区三区性色 | 综合久久色 | 久久久久国产精品一区二区 | 综合激情av | 中文字幕国产精品 | av中文字幕在线播放 | 观看av|