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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于51單片機的數字電子鐘Proteus仿真程序

[復制鏈接]
跳轉到指定樓層
樓主
基于51單片機的數字電子鐘仿真原理圖:

1.設計任務和要求
1、數字電子鐘(使用定時器做計時,用靜態或動態顯示時鐘)
主要設計內容
1)用定時器實現走時功能
2)用 4 位或 6 位數碼管實現時鐘顯示(時、分、秒)
3)用 2 個或多個按鍵實現校時修改(采用移位鍵和加 1 鍵修改時、分、秒)
4)修改校時過程中,被修改位要求定位閃爍,以表明該位數值正在修改
5)時鐘走時,要求秒點閃爍
6)時鐘走時誤差控制在 1 /
7)擴展增加年月日計時功能,并按鍵切換分屏顯示
2.電路設計方案選擇,分析電路工作原理和系統性能
         1. 數據顯示模塊
考慮到要顯示的內容頗多,故運用1602A顯示實時數據,第一行顯示狀態以及年月日星期(如S 2009—01—01 THU),第二行顯示溫度和實時時間(  22.0C12:00:00),在處理按鍵設置時,第二行暫時屏蔽溫度的顯示而顯示設置的內容。這樣雖然在程序方面多了1602A的一些初始化和讀寫子函數的定義,但程序的模塊化卻更加的清楚。而且采用1602A LCM的液晶顯示模塊后不僅滿足了大量數據的顯示,系統的硬件電路變的十分簡單清晰明
2.溫度采集模塊
采用常用的溫度采集芯片DS18B20單線數字溫度傳感器進行溫度的采集DS18B20的外部電源供電方式 在外部電源供電方式下,DS18B20工作電源由VDD引腳接入,此時I/O線不需要強上拉,不存在電源電流不足的問題,可以保證轉換精度,外部電源供電方式是DS18B20最佳的工作方式,工作穩定可靠,抗干擾能力強,而且電路也比較簡單。在外接電源方式下,可以充分發揮DS18B20寬電源電壓范圍的優點,即使電源電壓VCC降到3V時,依然能夠保證溫度量精度。外接電源解決了電壓方面的苛刻要求,雖多接了一根線,但對于本設計的近距離測試來說還是很適合的
     3.時間處理模塊
利用51內部的定時器和中生成秒,再利用程序累加清零等基本時間,爾后再調用C中一些經典的算法生成年月日以及星期等信息。但是該方案必須保證系統一直處于供電的情況,不能斷電,否則時間由初始化了,所以該方案中又添加了三個設置按鈕,也就是增加了一個設置調整模塊,在再次供電后可以調整時間以同步,完美的解決了時間的連續性問題。這雖使得電路和方案一復雜度相當,但是系統的設計對資源的利用更充分。
        4.調整設置模塊
這個模塊完全是第三個模塊的一個衍生品,它就是為了調整時間以便斷電后正常使用。該模塊包括四個按鍵(兩個中斷,兩個設置),一個中斷就是簡單要停止鬧鐘;另一個中斷時是停止時鐘,進入設置狀態,包括調整時間以同步和設置鬧鐘的值,而另外兩個設置建一個就是為了此時增加或減少時間值,另一個的作用是在調整完了當前量后進入下一個量的調整或退出調整。

