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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

STC89C52單片機+DS1302+數碼管顯示及按鍵調時的時鐘程序Proteus仿真圖

[復制鏈接]
跳轉到指定樓層
樓主
STC89C52單片機+DS1302+數碼管顯示時鐘及按鍵時+整點報時功能
資料含有程序源代碼+及仿真原理圖
仿真軟件運行和實際焊接電路運行都通過驗證。
//注意事項://:仿真時請將程序char H=0,L=1,開發板下載試驗請將變量char H=1  ,L=0;
//:請屏蔽此 DS1302初始化 //init_1302(); 函數。
void main()
{
        t0_init();
        t1_init();
        //init_1302();                //仿真時如你需要顯示當前實時系統時間,請屏蔽此函數。          
        while(1)
        {
           read_sf();
           ExecuteKeyNum();
        }
        
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)

1》按下設置啟動鍵:分鐘閃爍進入分鐘調時,再次按下小時閃爍進入小時調時
2》按下參數加或參數減按鈕:進行小時后分鐘的時間設置
注意:仿真時請將程序里WELA的變量H=0  L=1,開發板試驗請將變量H=1  L=0;

單片機源程序如下:
  1. /*********************************************************************************
  2. 描述: 8位共陰數碼管時鐘,顯示88-88-88樣式,正常走時的時候,兩個“-”0.5秒閃爍一次;
  3.        調時:按KEY1按鍵第1次分鐘位閃爍,再按KEY2一次分鐘加1,按KEY3一次分鐘減1,長按連加連減;
  4.                          按KEY1按鍵第2次小時位閃爍,再按KEY2一次小時加1,按KEY3一次小時減1,長按連加連減;
  5.                          按KEY1按鍵第3次,秒從零開始累加,時鐘回到正常走時;
  6.                          對時的時候先調好時、分,分鐘要比參考時間的分鐘加1分,
  7.                          再看參考時間的秒數到了59再按KEY1按鍵的第3次,這樣對時可以很準的
  8. 仿真 實物都通過.  11.0592MHz晶振,STC89C52RC,兩個74HC573鎖存器做位選、段選
  9. **********************************************************************************/
  10. #include<reg52.h>
  11. #include<intrins.h>

  12. #define uchar unsigned char
  13. #define uint unsigned int

  14. sbit sclk = P2^4;                                                                //1302時鐘端口
  15. sbit dio = P2^5;                                                                //1302數據端口
  16. sbit ce = P2^6;
  17.                                                                         //1302使能
  18. sbit wela1 = P2^0;                                                                //位選
  19. sbit wela2 = P2^1;                                                                //位選
  20. sbit wela3 = P2^2;        
  21. sbit wela4 = P2^3;        

  22. sbit buzzer=P3^7;

  23. sbit KEY1=P3^0;                                                                        //按鍵 設置/確認
  24. sbit KEY2=P3^1;                                                                        //按鍵 加
  25. sbit KEY3=P3^2;                                                                        //按鍵 減

  26. uchar snum,fnum;

  27. char shi,fen,miao,shi_alarm=6;

  28. uchar ss,mm;
  29. char H=0,L=1;                                                //用軟件仿真時關閉數碼管H全部改為0,單片機下載H改為1.
  30. char FunctionKeyNum=0;                                //功能鍵鍵值
  31. char FuncTempNum=0;                                        //功能鍵臨時鍵值
  32. typedef enum KeyState{StateInit,StateAffirm,StateSingle,StateRepeat};        //鍵值狀態值


  33. /***********寫時DS1302地址************/
  34. #define write_year  0x8c         //寫年的地址
  35. #define write_moon  0x88         //寫月的地址
  36. #define write_week  0x8a         //寫周的地址
  37. #define write_day   0x86         //寫日的地址
  38. #define write_shi  0x84                 //寫時的地址
  39. #define write_fen  0x82                 //寫分的地址
  40. #define write_miao 0x80                 //寫秒的地址
  41. #define write_ram  0xc0                 ////RAM的基地址
  42. /***********讀時DS1302地址************/
  43. #define read_year  0x8d                 //讀年的地址
  44. #define read_moon  0x89                 //讀月的地址
  45. #define read_week 0x8b                 //讀周的地址
  46. #define read_day  0x87                 //讀日的地址
  47. #define read_shi  0x85                 //讀時的地址
  48. #define read_fen  0x83                 //讀分的地址
  49. #define read_miao 0x81                 //讀秒的地址
  50. #define read_ram  0xc1                 //RAM的基地址
  51.                   // 0     1    2    3    4     5    6    7    8   9
  52. //uchar d[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //共陰不帶小數點
  53. //uchar d[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};  //        共陰帶小數點
  54. uchar d[]={0Xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};          //共陽極
  55. uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};          //共陽極帶小數點

  56. void Time_alarm();                 //整點報時子程序

  57. void delayms(uint z)
  58. {
  59.         uint x,y;
  60.         for(x=z;x>0;x--)
  61.                 for(y=120;y>0;y--);
  62. }
  63. /*
  64. void buzzer1()
  65. {
  66. uint i;
  67. for(i=0;i<10;i++)
  68.         {
  69.     buzzer=0;
  70.         delayms(500);
  71.         buzzer=1;
  72.         delayms(500);
  73.         }
  74. }
  75. */
  76. void buzzer2() //發聲子程序
  77. {
  78.          
  79.           uint t,tt;
  80.           for(t=0;t<50;t++) //45為蜂鳴器發聲頻率
  81.           {
  82.           buzzer=!buzzer;
  83.           for(tt=0;tt<50;tt++); //45為蜂鳴器發聲頻率
  84.           }
  85. }



  86. void t0_init()  //定時50ms一個中斷
  87. {
  88.    
  89.   TMOD |= 0X01;
  90.   TH0 = (65536-46080)/256;
  91.   TL0 = (65536-46080)%256;
  92.   EA = 1;
  93.   ET0 = 1;
  94.   TR0 = 1;

  95. }

  96. void t1_init()
  97. {
  98.         TMOD |= 0x10;
  99.         TH1 = 0x500;
  100.         TL1 = 0x00;
  101.         TR1 = 1;        
  102. }

  103. void temer0() interrupt 1
  104. {
  105.   TH0=(65536-46080)/256;
  106.   TL0=(65536-46080)%256;
  107.   ss++;
  108.   mm++;
  109.   if(ss==22)
  110.   {
  111.   ss=0;
  112.   }
  113.   if(mm==10)
  114.   {
  115.    mm=0;
  116.    Time_alarm();   
  117. }
  118. }         





  119. void Display(uchar shi,uchar fen)                          //顯示函數
  120. {
  121.         if(FunctionKeyNum==0)
  122.         {
  123.                 snum=30;
  124.                 fnum=30;
  125.         }
  126.         
  127.         if(FunctionKeyNum==1)
  128.         {
  129.                 fnum++;
  130.                 snum=30;
  131.         }
  132.         
  133.         if(FunctionKeyNum==2)
  134.         {
  135.                 snum++;
  136.                 fnum=30;
  137.         }
  138.         
  139.             wela1=H;   //關閉所有數碼管
  140.                 wela2=H;   //用軟件仿真時關閉數碼管H全部改為0,單片機下載H改為1.
  141.                 wela3=H;   //用軟件仿真時關閉數碼管H全部改為0,單片機下載H改為1.
  142.                 wela4=H;

  143.         
  144.         if(snum>=30)
  145.         {        
  146.                 if((shi/10)<1)         //如果小時十位小于1,
  147.                 {        
  148.                 wela1=L;                 // 小時十位就不顯示                  
  149.                 P0=d[0];                           // 小時十位就顯示"0"
  150.                 delayms(2);
  151.                 P0=0xff;
  152.                 wela1=H;
  153.         
  154.                 }
  155.         
  156.                 else
  157.                 {
  158.                 wela1=L;
  159.                 P0=d[shi/10];
  160.                 delayms(2);
  161.                 P0=0xff;
  162.                 wela1=H;

  163.                 }
  164.   
  165.         if(miao%2==0)            //if(miao%2==0) 1秒閃爍1次
  166.   //        if(ss>=20)                 //        這里寫為ss>=10,閃爍頻率可調
  167.                 {                                 
  168.             wela2=L;
  169.                 P0=dd[shi%10];
  170.                 delayms(2);
  171.                 P0=0xff;
  172.                 wela2=H;
  173.               }
  174.                
  175.                 else
  176.                 {
  177.                 wela2=L;
  178.                 P0=d[shi%10];                                                        
  179.                 delayms(2);
  180.                 P0=0xff;
  181.                 wela2=H;
  182.                 }

  183.                 if(snum==60)
  184.                         snum=0;
  185.         }  
  186.                         
  187.    //        if(miao%2==0)         //if(miao%2==0) 1秒閃爍1次
  188.                   if(ss>=20)                 //        這里寫為ss>=10,閃爍頻率可調
  189.                 {                                 
  190.             wela2=L;
  191.                 P0=d[shi%10];
  192.                 delayms(2);
  193.                 P0=0xff;
  194.                 wela2=H;
  195.               }
  196.                                 
  197.         if(fnum>=30)
  198.         {  
  199.                 wela3=L;
  200.                 P0=d[fen/10];
  201.                 delayms(2);
  202.                 P0=0xff;
  203.                 wela3=H;
  204.                         
  205.                 wela4=L;
  206.                 P0=d[fen%10];
  207.                 delayms(2);
  208.                 P0=0xff;
  209.                 wela4=H;
  210.                
  211.                
  212.                 if(fnum==60)
  213.                         fnum=0;
  214.                                 }         
  215. }


  216. void write_1302(uchar add,dat)                 //寫1302函數  
  217. {
  218.         uchar i,temp;
  219.         temp=add;
  220.         ce=0;
  221.         _nop_();
  222.         sclk=0;
  223.         _nop_();
  224.         ce=1;
  225.         _nop_();
  226.         for(i=0;i<8;i++)
  227.         {
  228.                 sclk=0;
  229.                 _nop_();
  230.                 if((temp&0x01)==0x01)
  231.                         dio=1;
  232.                         else
  233.                         dio=0;
  234.                 temp>>=1;
  235.                 sclk=1;
  236.                 _nop_();
  237.         }
  238.         temp=dat;
  239.         for(i=0;i<8;i++)
  240.         {
  241.                 sclk=0;
  242.                 _nop_();
  243.                 if((temp&0x01)==0x01)
  244.                         dio=1;
  245.                         else
  246.                         dio=0;
  247.                 temp>>=1;
  248.                 sclk=1;
  249.                 _nop_();
  250.         }
  251.         ce=0;
  252.         sclk=0;
  253. }
  254. uchar read_1302(uchar add)                                   //讀1302函數               
  255. {
  256.         uchar dat,dat1,i,temp;
  257.         temp=add;
  258.         ce=0;
  259.         _nop_();
  260.         sclk=0;
  261.         _nop_();
  262.         ce=1;
  263.         for(i=0;i<8;i++)
  264.         {
  265.                 sclk=0;
  266.                 _nop_();
  267.                 if((temp&0x01)==0x01)
  268.                         dio=1;
  269.                         else
  270.                         dio=0;
  271.                 temp>>=1;
  272.                 sclk=1;
  273.                 _nop_();
  274.         }
  275.         for(i=0;i<8;i++)
  276.         {
  277.                 sclk=0;
  278.                 _nop_();
  279.                 if(dio)
  280.                     dat|=0x80;
  281.                 if(i<7)
  282.                         dat>>=1;
  283.                 sclk=1;
  284.         }
  285.         dat1=dat/16;
  286.         dat=dat%16;
  287.         dat=dat1*10+dat;  
  288.         ce=0;
  289.         sclk=0;
  290.         return dat;
  291. }                        



  292. void init_1302()                                                        //初始化函數 設置時間
  293. {        
  294.         write_1302(0x8e,0x00);                                        //保護取消,可以進行寫操作
  295.         write_1302(write_year,0x20);
  296.         write_1302(write_moon,0x12);                        //寫入時修改月
  297.         write_1302(write_week,0x30);                        //寫入時修改星期
  298.         write_1302(write_day,0x04);                           //寫時修改日期
  299.         write_1302(write_miao,0x00);        
  300.         write_1302(write_fen,0x30);
  301.         write_1302(write_shi,0x10);
  302.         write_1302(0x8e,0x80);                                        //保護啟動,不能進行寫操作
  303. }         

  304. void read_sf()
  305. {
  306.         shi=read_1302(read_shi);
  307.         fen=read_1302(read_fen);
  308.         miao=read_1302(read_miao);
  309.         Display(shi,fen);

  310. }

  311. void KeyScan(void)
  312. {
  313.         static uchar KeyStateTemp1 = 0;                  //按鍵狀態臨時存儲值1
  314.         static uchar KeyStateTemp2 = 0;                  //按鍵狀態臨時存儲值2
  315.         static uchar KeyStateTemp3 = 0;                  //按鍵狀態臨時存儲值3
  316.         static uchar KeyTime = 0;                          //按鍵延時時間
  317.         bit KeyPressTemp1;                                          //按鍵是否按下存儲值1
  318.         bit KeyPressTemp2;                                          //按鍵是否按下存儲值2
  319.         bit KeyPressTemp3;                                          //按鍵是否按下存儲值3

  320.         KeyPressTemp1 = KEY1;                                  //讀取IO口的鍵值
  321.         switch(KeyStateTemp1)
  322.         {
  323.                 case StateInit:
  324.                         if(!KeyPressTemp1)                                        //KEY1按下
  325.                                 KeyStateTemp1 = StateAffirm;        //按鍵狀態切換到確認態
  326.                 break;
  327.                 case StateAffirm:                                                //確認狀態
  328.                         if(!KeyPressTemp1)                                        //按鍵還在按下
  329.                         {
  330.                                 KeyTime = 0;
  331.                                 KeyStateTemp1 = StateSingle;        //按鍵狀態切換到單擊狀態
  332.                         }
  333.                         else KeyStateTemp1 = StateInit;                //否則按鍵抬起,回到初始態
  334.                 break;
  335.                
  336.                 case StateSingle:                                                //單擊
  337.                          if(KeyPressTemp1)
  338.                          {
  339.                                 KeyStateTemp1 = StateInit;                 //按鍵釋放
  340.                                 FuncTempNum++;                                         //鍵值加1
  341.                                 if(FuncTempNum>3)  
  342.                                 FuncTempNum = 0;
  343.                          }

  344.                          else if(++KeyTime>100)
  345.                          {
  346.                                          KeyPressTemp1 = StateRepeat;
  347.                                         KeyTime = 0;
  348.                          }
  349.                 break;
  350.         
  351.                 case StateRepeat:                                                 //連發
  352.                         if(KeyPressTemp1)
  353.                                 KeyStateTemp1 = StateInit;
  354.                         else
  355.                         {
  356.                                 if(++KeyTime > 10)
  357.                                 {
  358.                                         KeyTime = 0;
  359.                                         FuncTempNum++;
  360.                                         if(FuncTempNum>3)  
  361.                                         FuncTempNum = 0;
  362.                                 }
  363.                                 break;
  364.                         }
  365.                 break;
  366.         
  367.                 default :KeyStateTemp1 = KeyStateTemp1 = StateInit; break;
  368.                         
  369.         }


  370. if(FuncTempNum)                                                                //只有功能鍵被按下后,增加和減小鍵才有效
  371.         {
  372.                 KeyPressTemp2 = KEY2;                                        //讀取I/O口的鍵值
  373.                 switch(KeyStateTemp2)
  374.                 {        
  375.                         case StateInit:                                                //按鍵初始狀態
  376.                                 if(!KeyPressTemp2)                                //當按鍵按下,狀態切換到確認態
  377.                                         KeyStateTemp2 = StateAffirm;
  378.                                 break;
  379.                         case StateAffirm:                                        //按鍵確認態
  380.                                 if(!KeyPressTemp2)
  381.                                 {
  382.                                         KeyTime = 0;
  383.                                         KeyStateTemp2 = StateSingle;//切換到單次觸發態        
  384.                                 }
  385.                                 else KeyStateTemp2 = StateInit; //按鍵已抬起,切換到初始態
  386.                                 break;
  387.                         case StateSingle:                                        //按鍵單發態
  388.                                 if(KeyPressTemp2)                                //按下時間小于1s
  389.                                 {
  390.                                         KeyStateTemp2 = StateInit;  //按鍵釋放,則回到初始態
  391.                                         if(FunctionKeyNum == 1)                //若功能鍵第一次按下
  392.                                         {
  393.                                         fen++;
  394.                                         fen=fen/10*16+fen%10;                //轉為16進制
  395.                                         if(fen==0x60)
  396.                                             fen=0x00;
  397.                                            write_1302(write_fen,fen);        //寫入1302
  398. ……………………

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

所有資料51hei附件下載:
STC89C52單片機+DS1302+數碼管顯示及按鍵調時的時鐘程序.7z (72.88 KB, 下載次數: 58)

評分

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

查看全部評分

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美激情欧美激情在线五月 | 国产一区二区在线视频 | 成人看片在线观看 | 韩日在线 | 欧美日韩不卡合集视频 | 国产91黄色 | 国产精品久久久久久久久久 | 午夜精品一区二区三区在线视频 | www.4567| www.久久99 | 人人九九精 | 午夜影院操 | heyzo在线| 日本小电影在线 | 日韩精品一区二区三区 | 欧美午夜在线 | 国产福利资源 | 欧美日韩精选 | 精品亚洲永久免费精品 | 欧美精品福利视频 | 久久久www成人免费精品 | 久久亚洲综合 | 日韩a| 国产成人免费 | 亚洲天堂一区二区 | 中文字幕精品一区二区三区精品 | 中文字幕 视频一区 | 国产亚洲成av人片在线观看桃 | 日韩精品一区二区三区中文字幕 | 精品一区二区三区在线观看 | 精品国产一级 | 国产91视频一区二区 | 久在线| 亚洲成人福利在线观看 | 日韩欧美国产一区二区三区 | 国产成人小视频 | 国产精品免费一区二区三区四区 | 日韩av一区在线观看 | 一区二区三区国产精品 | 日韩欧美在线免费观看视频 | av黄色在线观看 |