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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8677|回復: 13
收起左側

12864萬年歷(單片機畢業設計可參考)

  [復制鏈接]
ID:198608 發表于 2018-3-11 10:20 | 顯示全部樓層 |閱讀模式
它可以對年、月、日、時、分、秒進行計時,還具有閏年補償等多種功能,而且DS1302的使用壽命長,誤差小。對于數字電子萬年歷采用直觀的數字顯示,可以同時顯示年、月、日、時、分、秒和溫度等信息,還具有時間校準等功能。該電路采用AT89C51單片機作為核心,DS1302時鐘芯片作為時鐘數據的時間,用DS18b20Z作為溫度傳感器,降低單片機芯片內部資源的消耗,功耗小,工作電壓5V。阿陽工作室
一、 設計要求:
1、系統要控制準確無誤;
2、可以調整萬年歷時間;
3、可以設置鬧鐘
4、用12864顯示時間,溫度;
5、分析電路的工作原理和工作過程。
QQ1137035271

實物圖:
1 (10).JPG 1.jpg 2.jpg 1 (9).JPG QQ截圖20180310213049.png

單片機源程序如下:
  1. #include <reg52.h>                 //調用單片機頭文件
  2. #define uchar unsigned char  //無符號字符型 宏定義        變量范圍0~255
  3. #define uint  unsigned int         //無符號整型 宏定義        變量范圍0~65535
  4. #include "nongli.h"

  5. uchar code shuzi[]="0123456789ABCDEF";
  6. char  code shuzi_c[]="0123456789ABCDEF";//uchar xdata dat_12864[64][16];

  7. sbit rs=P0^2;         //寄存器選擇信號 H:數據寄存器          L:指令寄存器
  8. sbit rw=P0^1;         //寄存器選擇信號 H:數據寄存器          L:指令寄存器
  9. sbit e =P0^0;         //片選信號   下降沿觸發
  10. sbit LCD12864_PSB=P0^3;

  11. sbit beep = P3^7;        //蜂鳴器IO口

  12. sbit dq   = P3^2;          //18b20 IO口的定義
  13. uint temperature ;    //溫度變量


  14. bit flag_200ms = 1;
  15. uchar menu_1;
  16. uchar flag_clock_en;        //鬧鐘標志位
  17. uchar open1;        //鬧鐘開標志位
  18. uchar flag_c_en;
  19. bit flag_100ms;

  20. uchar n_nian,n_yue,n_ri;

  21. /********************************************************************
  22. * 名稱 : delay_1ms()
  23. * 功能 : 延時1ms函數
  24. * 輸入 : q
  25. * 輸出 : 無
  26. ***********************************************************************/
  27. void delay_1ms(uint q)
  28. {
  29.         uint i,j;
  30.         for(i=0;i<q;i++)
  31.                 for(j=0;j<115;j++);
  32. }


  33. #include "ds1302.h"


  34. /*********************定時器0、定時器1初始化******************/
  35. void time0_init()         
  36. {                                         
  37.         EA  = 1;                   //開總中斷
  38.         TMOD = 0X11;          //定時器0、定時器1工作方式1
  39.         ET0 = 1;                  //開定時器0中斷
  40.         TR0 = 1;                  //允許定時器0定時
  41. }
  42.                                                    
  43.                                           
  44. /************ 延時函數  *****************/
  45. void delay_uint(uint z)
  46. {
  47.    while(z--);
  48. }

  49. /***************交換函數 高位變低位 低位變高位*****************/
  50. uchar change_dat(uchar dat)
  51. {
  52.         uchar i,value;
  53.         for(i=0;i<8;i++)
  54.         {        
  55.                 value <<= 1;
  56.                 if((dat & 0x01) == 0x01)
  57.                         value |= 0x01;
  58.                 dat >>= 1;        
  59.         }
  60.         return value;
  61. }

  62. /************ 寫命令函數  *****************/
  63. void write_com(uchar com)
  64. {

  65.    P2=com;//change_dat(com);
  66.    rw=0;
  67.    rs=0;
  68.    delay_uint(25);
  69.    e=1;
  70.    delay_uint(50);
  71.    e=0;
  72. }
  73. /************ 寫數據函數  *****************/
  74. void write_dat(uchar dat)
  75. {

  76.    P2=dat;//change_dat(dat);;
  77.    rw=0;
  78.    rs=1;
  79.    delay_uint(25);
  80.    e=1;
  81.    delay_uint(50);
  82.    e=0;
  83. }

  84. /**********************************************************
  85. *函數名: addr_12864
  86. *功能:寫地址
  87. *說明:寫漢字時要寫個地址
  88. *輸入:無
  89. *返回:無
  90. **********************************************************/
  91. void addr_12864(uchar hang,uchar lie)          //地址轉換
  92. {
  93.         uchar address;
  94.         switch(hang)
  95.         {
  96.                 case 1: address=0x80 + lie ;
  97.                                 break;
  98.                 case 2: address=0x90 + lie ;
  99.                                 break;
  100.                 case 3: address=0x88 + lie ;
  101.                                 break;
  102.                 case 4: address=0x98 + lie ;
  103.                                 break;
  104.                 default :
  105.                                 break;
  106.         }        
  107.         write_com(address);
  108. }

  109. /**********************************************************
  110. *函數名: write_shu16
  111. *功能:在12864上顯示16進制數據
  112. *說明:
  113. *輸入:無
  114. *返回:無
  115. **********************************************************/
  116. void write_shu16(uchar hang,uchar lie,uchar dat)
  117. {
  118.         addr_12864(hang,lie);          //地址轉換        
  119.         write_dat(shuzi[dat/16]);        
  120.         write_dat(shuzi[dat%16]);        
  121. }

  122. /**********************************************************
  123. *函數名: write_string
  124. *功能:在12864上顯示字符數據
  125. *說明:
  126. *輸入:無
  127. *返回:無
  128. **********************************************************/

  129. void write_string(uchar hang,uchar lie,uchar *p)
  130. {
  131.         addr_12864(hang,lie);          //地址轉換
  132.         while(*p != '\0')
  133.         {
  134.                 write_dat(*p);
  135.                 p++;
  136.                 delay_uint(50);
  137.         }
  138. }


  139. /*****************控制光標函數********************/
  140. void write_guanbiao(uchar hang,uchar lie,uchar date)
  141. {               
  142.         addr_12864(hang,lie);         
  143.         if(date == 1)
  144.                 write_com(0x0f);     //顯示光標并且閃爍        
  145.         else
  146.                 write_com(0xc0);   //關閉光標
  147. }         


  148. /************12864液晶初始化函數*****************/
  149. void init_12864()
  150. {
  151.         LCD12864_PSB=1;   //串口模式
  152.    write_com(0x30);
  153.    write_com(0x0c);
  154.    write_com(0x01);
  155. }

  156. /*------------------------清除12864------------------------------*/
  157. void clear_12864()
  158. {
  159.         write_string(1,0,"                ");        //1行        
  160.         write_string(2,0,"                ");        //2行        
  161.         write_string(3,0,"                ");        //3行        
  162.         write_string(4,0,"                ");        //4行        
  163. }


  164. /************初始化顯示*****************/
  165. void init_12864_dis()
  166. {
  167.         write_string(1,0,"液晶多功能臺歷");
  168.         write_string(2,0,"陽歷2000年00月00");
  169.         write_string(3,0,"農歷00-00 星期  ");
  170.         write_string(4,0," 00:00:00 00.0℃");
  171.         write_guanbiao(1,1,0);
  172. }

  173. /************初始化設置顯示*****************/
  174. void init_12864_set1()
  175. {
  176.         clear_12864();
  177.         write_string(1,0,"2015年00月00日  ");
  178.         write_string(2,0,"  00時00分00秒  ");
  179.         write_string(3,0,"設置  星期01    ");
  180.         write_string(4,0,"鬧鐘開  00時00分");
  181.         if(open1 == 1)
  182.                 write_string(4,2,"開");
  183.         else
  184.                 write_string(4,2,"關");
  185.         write_guanbiao(1,1,1);
  186. }

  187. /***********************18b20初始化函數*****************************/
  188. void init_18b20()
  189. {
  190.         bit q;
  191.         dq = 1;                                //把總線拿高
  192.         delay_uint(1);            //15us
  193.         dq = 0;                                //給復位脈沖
  194.         delay_uint(80);                //750us
  195.         dq = 1;                                //把總線拿高 等待
  196.         delay_uint(10);                //110us
  197.         q = dq;                                //讀取18b20初始化信號
  198.         delay_uint(20);                //200us
  199.         dq = 1;                                //把總線拿高 釋放總線
  200. }

  201. /*************寫18b20內的數據***************/
  202. void write_18b20(uchar dat)
  203. {
  204.         uchar i;
  205.         for(i=0;i<8;i++)
  206.         {                                         //寫數據是低位開始
  207.                 dq = 0;                         //把總線拿低寫時間隙開始
  208.                 dq = dat & 0x01; //向18b20總線寫數據了
  209.                 delay_uint(5);         // 60us
  210.                 dq = 1;                         //釋放總線
  211.                 dat >>= 1;
  212.         }        
  213. }

  214. /*************讀取18b20內的數據***************/
  215. uchar read_18b20()
  216. {
  217.         uchar i,value;
  218.         for(i=0;i<8;i++)
  219.         {
  220.                 dq = 0;                         //把總線拿低讀時間隙開始
  221.                 value >>= 1;         //讀數據是低位開始
  222.                 dq = 1;                         //釋放總線
  223.                 if(dq == 1)                 //開始讀寫數據
  224.                         value |= 0x80;
  225.                 delay_uint(5);         //60us        讀一個時間隙最少要保持60us的時間
  226.         }
  227.         return value;                 //返回數據
  228. }

  229. /*************讀取溫度的值 讀出來的是小數***************/
  230. uint read_temp()
  231. {
  232.         uint value;
  233.         uchar low;                           //在讀取溫度的時候如果中斷的太頻繁了,就應該把中斷給關了,否則會影響到18b20的時序
  234.         init_18b20();                   //初始化18b20
  235.         write_18b20(0xcc);           //跳過64位ROM
  236.         write_18b20(0x44);           //啟動一次溫度轉換命令
  237.         delay_uint(50);                   //500us

  238.         init_18b20();                   //初始化18b20
  239.         
  240.         write_18b20(0xcc);           //跳過64位ROM
  241.         write_18b20(0xbe);           //發出讀取暫存器命令
  242.         
  243.         EA = 0;
  244.         low = read_18b20();           //讀溫度低字節
  245.         value = read_18b20();  //讀溫度高字節
  246.         EA = 1;
  247.         value <<= 8;                   //把溫度的高位左移8位
  248.         value |= low;                   //把讀出的溫度低位放到value的低八位中
  249.         value *= 0.625;               //轉換到溫度值 小數
  250.         return value;                   //返回讀出的溫度 帶小數
  251. }


  252. /******************時間芯片顯示函數**********************/           
  253. void ds1302_dis()
  254. {
  255.         uchar miao_1;
  256.         if(menu_1 == 0)
  257.         {
  258.                 read_time();
  259.                 if(miao_1 != miao)
  260.                 {
  261.                         miao_1 = miao;
  262.                         Conversion(0,nian,yue,ri);        //農歷轉換                                    
  263.                         n_nian = year_moon ;
  264.                         n_yue  = month_moon ;
  265.                         n_ri   = day_moon ;
  266.                         write_shu16(2,3,nian);           //顯示年
  267.                         write_shu16(2,5,yue);           //顯示月
  268.                         write_shu16(2,7,ri);           //顯示日
  269.                         write_shu16(3,7,week);           //顯示星期
  270.                         
  271.                         addr_12864(3,2);          //地址轉換        
  272.                         write_dat(shuzi[n_yue/16]);        
  273.                         write_dat(shuzi[n_yue%16]);        
  274.                         write_dat('-');        
  275.                         write_dat(shuzi[n_ri/16]);        
  276.                         write_dat(shuzi[n_ri%16]);        
  277.                                        
  278.                         addr_12864(4,0);          //地址轉換
  279.                         write_dat(' ');               
  280.                         write_dat(shuzi[shi/16]);        
  281.                         write_dat(shuzi[shi%16]);        
  282.                         write_dat(':');        
  283.                         write_dat(shuzi[fen/16]);        
  284.                         write_dat(shuzi[fen%16]);        
  285.                         write_dat(':');        
  286.                         write_dat(shuzi[miao/16]);        
  287.                         write_dat(shuzi[miao%16]);        

  288.                         write_dat(' ');        
  289.                         write_dat(shuzi[temperature/100%10]);        
  290.                         write_dat(shuzi[temperature/10%10]);        
  291.                         write_dat('.');        
  292.                         write_dat(shuzi[temperature%10]);        


  293.                 }
  294.         }
  295. }



  296. /********************獨立按鍵程序*****************/
  297. uchar key_can;         //按鍵值

  298. void key()         //獨立按鍵程序
  299. {
  300.         static uchar key_new;
  301.         key_can = 20;                   //按鍵值還原
  302.         P3 |= 0x78;                     //對應的按鍵IO口輸出為1
  303.         if((P3 & 0x78) != 0x78)                //按鍵按下
  304.         {
  305.                 delay_1ms(1);                     //按鍵消抖動
  306.                 if(((P3 & 0x78) != 0x78) && (key_new == 1))
  307.                 {                                                //確認是按鍵按下
  308.                         key_new = 0;
  309.                         switch(P3 & 0x78)
  310.                         {
  311.                                 case 0x70:  key_can = 1;  break;         //得到按鍵值
  312.                                 case 0x68:  key_can = 2;  break;         //得到按鍵值
  313.                                 case 0x58:  key_can = 3;  break;         //得到按鍵值
  314.                                 case 0x38:  key_can = 4;  break;         //得到按鍵值
  315.                         }
  316. //                        write_sfm2(1,0,key_can);                                 //顯示按鍵值
  317.                 }                        
  318.         }
  319.         else
  320.                 key_new = 1;        
  321. }

  322. /**********************設置函數************************/
  323. void key_with()
  324. {
  325.         if(key_can == 4)   //退出鍵
  326.         {
  327.                 init_12864();
  328.                 init_12864_dis();
  329.                 flag_200ms = 1;
  330.                 menu_1 = 0;
  331.         }
  332.         if(key_can == 1)        //設置鍵
  333.         {
  334.                 menu_1 ++;
  335.                 flag_200ms = 1;
  336.                 if(menu_1 == 1)
  337.                         init_12864_set1();
  338.                 if(menu_1 > 10)
  339.                         menu_1 = 1;
  340.         }
  341.         if(menu_1 != 0)
  342.         {
  343.                 if(menu_1 == 1)                  //設置年
  344.                 {
  345.                         if(key_can == 2)        //加
  346.                                 set_ds1302time(1,&nian,0x99);               
  347.                         if(key_can == 3)        //減         
  348.                                 set_ds1302time(0,&nian,0x99);        
  349.                 }
  350.                 if(menu_1 == 2)                  //設置月
  351.                 {
  352.                         if(key_can == 2)        //加
  353.                                 set_ds1302time(1,&yue,0x13);               
  354.                         if(key_can == 3)        //減         
  355.                                 set_ds1302time(0,&yue,0x13);        
  356.                 }
  357.                 if(menu_1 == 3)                  //設置日
  358.                 {
  359.                         if(key_can == 2)        //加
  360.                                 set_ds1302time(1,&ri,0x32);               
  361.                         if(key_can == 3)        //減         
  362.                                 set_ds1302time(0,&ri,0x32);        
  363.                 }
  364.                 if(menu_1 == 4)                  //設置時
  365.                 {
  366.                         if(key_can == 2)        //加
  367.                                 set_ds1302time(1,&shi,0x24);               
  368.                         if(key_can == 3)        //減         
  369.                                 set_ds1302time(0,&shi,0x24);        
  370.                 }
  371.                 if(menu_1 == 5)                  //設置分
  372.                 {
  373.                         if(key_can == 2)        //加
  374.                                 set_ds1302time(1,&fen,0x60);               
  375.                         if(key_can == 3)        //減         
  376.                                 set_ds1302time(0,&fen,0x60);        
  377.                 }
  378.                 if(menu_1 == 6)                  //設置秒
  379.                 {
  380.                         if(key_can == 2)        //加
  381.                                 set_ds1302time(1,&miao,0x60);               
  382.                         if(key_can == 3)        //減         
  383.                                 set_ds1302time(0,&miao,0x60);        
  384.                 }
  385.                 if(menu_1 == 7)                  //設置星期
  386.                 {
  387.                         if(key_can == 2)        //加
  388.                                 set_ds1302time(1,&week,0x8);               
  389.                         if(key_can == 3)        //減         
  390.                                 set_ds1302time(0,&week,0x8);        
  391.                 }
  392.                 if(menu_1 == 8)                  //設置鬧鐘時
  393.                 {
  394.                         if(key_can == 2)        //加
  395.                                 set_ds1302time(1,&shi1,0x24);               
  396.                         if(key_can == 3)        //減         
  397.                                 set_ds1302time(0,&shi1,0x24);        
  398.                         clock1_save();
  399.                 }
  400.                 if(menu_1 == 9)                  //設置鬧鐘分
  401.                 {
  402.                         if(key_can == 2)        //加
  403.                                 set_ds1302time(1,&fen1,0x60);               
  404.                         if(key_can == 3)        //減         
  405.                                 set_ds1302time(0,&fen1,0x60);
  406.                         clock1_save();        
  407.                 }
  408.                 if(menu_1 == 10)                  //設置鬧鐘分
  409.                 {
  410.                         if((key_can == 2) || (key_can == 3))        //加
  411.                                 open1 ++;
  412.                         if(open1 >= 2)
  413.                                 open1 = 0;
  414.                         if(open1 == 1)
  415.                                 write_string(4,2,"開");
  416.                         else
  417.                                 write_string(4,2,"關");        
  418.                         clock1_save();        
  419.                 }
  420.                 write_shu16(1,1,nian);           //顯示年
  421.                 write_shu16(1,3,yue);           //顯示月
  422.                 write_shu16(1,5,ri);           //顯示日
  423.                 write_shu16(2,1,shi);           //顯示時
  424.                 write_shu16(2,3,fen);           //顯示分
  425.                 write_shu16(2,5,miao);           //顯示秒
  426.                 write_shu16(3,5,week);           //顯示星期                                       
  427.                 write_shu16(4,4,shi1);           //顯示時鐘
  428.                 write_shu16(4,6,fen1);           //顯示分鐘
  429.                 switch(menu_1)           // 光標顯示
  430.                 {
  431.                         case 1:  write_guanbiao(1,1,1);  break;
  432.                         case 2:  write_guanbiao(1,3,1);  break;
  433.                         case 3:  write_guanbiao(1,5,1);  break;
  434.                         case 4:  write_guanbiao(2,1,1);  break;
  435.                         case 5:  write_guanbiao(2,3,1);  break;
  436.                         case 6:  write_guanbiao(2,5,1);  break;
  437.                         case 7:  write_guanbiao(3,5,1);  break;
  438.                         case 8:  write_guanbiao(4,4,1);  break;
  439.                         case 9:  write_guanbiao(4,6,1);  break;
  440.                         case 10: write_guanbiao(4,2,1);  break;
  441.                 }
  442.                 write_time();           //把時間寫進去
  443.         }                        
  444. }

  445. /*************鬧鐘報警函數***************/
  446. void menu_dis()
  447. {
  448.         if(menu_1 == 0)
  449.         if(open1 == 1)        //如果鬧鐘打開
  450.         {
  451.                 if((fen == fen1) && (shi == shi1) && (miao == 0))
  452.                 {               
  453.                         flag_clock_en = 1;        //有報警 打開蜂鳴器響的標志位                                
  454.                 }               
  455.                 if(flag_clock_en == 1)        //鬧鐘以被打開
  456.                 {        
  457.                         beep = ~beep;           //蜂鳴器叫3秒
  458.                 }
  459.         }        
  460. }


  461. ……………………

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