3.主控制器AT89C52介紹
1.AT89C52功能介紹
AT89C52是8字節FLASH閃速存儲器,256字竹內部RAM , 32個I/O口線,3個16 位定時/計數器,一個6向量兩級中斷結構,一個全雙工串行通信口,片內振蕩器及時鐘電路。同時,AT89c52可降至OHz的靜態邏輯操作,并支持兩種軟件可選的節電上作模式。空閑方式停止CPU 的工作,但允許RAM,定時/計數器.串行通信口及中斷系統繼續工作。掉電方式保存RAM 中的內容,但振蕩器停止工作并禁止其它所有部件工作直到下一個硬件復位.
2.功能引腳說明:
Vcc:電源電壓
GND:地
P0:P0口是一組8位漏極開路型雙向1/O 口,也即地址/數據總線復用口。作為輸出口用時.每位能吸收電流的方式驅動8個TTL 邏輯門電路,對端口P0 寫“1”時,可作為高阻抗輸入端用。
在訪問外部數據存儲器或程序存儲器時,這組口線分時轉換地址(低8位)和數據總線復用,在訪問期間激活內部 上拉電阻。
FLASH由編程時,P0口接收指令字節,而在程序校驗時,輸出指令字 節,校驗時,要求外接上拉電阻。
P1口:PI 是一個帶內部上拉電阻的8位雙向I/O口,Pl的輸出緩沖級可驅動(吸收或輸出電流4個TTL邏輯門電路。對端口寫“1”,通過內部的上拉電阻把端口拉到高電平,此時可作輸入口。作 輸入口使用時,因為內部存在上拉電阻某個引腳被外部信號拉低時會輸出一個電流IIL
AT89C51不同之處是,Pl.0 和P1.1還可分別作為定時/計數器2 的外部計數輸入(Pl.0/T2 )和輸入(P1.1/T2EX) ,
FLASH編程和程序校驗期間,Pl接收低8位地址。
PI.O 和PI.l 的第二功能:
P2 是一個帶有內部上拉電阻的8位雙向I/O口,P2的輸出緩沖級可驅動(吸收或輸出電流)4個TTL邏輯電路。對端口P2寫“l",通過內部的上拉電阻把端口拉到高電平,此時可作輸入口,           作輸入口使用時,因為內部存在上拉電阻,某個引腳被外部信號拉低時會輸出一個電流(llt )。
在訪問外部程序存儲器或16位地址的外部數據存儲器,P2送出高8 位地址數據。在訪問8位地址的外部數據存儲器、如執行MOVX@RI指令)時,P2口輸出P2鎖存器的內容。
FLASH編程或校驗時,P2亦接收高位地址和一些控制信號。
     P3口:P3口是一組帶有內部上拉電阻的8位雙向I/O口。P3口輸出緩沖級可驅動(吸收或輸出電流)4個TTL邏輯門電路。對P3口寫入“1”時,它們被內部上拉電阻拉高并可作為輸入端口。此時,被外部拉低的P3口將用上拉電阻輸出電流(IIL) .
P3口除了作為一般的I/0口線外,更重要的用途是它的第二功能,如下表所示:
P3.0 RXD(串行輸入口〕
P3.1 TXD(串行輸出口〕
P3.2 INTO(外中斷0〕
P3.3 INTO(外中斷l)
P3.4 TO (定時/計數器0 )
P3.5 Tl (定時/計數器l )
P3.6 WR(外部數據存儲器寫選通)
P3.7 RD(外部數據存儲器讀選通)
此外,P3口還接收一些用于FLASH閃速存儲器編程和程序校驗的控制信號。
RST:復位輸入。當振蕩器工作時,RST引腳出現兩個機器周期以上高電平將使單片機復位。
ALE/PROG:當訪問外部程序存儲器或數據存儲器時,ALE(地址鎖存允許)輸出脈沖用于鎖存地址的低8位字節.一般情況下,ALE仍以時鐘振蕩頻率的1/6輸出固定的脈沖信號,因此它可對外輸出時鐘或用于定時目的。要注意的是:每當訪問外部數據存儲器時將跳過一個ALE脈沖。對Flash存儲器編程期間,該引腳還用于輸入編程脈沖(PROG)。如有必要,可通過對特殊功能寄存器(SFR)區中的8EH單元的D0位置位.可禁止ALE操作。該位置位后,只有一條MOVX和MOVC指令才能將ALE激活,此外,該引腳會被微弱拉高,單片機執行外部程序時,應設置ALE禁止位無效。
PSEN:程序儲存允許PSEN輸出是外部程序存儲器的讀選通信號,當AT89C52由外部程序存儲器取指令(或數據)時,每個機器周期兩次PSEN有效,即輸出兩個脈沖。在此期間,當訪問外部數據存儲器,將跳過兩次PSEN信號。
EA/VPP:外部訪問允許。欲使CPU 僅訪問外部程序存儲器(地址為0000H-FFFFH ) , EA端必須保持低電平(接地).需注怠的是:如果加密位LBI被編程,復位時內部會鎖存EA端狀態。
3.最小系統
單片機最小系統包括時鐘電路、電源和復位電路等,是單片機工作的基本要求。單片機控制整個系統的工作,一方面讀取日歷時鐘芯片中的日期等數據,檢測是否需要設置,并處理相應的按鍵。另一方面,控制顯示器的工作,將各種數據送到液晶顯示器去顯 80C52型單片機內有一增益反相放大器,振蕩頻率取決于石英晶體的振蕩頻率。范圍可取1。2—12MHZ,C01、C02主要起頻率微調和穩定作用。
(1)復位電路
單片機在開關機時都需要復位,以便中央處理器CPU及其他功能部件都RC構成處于一個確定的初始狀態,并從這個狀態開始工作。80C51RST引腳是復位信號的輸入端。復位信號高電平有效,持續時間需要24個時鐘周期以上。
RC構成微分電路,在接電瞬間,產生一個微分脈沖,其寬度若大于2個機器周期,80C51型單片機將復位。為保證微分脈沖寬度足夠大,RC時間常數應大于2個機器周期。一般取10uF電容、8.2K歐姆電阻。
4.振蕩器特性:
XTAL1和XTAL2分別為反向放大器的輸入和輸出。該反向放大器可以配置為片內振蕩器。石晶振蕩和陶瓷振蕩均可采用。如采用外部時鐘源驅動器件,XTAL2應不接。有余輸入至內部時鐘信號要通過一個二分頻觸發器,因此對外部時鐘信號的脈寬無任何要求,但必須保證脈沖的高低電平要求的寬度。
基于51單片機的數字電子鐘源碼:(完整代碼和電路圖在附件中)
  1. #include "reg52.h"
  2. //#include "delay.h"
  3. #include "ds1302.h"        
  4. #include "lcd1602.h"
  5. #include "ds18b20.h"
  6. //#include "stdio.h"

  7. #define uint unsigned int
  8. #define uchar unsigned char

  9. sbit K1=P3^3;                                                //選擇
  10. sbit K2=P3^4;                  //加
  11. sbit K3=P3^5;                  //減
  12. sbit K4=P3^6;                  //確定

  13. sbit BUZZER=P1^0;                                //蜂鳴器

  14. uchar RTC_flag=0;
  15. char RTC_NYRSFM[14]={0};
  16. code char RTC_set_state[6]={'N','Y','R','S','F','M'};
  17. code char Ping_Run_Year[12]={31,28,31,30,31,30,31,31,30,31,30,31};
  18. code char Tab[]={0x08,0x0F,0x12,0x0F,0x0A,0x1F,0x02,0x02,//年
  19.                                                                                 0x0F,0x09,0x0F,0x09,0x0F,0x09,0x0B,0x11,//月
  20.                                                                                 0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x00};//日
  21. /*
  22. 函數作用:將時間進行加一或減一后返回(DA指令轉換)
  23. 函數形參:
  24.                                         DateTime:要轉化的時間
  25.                                         n                                :時間的進制
  26.                                         x                                :1表示加1,0表示減1
  27.                                         y                                :0表示起始數值是0,1表示起始數值是1
  28. 返回值        :轉化好的時間
  29. */
  30. uchar        DA_DateTime(uchar DateTime,uchar n,uchar x,uchar y)
  31. {
  32.         uchar a;
  33.         a=(DateTime>>4)*10+(DateTime&0x0f);
  34.         if(x)//加
  35.         {
  36.                 if(y)        a=(a%n)+1;//起始為0
  37.                 else        a=(++a)%n;
  38.         }
  39.         else//減
  40.         {
  41.                 if(y)        a=(a+n-1)%n;//起始為0
  42.                 else        a=((a+n-2)%n)+1;
  43.         }
  44.         return ((a/10)*16+a%10);
  45. }
  46. /*
  47. 函數作用:刷新星期(2000年~2099年星期算法)
  48. 函數形參:
  49.                                         y:年
  50.                                         m:月
  51.                                         d:日
  52. 返回值        :
  53. */
  54. void RefreshWeekDay(uchar y,uchar m,uchar d)
  55. {
  56.   if(m==1||m==2)
  57.   {
  58.                 m+=12;
  59.                 y--;
  60.   }
  61.   TIME[5]=((d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7);
  62. }
  63. /*
  64. 函數作用:顯示屏顯示從DS1302讀出的時鐘
  65. 函數形參:
  66. 返回值        :
  67. */
  68. void Lcd_1602_Display(void)
  69. {
  70.                 RefreshWeekDay((TIME[6]>>4)*10+(TIME[6]&0x0f),(TIME[4]>>4)*10+(TIME[4]&0x0f),(TIME[3]>>4)*10+(TIME[3]&0x0f));
  71.         
  72.                 L1602_char(1,1,TIME[6]/16+'0');
  73.                 L1602_char(1,2,(TIME[6]&0x0f)+'0');//年
  74.                 L1602_char(1,3,0x00);//自定義漢字年
  75.                 L1602_char(1,4,TIME[4]/16+'0');
  76.                 L1602_char(1,5,(TIME[4]&0x0f)+'0');//月
  77.                 L1602_char(1,6,0x01);//自定義漢字月
  78.                 L1602_char(1,7,TIME[3]/16+'0');
  79.                 L1602_char(1,8,(TIME[3]&0x0f)+'0');//日
  80.                 L1602_char(1,9,0x02);//自定義漢字日
  81.                 L1602_char(1,11,((TIME[5]&0x0f)+6)%7+1+'0');//周
  82.                 L1602_char(2,1,TIME[2]/16+'0');
  83.                 L1602_char(2,2,(TIME[2]&0x0f)+'0');//時
  84.                 L1602_char(2,3,':');
  85.                 L1602_char(2,4,TIME[1]/16+'0');
  86.                 L1602_char(2,5,(TIME[1]&0x0f)+'0');//分
  87.                 L1602_char(2,6,':');
  88.                 L1602_char(2,7,TIME[0]/16+'0');
  89.                 L1602_char(2,8,(TIME[0]&0x0f)+'0');//秒
  90. }
  91. /*
  92. 函數作用:天數加減一
  93. 函數形參:x為1加,0減
  94. 返回值        :
  95. */
  96. void RCT_DA_R(uchar x)
  97. {
  98.         if(((((TIME[6]>>4)*10+(TIME[6]&0x0f))%4==0 && ((TIME[6]>>4)*10+(TIME[6]&0x0f))%100!=0) || (((TIME[6]>>4)*10+(TIME[6]&0x0f))%400==0)) && ((TIME[4]>>4)*10+(TIME[4]&0x0f))==2)//閏年二月
  99.         {
  100.                 TIME[3]=DA_DateTime(TIME[3],29,x,1);
  101.         }
  102.         else
  103.         {
  104.                 TIME[3]=DA_DateTime(TIME[3],Ping_Run_Year[(TIME[4]>>4)*10+(TIME[4]&0x0f)-1],x,1);
  105.         }
  106. }
  107. /*
  108. 函數作用:寫入自定義圖形(年月日)
  109. 函數形參:
  110. 返回值        :
  111. */
  112. void LCD1602_CustomData()
  113. {
  114.         uchar i;
  115.         wcmd(0x40);//定義第一個自定義字符
  116.         for(i=0;i<8*3;i++)
  117.         {
  118.                 wdata(Tab[i]);
  119.         }
  120. }

  121. void Int1_Init()//設置INT1
  122. {
  123.         IT1=1;//跳變沿出發方式(下降沿)
  124.         EX1=1;//打開INT1的中斷允許。
  125.         EA=1;//打開總中斷
  126. }


  127. void main()
  128. {
  129.         uchar i;
  130.         BUZZER=0;
  131.         L1602_init();
  132.         Ds1302_Init();
  133.         Int1_Init();
  134.         LCD1602_CustomData();
  135.         while(1)
  136.         {
  137.                 if(RTC_flag==0)//正常顯示模式
  138.                 {
  139.                         Ds1302ReadTime();//DS1302獲取時間
  140.                         if((TIME[1]==0)&&(TIME[0]==0))//分秒為0,整點報時
  141.                         {
  142.                                 BUZZER=1;
  143.                         }
  144.                         else
  145.                         {
  146.                                 BUZZER=0;
  147.                         }
  148.                         Lcd_1602_Display();//顯示時間
  149.                         L1602_string(1,14,"RTC");
  150.                         datapros();
  151.                 }
  152.                 else//設置模式
  153.                 {
  154.                         BUZZER=0;
  155.                         if(K1==0)
  156.                         {
  157.                                 while(K1==0);
  158.                                 L1602_string(1,14,"[ ]");
  159.                                 for(i=0;i<7;i++)
  160.                                 {
  161.                                         if((i+1)==RTC_flag)//顯示設置的參數狀態
  162.                                         {
  163.                                                 L1602_char(1,15,RTC_set_state[i]);
  164.                                         }
  165.                                 }
  166.                         }
  167.                         else if(K2==0)//加
  168.                         {
  169.                                 while(K2==0);
  170.                                 switch(RTC_flag)
  171.                                 {
  172.                                         case 1:TIME[6]=DA_DateTime(TIME[6],100,1,0);break;
  173.                                         case 2:TIME[4]=DA_DateTime(TIME[4],12,1,1);break;
  174.                                         case 3:RCT_DA_R(1);break;
  175.                                         case 4:TIME[2]=DA_DateTime(TIME[2],24,1,0);break;
  176.                                         case 5:TIME[1]=DA_DateTime(TIME[1],60,1,0);break;
  177.                                         case 6:TIME[0]=DA_DateTime(TIME[0],60,1,0);break;
  178.                                 }
  179.                                 Lcd_1602_Display();
  180.                         }
  181.                         else if(K3==0)//減
  182.                         {
  183.                                 while(K3==0);
  184.                                 switch(RTC_flag)
  185.                                 {
  186.                                         case 1:TIME[6]=DA_DateTime(TIME[6],100,0,0);break;
  187.                                         case 2:TIME[4]=DA_DateTime(TIME[4],12,0,1);break;
  188.                                         case 3:RCT_DA_R(0);break;
  189.                                         case 4:TIME[2]=DA_DateTime(TIME[2],24,0,0);break;
  190.                                         case 5:TIME[1]=DA_DateTime(TIME[1],60,0,0);break;
  191.                                         case 6:TIME[0]=DA_DateTime(TIME[0],60,0,0);break;
  192.                                 }
  193.                                 Lcd_1602_Display();
  194.                         }
  195.                         else if(K4==0)//確定
  196.                         {
  197.                                 while(K4==0);
  198.                                 L1602_string(1,14,"RTC");
  199.                                 Ds1302_Init();//寫進時間
  200.                                 RTC_flag=0;
  201.                         }
  202.                 }
  203.         }               
  204. }

  205. void EX_INT1() interrupt 2
  206. {
  207.         RTC_flag=(RTC_flag++)%6+1;//N Y R S F M
  208. }

復制代碼


全部資料51hei下載地址:
數字時鐘.zip (176.62 KB, 下載次數: 98)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:891233 發表于 2021-11-1 12:11 | 只看該作者
為啥1602不能正常顯示
回復

使用道具 舉報

板凳
ID:1058304 發表于 2022-12-20 20:46 | 只看該作者
為什么打開那個Proteus始終一直再跳,而且設置完成后按下確認也無法改變
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 观看av | 久久精品女人天堂av | 亚洲综合五月天婷婷 | 久久精品欧美一区二区三区不卡 | 国产99久久精品一区二区永久免费 | 中文字幕三区 | 精品国产一区二区三区久久久久久 | 全免一级毛片 | 亚洲精品久久久久avwww潮水 | 日韩精品中文字幕一区二区三区 | 天天宗合网 | 91pao对白在线播放 | 欧美综合久久久 | 日本高清视频在线播放 | 国产精品伦一区二区三级视频 | 日本午夜免费福利视频 | 精品一区二区电影 | 欧美精品一区二区三区在线 | 中文字幕在线视频免费观看 | 欧美久久视频 | 久久亚洲一区二区三区四区 | h视频亚洲| 香蕉国产在线视频 | 成年人的视频免费观看 | 国产免费又黄又爽又刺激蜜月al | 黄色毛片视频 | 精品九九九 | 亚洲高清在线观看 | 久久精品国产一区 | 日本男人天堂 | 国产原创视频 | 亚洲一区在线播放 | 成人欧美一区二区三区黑人孕妇 | 国产精品无码专区在线观看 | 国产福利视频 | 九九在线精品视频 | 亚州精品成人 | 国产精品免费看 | 老妇激情毛片免费 | 午夜视频网站 | 伊大人久久 |