所有資料51hei提供下載:
參考資料.rar (180.82 KB, 下載次數: 247)


評分

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

查看全部評分

回復

使用道具 舉報

ID:339506 發表于 2018-5-28 16:23 | 顯示全部樓層
值得參考
回復

使用道具 舉報

ID:339506 發表于 2018-5-28 16:25 | 顯示全部樓層
哈哈,值得學習一下。。
回復

使用道具 舉報

ID:380985 發表于 2018-10-17 08:27 來自觸屏版 | 顯示全部樓層
別下載了,沒有代碼
回復

使用道具 舉報

ID:106063 發表于 2018-10-25 20:24 | 顯示全部樓層
謝謝分享
回復

使用道具 舉報

ID:408839 發表于 2018-11-17 18:08 | 顯示全部樓層
PSB=1是并口,整個程序也都不完整。
回復

使用道具 舉報

ID:400807 發表于 2018-11-18 22:08 | 顯示全部樓層
值得好好學習一下
回復

使用道具 舉報

ID:428919 發表于 2018-11-18 22:27 | 顯示全部樓層
很經典的demo。
回復

使用道具 舉報

ID:428947 發表于 2018-11-19 00:07 來自觸屏版 | 顯示全部樓層
大神,灰常感謝
回復

使用道具 舉報

ID:442877 發表于 2018-12-9 21:11 | 顯示全部樓層
謝謝分享
回復

使用道具 舉報

ID:412461 發表于 2018-12-17 09:11 | 顯示全部樓層
沒有仿真,沒有電路圖,只有程序
回復

使用道具 舉報

ID:312128 發表于 2019-4-2 22:04 | 顯示全部樓層
謝謝分享
回復

使用道具 舉報

ID:323774 發表于 2019-7-9 15:15 | 顯示全部樓層
都不全
下次給你們個全的
回復

使用道具 舉報

ID:590697 發表于 2019-7-26 10:55 | 顯示全部樓層
這個太強了,新手過來學習
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美一区二区在线观看 | 亚洲精品一区二区三区在线 | 伊人激情综合网 | 国产欧美日韩在线播放 | 亚洲永久在线 | 亚洲a人 | 欧美精品一区二区免费视频 | 日韩高清一区 | 中文字幕久久久 | 99热热热 | 在线看片网站 | 亚洲视频在线观看免费 | 亚洲综合色 | 国产剧情一区 | 久久久精品一区 | 国产成人精品一区二 | 亚洲成人久久久 | 中文字幕国产一区 | 国产视频久久久 | 成人毛片视频免费 | 日韩av成人 | 成人网av | 天天精品在线 | 久久国产高清 | 91精品在线播放 | 国产精品毛片在线 | 9999在线视频 | 成人 在线 | 91欧美激情一区二区三区成人 | 欧美精品一区二区免费视频 | 日韩在线视频观看 | 久久精品国产一区二区三区不卡 | 国产欧美一区二区三区在线看 | 国产高清精品一区二区三区 | 在线亚州| 亚洲福利视频网 | 国产高清久久久 | 亚洲热在线视频 | 中文字幕在线观看日韩 | 亚洲高清av | 黄色综合|