找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 5967|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

基于51單片機(jī)液晶萬(wàn)年歷設(shè)計(jì)(源碼+AD原理圖)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:72940 發(fā)表于 2019-1-21 19:50 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
       電子萬(wàn)年歷是一種非常廣泛日常計(jì)時(shí)工具,給人們的帶來(lái)了很大的方便,在社會(huì)上越來(lái)越流行。 它可以對(duì)年、月、日、時(shí)、分、秒進(jìn)行計(jì)時(shí),采用直觀的數(shù)字顯示,可以同時(shí)顯示年月日時(shí)分秒和溫度等信息,還有時(shí)間校準(zhǔn)、鬧鐘等功能。該電子萬(wàn)年歷主要采用STC89C52單片機(jī)作為主控核心,用DS1302時(shí)鐘芯片作為時(shí)鐘、液晶12864顯示屏顯示。STC89C52單片機(jī)是由宏晶公司推出的,功耗小,電壓可選用4~6V電壓供電;DS1302時(shí)鐘芯片是美國(guó)DALLAS公司推出的具有細(xì)電流充電功能的低功耗實(shí)時(shí)時(shí)鐘芯片,它可以對(duì)年、月、日、星期、時(shí)、分、秒進(jìn)行計(jì)時(shí),還具有閏年補(bǔ)償?shù)榷喾N功能,而且DS1302的使用壽命長(zhǎng),誤差;數(shù)字顯示是采用的12864液晶顯示屏來(lái)顯示,可以同時(shí)顯示年、月、日、星期、時(shí)、分、秒和溫度等信息。此外,該電子萬(wàn)年歷還具有時(shí)間校準(zhǔn)等功能
1.        系統(tǒng)總體功能
    本設(shè)計(jì)采用的是宏晶公司的STC89C52單片機(jī)為核心,通過(guò)單片機(jī)與時(shí)鐘芯片DS1302通信來(lái)對(duì)時(shí)間的讀寫(xiě),保證時(shí)鐘時(shí)間的穩(wěn)定性,并帶有內(nèi)部電源模塊,使系統(tǒng)斷電時(shí)時(shí)鐘數(shù)據(jù)不會(huì)丟失,以DS18B20溫度感應(yīng)芯片作為溫度電路的核心,向單片機(jī)發(fā)出獲取到的溫度數(shù)據(jù),并通過(guò)LCD1602將時(shí)間、顯示出來(lái),并可以通過(guò)按鍵調(diào)整時(shí)間日期和鬧鐘時(shí)間
2.        總體電路圖
   
3.        程序設(shè)計(jì)
(1)        LCD1602驅(qū)動(dòng)程序
  1. sbit rs                = P2^0;
  2. sbit rw                = P2^1;
  3. sbit e          = P2^2;
  4. #define lcddata P0
  5. sbit busy=P0^7;   //lcd busy bit
  6. void wr_d_lcd(uchar content);
  7. void wr_i_lcd(uchar content);
  8. void clrram_lcd (void);
  9. void init_lcd(void);
  10. void busy_lcd(void);
  11. void rev_row_lcd(uchar row);
  12. void rev_co_lcd(uchar row,uchar col,uchar mode);
  13. void clr_lcd(void);
  14. void wr_co_lcd(uchar row,uchar col,uchar lcddata1,uchar lcddtta2);
  15. void wr_row_lcd(uchar row,char *p);
  16. //**********************************
  17. //液晶初始化
  18. //**********************************
  19. void init_lcd(void)
  20. {
  21.         wr_i_lcd(0x06);  /*光標(biāo)的移動(dòng)方向*/
  22.         wr_i_lcd(0x0c);  /*開(kāi)顯示,關(guān)游標(biāo)*/
  23. }
  24. //***********************************
  25. //填充液晶DDRAM全為空格
  26. //**********************************
  27. void clrram_lcd (void)
  28. {
  29.         wr_i_lcd(0x30);
  30.         wr_i_lcd(0x01);
  31. }
  32. //***********************************
  33. //對(duì)液晶寫(xiě)數(shù)據(jù)
  34. //content為要寫(xiě)入的數(shù)據(jù)
  35. //***********************************
  36. void wr_d_lcd(uchar content)
  37. {
  38.         busy_lcd();
  39.         rs=1;
  40.     rw=0;
  41.         lcddata=content;
  42.         e=1;
  43.         ;
  44.         e=0;
  45. }
  46. //********************************
  47. //對(duì)液晶寫(xiě)指令
  48. //content為要寫(xiě)入的指令代碼
  49. //*****************************
  50. void wr_i_lcd(uchar content)
  51. {
  52.         busy_lcd();
  53.         rs=0;
  54.     rw=0;
  55.         lcddata=content;
  56.         e=1;
  57.         ;
  58.         e=0;
  59. }
  60. //********************************
  61. //液晶檢測(cè)忙狀態(tài)
  62. //在寫(xiě)入之前必須執(zhí)行
  63. //********************************
  64. void busy_lcd(void)
  65. {
  66.   lcddata=0xff;
  67.   rs=0;
  68.   rw=1;
  69.   e =1;
  70.   while(busy==1);
  71.   e =0;
  72. }
  73. //********************************
  74. //指定要顯示字符的坐標(biāo)
  75. //*******************************
  76. void gotoxy(unsigned char y, unsigned char x)
  77. {
  78.         if(y==1)
  79.                 wr_i_lcd(0x80|x);
  80.         if(y==2)
  81.         wr_i_lcd(0x90|x);
  82.         if(y==3)
  83.                 wr_i_lcd((0x80|x)+8);
  84.         if(y==4)
  85.         wr_i_lcd((0x90|x)+8);
  86. }
  87. //**********************************
  88. //液晶顯示字符串程序
  89. //**********************************
  90. void print(uchar *str)
  91. {
  92.         while(*str!='\0')
  93.         {
  94.                 wr_d_lcd(*str);
  95.                 str++;
  96.         }
  97. }

  98. //***************************************
  99. //液晶顯示主程序模塊
  100. //***************************************
  101. void show_time()   
  102. {
  103.   DS1302_GetTime(&CurrentTime);  //獲取時(shí)鐘芯片的時(shí)間數(shù)據(jù)
  104.   TimeToStr(&CurrentTime);       //時(shí)間數(shù)據(jù)轉(zhuǎn)換液晶字符
  105.   DateToStr(&CurrentTime);       //日期數(shù)據(jù)轉(zhuǎn)換液晶字符
  106.   ReadTemp();                    //開(kāi)啟溫度采集程序
  107.   temp_to_str();                 //溫度數(shù)據(jù)轉(zhuǎn)換成液晶字符
  108.   gotoxy(4,0);
  109.   print("溫度");
  110.   gotoxy(4,2);                  //液晶字符顯示位置
  111.   print(TempBuffer);             //顯示溫度
  112.   gotoxy(4,6);
  113.   print("℃");
  114.   gotoxy(3,0);
  115.   print("時(shí)間:");
  116.   gotoxy(3,3);
  117.   print(CurrentTime.TimeString); //顯示時(shí)間
  118.   gotoxy(2,3);
  119.   print(CurrentTime.DateString); //顯示日期
  120.   gotoxy(2,0);
  121.   print("星期");
  122.   gotoxy(2,2);
  123.   print(week_value);             //顯示星期
  124.   gotoxy(1,1);
  125.   print("【萬(wàn)年歷】");
  126.   mdelay(500);                 //掃描延時(shí)
  127. }
復(fù)制代碼
(2)        DS1302驅(qū)動(dòng)程序

  1. //***********************************
  2. //DS1302時(shí)鐘部分子程序模塊
  3. //***********************************
  4. typedef struct __SYSTEMTIME__
  5. {
  6.         uchar Second;
  7.         uchar Minute;
  8.         uchar Hour;
  9.         uchar Week;
  10.         uchar Day;
  11.         uchar Month;
  12.         uchar  Year;
  13.         uchar DateString[11];
  14.         uchar TimeString[9];
  15. }SYSTEMTIME;        //定義的時(shí)間類型
  16. SYSTEMTIME CurrentTime;


  17. #define AM(X)        X
  18. #define PM(X)        (X+12)                      // 轉(zhuǎn)成24小時(shí)制
  19. #define DS1302_SECOND        0x80          //時(shí)鐘芯片的寄存器位置,存放時(shí)間
  20. #define DS1302_MINUTE        0x82
  21. #define DS1302_HOUR                0x84
  22. #define DS1302_WEEK                0x8A
  23. #define DS1302_DAY                0x86
  24. #define DS1302_MONTH        0x88
  25. #define DS1302_YEAR                0x8C
  26. //**********************************
  27. //實(shí)時(shí)時(shí)鐘寫(xiě)入一字節(jié)(內(nèi)部函數(shù))
  28. //**********************************
  29. void DS1302InputByte(uchar d)         
  30. {
  31.     uchar i;
  32.     ACC = d;
  33.     for(i=8; i>0; i--)
  34.     {
  35.         DS1302_IO = ACC0;                   //相當(dāng)于匯編中的 RRC
  36.         DS1302_CLK = 1;
  37.         DS1302_CLK = 0;
  38.         ACC = ACC >> 1;
  39.     }
  40. }
  41. //*************************************
  42. //實(shí)時(shí)時(shí)鐘讀取一字節(jié)(內(nèi)部函數(shù))
  43. //*************************************
  44. uchar DS1302OutputByte(void)         
  45. {
  46.     uchar i;
  47.     for(i=8; i>0; i--)
  48.     {
  49.         ACC = ACC >>1;                                 //相當(dāng)于匯編中的 RRC
  50.         ACC7 = DS1302_IO;
  51.         DS1302_CLK = 1;
  52.         DS1302_CLK = 0;
  53.     }
  54.     return(ACC);
  55. }
  56. //**************************************
  57. //ucAddr: DS1302地址, ucData: 要寫(xiě)的數(shù)據(jù)
  58. //**************************************
  59. void Write1302(uchar ucAddr, uchar ucDa)        
  60. {
  61.     DS1302_RST = 0;
  62.     DS1302_CLK = 0;
  63.     DS1302_RST = 1;
  64.     DS1302InputByte(ucAddr);               // 地址,命令
  65.     DS1302InputByte(ucDa);               // 寫(xiě)1Byte數(shù)據(jù)
  66.     DS1302_CLK = 1;
  67.     DS1302_RST = 0;
  68. }
  69. //**************************************
  70. //讀取DS1302某地址的數(shù)據(jù)
  71. //**************************************
  72. uchar Read1302(uchar ucAddr)        
  73. {
  74.     uchar ucData;
  75.     DS1302_RST = 0;
  76.     DS1302_CLK = 0;
  77.     DS1302_RST = 1;
  78.     DS1302InputByte(ucAddr|0x01);        // 地址,命令
  79.     ucData = DS1302OutputByte();         // 讀1Byte數(shù)據(jù)
  80.     DS1302_CLK = 1;
  81.     DS1302_RST = 0;
  82.     return(ucData);
  83. }

  84. //******************************************
  85. //獲取時(shí)鐘芯片的時(shí)鐘數(shù)據(jù)到自定義的結(jié)構(gòu)型數(shù)組
  86. //******************************************
  87. void DS1302_GetTime(SYSTEMTIME *Time)  
  88. {
  89.         uchar ReadValue;
  90.         ReadValue = Read1302(DS1302_SECOND);
  91.         Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//轉(zhuǎn)換為相應(yīng)的10進(jìn)制數(shù)
  92.         ReadValue = Read1302(DS1302_MINUTE);
  93.         Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  94.         ReadValue = Read1302(DS1302_HOUR);
  95.         Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  96.         ReadValue = Read1302(DS1302_DAY);
  97.         Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);        
  98.         ReadValue = Read1302(DS1302_WEEK);
  99.         Time->Week = ((ReadValue&0x10)>>4)*10 + (ReadValue&0x0F);
  100.         ReadValue = Read1302(DS1302_MONTH);
  101.         Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  102.         ReadValue = Read1302(DS1302_YEAR);
  103.         Time->Year = ((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F);        
  104. }
  105. //******************************************
  106. //將時(shí)間年,月,日,星期數(shù)據(jù)轉(zhuǎn)換成液
  107. //晶顯示字符串,放到數(shù)組里DateString[]
  108. //******************************************
  109. void DateToStr(SYSTEMTIME *Time)   
  110. {   
  111.    uchar tab[ ]={0XD2,0XBB,0XB6,0XFE,0XC8,0XFD,0XCB,0XC4,0XCE,0XE5,0XC1,0XF9,0XC8,0XD5};
  112.    if(hide_year<2)          //這里的if,else語(yǔ)句都是判斷位閃爍,<2顯示數(shù)據(jù),>2就不顯示,輸出字符串為 2007/07/22
  113.     {                              
  114.           Time->DateString[0] = '2';
  115.           Time->DateString[1] = '0';         
  116.           Time->DateString[2] = Time->Year/10 + '0';
  117.           Time->DateString[3] = Time->Year%10 + '0';
  118.         }
  119.           else
  120.             {
  121.               Time->DateString[0] = ' ';
  122.               Time->DateString[1] = ' ';                 
  123.               Time->DateString[2] = ' ';
  124.               Time->DateString[3] = ' ';
  125.                 }
  126.     Time->DateString[4]='-';
  127.         if(hide_month<2)
  128.         {
  129.           Time->DateString[5] = Time->Month/10 + '0';
  130.           Time->DateString[6] = Time->Month%10 + '0';
  131.         }
  132.           else
  133.           {
  134.             Time->DateString[5] = ' ';
  135.             Time->DateString[6] = ' ';
  136.           }
  137.     Time->DateString[7]='-';
  138.         if(hide_day<2)
  139.         {
  140.           Time->DateString[8] = Time->Day/10 + '0';
  141.           Time->DateString[9] = Time->Day%10 + '0';
  142.         }
  143.           else
  144.           {
  145.             Time->DateString[8] = ' ';
  146.             Time->DateString[9] = ' ';            
  147.           }
  148.         if(hide_week<2)
  149.         {
  150.           week_value[0] =tab[2*(Time->Week%10)-2];  //星期的數(shù)據(jù)另外放到 week_value[]數(shù)組里,跟年,月,日的分開(kāi)存放,因?yàn)榈纫幌乱谧詈箫@示
  151.           week_value[1] =tab[2*(Time->Week%10)-1];
  152.         }
  153.           else
  154.           {
  155.             week_value[0] = ' ';
  156.                 week_value[1]=' ';
  157.           }
  158.           week_value[2] = '\0';

  159.         Time->DateString[10] = '\0'; //字符串末尾加 '\0' ,判斷結(jié)束字符
  160. }
  161. //******************************************
  162. //將時(shí),分,秒數(shù)據(jù)轉(zhuǎn)換成液晶
  163. //顯示字符放到數(shù)組 TimeString[]
  164. //*****************************************
  165. void TimeToStr(SYSTEMTIME *Time)
  166. {   if(hide_hour<2)
  167.     {
  168.           Time->TimeString[0] = Time->Hour/10 + '0';
  169.           Time->TimeString[1] = Time->Hour%10 + '0';
  170.         }
  171.           else
  172.             {
  173.               Time->TimeString[0] = ' ';
  174.               Time->TimeString[1] = ' ';
  175.                 }
  176.         Time->TimeString[2] = ':';
  177.     if(hide_min<2)
  178.         {
  179.           Time->TimeString[3] = Time->Minute/10 + '0';
  180.           Time->TimeString[4] = Time->Minute%10 + '0';
  181.         }
  182.           else
  183.             {
  184.               Time->TimeString[3] = ' ';
  185.               Time->TimeString[4] = ' ';
  186.                }
  187.         Time->TimeString[5] = ':';
  188.     if(hide_sec<2)
  189.     {
  190.           Time->TimeString[6] = Time->Second/10 + '0';
  191.           Time->TimeString[7] = Time->Second%10 + '0';
  192.     }
  193.       else
  194.        {
  195.          Time->TimeString[6] = ' ';
  196.              Time->TimeString[7] = ' ';
  197.        }
  198.         Time->TimeString[8] = '\0';
  199. }

  200. //******************************
  201. //時(shí)鐘芯片初始化
  202. //******************************
  203. void Initial_DS1302(void)   
  204. {   
  205.         uchar Second=Read1302(DS1302_SECOND);
  206.         if(Second&0x80)              //判斷時(shí)鐘芯片是否關(guān)閉         
  207.     {
  208.         Write1302(0x8e,0x00); //寫(xiě)入允許
  209.         Write1302(0x8c,0x07); //以下寫(xiě)入初始化時(shí)間 日期:07/07/25.星期: 3. 時(shí)間: 23:59:55
  210.         Write1302(0x88,0x07);
  211.         Write1302(0x86,0x25);
  212.         Write1302(0x8a,0x07);
  213.         Write1302(0x84,0x23);
  214.         Write1302(0x82,0x59);
  215.         Write1302(0x80,0x55);
  216.         Write1302(0x8e,0x80); //禁止寫(xiě)入
  217.         }

  218. }
復(fù)制代碼
(3)DS18B20驅(qū)動(dòng)程序

  1. /***********ds18b20子程序*************************/

  2. /***********ds18b20延遲子函數(shù)(晶振12MHz )*******/

  3. void delay_18B20(unsigned int i)
  4. {
  5.         while(i--);
  6. }

  7. /**********ds18b20初始化函數(shù)**********************/

  8. void Init_DS18B20(void)
  9. {
  10.          unsigned char x=0;
  11.          DQ = 1;          //DQ復(fù)位
  12.          delay_18B20(8);  //稍做延時(shí)
  13.          DQ = 0;          //單片機(jī)將DQ拉低
  14.          delay_18B20(40); //精確延時(shí) 大于 480us
  15.          DQ = 1;          //拉高總線
  16.          delay_18B20(7);
  17.          x=DQ;            //稍做延時(shí)后 如果x=0則初始化成功 x=1則初始化失敗
  18.          delay_18B20(10);
  19. }

  20. /***********ds18b20讀一個(gè)字節(jié)**************/  

  21. uchar ReadOneChar(void)
  22. {
  23.         uchar i=0;
  24.         uchar dat = 0;
  25.         for (i=8;i>0;i--)
  26.          {
  27.                   DQ = 0; // 給脈沖信號(hào)
  28.                   dat>>=1;
  29.                   DQ = 1; // 給脈沖信號(hào)
  30.                   if(DQ)
  31.                   dat|=0x80;
  32.                   delay_18B20(4);
  33.          }
  34.          return(dat);
  35. }

  36. /*************ds18b20寫(xiě)一個(gè)字節(jié)****************/  

  37. void WriteOneChar(uchar dat)
  38. {
  39.          uchar i=0;
  40.          for (i=8; i>0; i--)
  41.          {
  42.                   DQ = 0;
  43.                  DQ = dat&0x01;
  44.             delay_18B20(5);
  45.                  DQ = 1;
  46.             dat>>=1;
  47. }
  48. }

  49. /**************讀取ds18b20當(dāng)前溫度************/

  50. void ReadTemp(void)
  51. {
  52.         uchar a=0;
  53.         uchar b=0;
  54.         uchar t;

  55.         Init_DS18B20();
  56.         WriteOneChar(0xCC);            // 跳過(guò)讀序號(hào)列號(hào)的操作
  57.         WriteOneChar(0x44);         // 啟動(dòng)溫度轉(zhuǎn)換

  58.         delay_18B20(100);       // this message is wery important

  59.         Init_DS18B20();
  60.         WriteOneChar(0xCC);         //跳過(guò)讀序號(hào)列號(hào)的操作
  61.         WriteOneChar(0xBE);         //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度

  62.         delay_18B20(50);

  63.         a=ReadOneChar();            //讀取溫度值低位
  64.         b=ReadOneChar();                   //讀取溫度值高位
  65.         t=b&0xf8;
  66.         if(t)
  67.         {
  68.           TempBuffer[0]=':';
  69.           TempBuffer[1]='-';
  70.             temp_value=b<<4;
  71.           temp_value+=(a&0xf0)>>4;  
  72.           temp_value=~temp_value+1;
  73.           temp1_value=~a&0x0f;
  74.         }
  75.         else
  76.         {  
  77.         temp_value=b<<4;
  78.         temp_value+=(a&0xf0)>>4;
  79.                  temp1_value=a&0x0f;
  80.             TempBuffer[0]=':';
  81.             TempBuffer[1]=temp_value/100+'0';  //百位
  82.        if(TempBuffer[1]=='1')
  83.        {
  84.             TempBuffer[1]='1';
  85.        }
  86.        else
  87.        {
  88.            TempBuffer[1]=' ';
  89.        }
  90.     }
  91. }
  92. void temp_to_str()   //溫度數(shù)據(jù)轉(zhuǎn)換成液晶字符顯示
  93. {               

  94.   TempBuffer[2]=temp_value%100/10+'0';  //十位
  95.   TempBuffer[3]=temp_value%10+'0';  //個(gè)位
  96.   TempBuffer[4]='.';
  97.   TempBuffer[5]=temp1_value*625/1000%10+'0';
  98.   TempBuffer[6]=temp1_value*625/100%10+'0';
  99.   TempBuffer[7]=temp1_value*625/10%10+'0';
  100.   //TempBuffer[8]=temp1_value*625%10+'0';
  101.   TempBuffer[8]='\0';
  102. }
  103. //**********************************************
  104. //延時(shí)子程序模塊
  105. //**********************************************
  106. void mdelay(uint delay)
  107. {        uint i;
  108.          for(;delay>0;delay--)
  109.                    {for(i=0;i<80;i++) //1ms延時(shí).
  110.                        {;}
  111.                    }
  112. }
復(fù)制代碼
(4)        按鍵驅(qū)動(dòng)程序

  1. //************************************
  2. //跳出調(diào)整模式,返回默認(rèn)顯示
  3. //************************************
  4. void outkey()                    
  5. { uchar Second;
  6.   if(out==0)         
  7.   { mdelay(5);
  8.         count=0;
  9.         hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;
  10.         Second=Read1302(DS1302_SECOND);
  11.     Write1302(0x8e,0x00); //寫(xiě)入允許
  12.         Write1302(0x80,Second&0x7f);
  13.         Write1302(0x8E,0x80);          //禁止寫(xiě)入
  14.         done=0;           
  15.   }
  16. }
  17. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  18. //*************************
  19. //升序按鍵
  20. //*************************
  21. void Upkey()
  22. {           
  23.                 Up=1;
  24.                     if(Up==0)
  25.                           {
  26.                                    mdelay(5);
  27.                                        switch(count)
  28.                                           {case 1:
  29.                                   temp=Read1302(DS1302_SECOND);  //讀取秒數(shù)
  30.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  31.                                                                   temp=temp+1;  //秒數(shù)加1
  32.                                   up_flag=1;    //數(shù)據(jù)調(diào)整后更新標(biāo)志
  33.                                                                   if((temp)>59)   //超過(guò)59秒,清零
  34.                                   temp=0;        
  35.                                                                     temp=temp/10*16+temp%10;
  36.                                                                   break;
  37.                                            case 2:
  38.                                   temp=Read1302(DS1302_MINUTE);  //讀取分?jǐn)?shù)
  39.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  40.                                                                   temp=temp+1;  //分?jǐn)?shù)加1
  41.                                   up_flag=1;
  42.                                                                   if(temp>59)          //超過(guò)59分,清零
  43.                                                                   temp=0;
  44.                                                                   temp=temp/10*16+temp%10;
  45.                                                                   break;
  46.                                            case 3:
  47.                                   temp=Read1302(DS1302_HOUR);  //讀取小時(shí)數(shù)
  48.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  49.                                                                   temp=temp+1;  //小時(shí)數(shù)加1
  50.                                   up_flag=1;
  51.                                                                   if(temp>23)   //超過(guò)23小時(shí),清零
  52.                                                                   temp=0;
  53.                                                                   temp=temp/10*16+temp%10;
  54.                                                                   break;
  55.                                            case 4:
  56.                                   temp=Read1302(DS1302_WEEK);  //讀取星期數(shù)
  57.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  58.                                                                   temp=temp+1;  //星期數(shù)加1
  59.                                   up_flag=1;
  60.                                                                   if(temp>7)  
  61.                                                                   temp=1;
  62.                                                                   temp=temp/10*16+temp%10;
  63.                                                                   break;
  64.                                            case 5:
  65.                                   temp=Read1302(DS1302_DAY);  //讀取日數(shù)
  66.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  67.                                                                   temp=temp+1;  //日數(shù)加1
  68.                                   up_flag=1;
  69.                                                                   if(temp>31)
  70.                                                                   temp=1;
  71.                                                                   temp=temp/10*16+temp%10;
  72.                                                                   break;
  73.                                            case 6:
  74.                                   temp=Read1302(DS1302_MONTH);  //讀取月數(shù)
  75.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  76.                                                                   temp=temp+1;  //月數(shù)加1
  77.                                   up_flag=1;
  78.                                                                   if(temp>12)
  79.                                                                   temp=1;
  80.                                                                   temp=temp/10*16+temp%10;
  81.                                                                   break;
  82.                                            case 7:
  83.                                   temp=Read1302(DS1302_YEAR);  //讀取年數(shù)
  84.                                                                   temp=((temp&0xf0)>>4)*10 + (temp&0x0F);
  85.                                                                   temp=temp+1;  //年數(shù)加1
  86.                                   up_flag=1;
  87.                                                                   if(temp>99)
  88.                                                                   temp=0;
  89.                                                                   temp=temp/10*16+temp%10;
  90.                                                                   break;
  91.                                                default:break;
  92.                                           }
  93.                                           
  94.                                  //  while(Up==0);
  95.                                   }
  96. }

  97. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  98. //************************
  99. //降序按鍵
  100. //************************
  101. void Downkey()
  102. {            
  103.                 Down=1;
  104.             if(Down==0)
  105.                           {
  106.                                    mdelay(5);
  107.                                      switch(count)
  108.                                           {case 1:
  109.                                   temp=Read1302(DS1302_SECOND);  //讀取秒數(shù)
  110.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  111.                                                                   temp=temp-1;                                                    //秒數(shù)減1
  112.                                   down_flag=1;       //數(shù)據(jù)調(diào)整后更新標(biāo)志
  113.                                                                   if(temp==-1)     //小于0秒,返回59秒
  114.                                                                   temp=59;
  115.                                                                   temp=temp/10*16+temp%10;
  116.                                                                   break;
  117.                                            case 2:
  118.                                   temp=Read1302(DS1302_MINUTE);  //讀取分?jǐn)?shù)
  119.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  120.                                                                   temp=temp-1;  //分?jǐn)?shù)減1
  121.                                   down_flag=1;
  122.                                                                   if(temp==-1)
  123.                                                                   temp=59;      //小于0秒,返回59秒
  124.                                                                   temp=temp/10*16+temp%10;
  125.                                                                   break;
  126.                                            case 3:
  127.                                   temp=Read1302(DS1302_HOUR);  //讀取小時(shí)數(shù)
  128.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  129.                                                                   temp=temp-1;  //小時(shí)數(shù)減1
  130.                                   down_flag=1;
  131.                                                                   if(temp==-1)
  132.                                                                   temp=23;
  133.                                                                   temp=temp/10*16+temp%10;
  134.                                                                   break;
  135.                                            case 4:
  136.                                   temp=Read1302(DS1302_WEEK);  //讀取星期數(shù);
  137.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  138.                                                                   temp=temp-1;  //星期數(shù)減1
  139.                                   down_flag=1;
  140.                                                                   if(temp==0)
  141.                                                                   temp=7;
  142.                                                                   temp=temp/10*16+temp%10;
  143.                                                                   break;
  144.                                            case 5:
  145.                                   temp=Read1302(DS1302_DAY);  //讀取日數(shù)
  146.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  147.                                                                   temp=temp-1;  //日數(shù)減1
  148.                                   down_flag=1;
  149.                                                                   if(temp==0)
  150.                                                                   temp=31;
  151.                                                                   temp=temp/10*16+temp%10;
  152.                                                                   break;
  153.                                            case 6:
  154.                                   temp=Read1302(DS1302_MONTH);  //讀取月數(shù)
  155.                                                                   temp=((temp&0x70)>>4)*10 + (temp&0x0F);
  156.                                                                   temp=temp-1;  //月數(shù)減1
  157.                                   down_flag=1;
  158.                                                                   if(temp==0)
  159.                                                                   temp=12;
  160.                                                                   temp=temp/10*16+temp%10;
  161.                                                                   break;
  162.                                            case 7:
  163.                                   temp=Read1302(DS1302_YEAR);  //讀取年數(shù)
  164.                                                                   temp=((temp&0xf0)>>4)*10 + (temp&0x0F);
  165.                                                                   temp=temp-1;  //年數(shù)減1
  166.                                   down_flag=1;
  167.                                                                   if(temp==-1)
  168.                                                                   temp=99;
  169.                                                                   temp=temp/10*16+temp%10;
  170.                                                                   break;
  171.                                               default:break;
  172.                                          }
  173.                                          
  174.                                  //  while(Down==0);
  175.                                   }
  176. }

  177. //**************************
  178. //模式選擇按鍵
  179. //**************************
  180. void Setkey()
  181. {
  182.                 Set=1;
  183.                 if(Set==0)
  184.             {
  185.            mdelay(5);
  186.            count=count+1;         //Setkey按一次,count就加1
  187.                    done=1;                         //進(jìn)入調(diào)整模式
  188.            while(Set==0);
  189.                  }

  190. }

  191. //*************************
  192. //按鍵功能執(zhí)行
  193. //*************************
  194. void keydone()
  195. {        
  196.                 uchar Second;
  197.                 /* if(flag==0)    //關(guān)閉時(shí)鐘,停止計(jì)時(shí)
  198.          { Write1302(0x8e,0x00); //寫(xiě)入允許
  199.            temp=Read1302(0x80);
  200.            Write1302(0x80,temp|0x80);
  201.                Write1302(0x8e,0x80); //禁止寫(xiě)入
  202.            flag=1;
  203.          }*/
  204.          Setkey();                                            //掃描模式切換按鍵
  205.                  switch(count)
  206.                  {
  207.                          case 1:do                                                //count=1,調(diào)整秒
  208.                        {
  209.                    outkey();                           //掃描跳出按鈕
  210.                                    Upkey();                //掃描加按鈕
  211.                                    Downkey();              //掃描減按鈕
  212.                                    if(up_flag==1||down_flag==1)  //數(shù)據(jù)更新,重新寫(xiě)入新的數(shù)據(jù)
  213.                                    {
  214.                                      Write1302(0x8e,0x00); //寫(xiě)入允許
  215.                                      Write1302(0x80,temp); //寫(xiě)入新的秒數(shù)
  216.                                      Write1302(0x8e,0x80); //禁止寫(xiě)入
  217.                                      up_flag=0;
  218.                                      down_flag=0;
  219.                                   }
  220.                      if(Down!=0&&Up!=0)
  221.                      {
  222.                                                 hide_sec++;
  223.                                         if(hide_sec>3)
  224.                                         hide_sec=0;
  225.                      }
  226.                                          else hide_sec=0;
  227.                                          show_time();         //液晶顯示數(shù)據(jù)
  228.                                   }while(count==2);break;  
  229.                   case 2:do                                                //count=2,調(diào)整分
  230.                           {
  231.                                    hide_sec=0;
  232.                                    outkey();
  233.                                    Upkey();
  234.                                    Downkey();
  235.                                    if(temp>0x60)
  236.                                      temp=0;
  237.                                    if(up_flag==1||down_flag==1)
  238.                                    {
  239.                                      Write1302(0x8e,0x00); //寫(xiě)入允許
  240.                                      Write1302(0x82,temp); //寫(xiě)入新的分?jǐn)?shù)
  241.                                      Write1302(0x8e,0x80); //禁止寫(xiě)入
  242.                                      up_flag=0;
  243.                                      down_flag=0;
  244.                                   }
  245.                      if(Down!=0&&Up!=0)
  246.                      {
  247.                                                 hide_min++;
  248.                                         if(hide_min>3)
  249.                                         hide_min=0;
  250.                      }
  251.                                          else hide_min=0;
  252.                                          show_time();
  253.                                   }while(count==3);break;
  254.                   case 3:do                                                //count=3,調(diào)整小時(shí)
  255.                           {
  256.                    hide_min=0;
  257.                                    outkey();
  258.                                    Upkey();
  259.                                    Downkey();
  260.                                    if(up_flag==1||down_flag==1)
  261.                                    {
  262.                                       Write1302(0x8e,0x00); //寫(xiě)入允許
  263.                                       Write1302(0x84,temp); //寫(xiě)入新的小時(shí)數(shù)
  264.                                       Write1302(0x8e,0x80); //禁止寫(xiě)入
  265.                                       up_flag=0;
  266.                                       down_flag=0;
  267.                                    }
  268.                       if(Down!=0&&Up!=0)
  269.                      {
  270.                                                 hide_hour++;
  271.                                         if(hide_hour>3)
  272.                                         hide_hour=0;
  273.                      }
  274.                                          else  hide_hour=0;
  275.                                           show_time();
  276.                                   }while(count==4);break;
  277.                   case 4:do                                                //count=4,調(diào)整星期
  278.                           {
  279.                    hide_hour=0;
  280.                                    outkey();
  281.                                    Upkey();
  282.                                    Downkey();
  283.                                    if(up_flag==1||down_flag==1)
  284.                                    {
  285.                                      Write1302(0x8e,0x00); //寫(xiě)入允許
  286.                                      Write1302(0x8a,temp); //寫(xiě)入新的星期數(shù)
  287.                                      Write1302(0x8e,0x80); //禁止寫(xiě)入
  288.                                      up_flag=0;
  289.                                      down_flag=0;
  290.                                    }
  291.                      if(Down!=0&&Up!=0)
  292.                      {
  293.                                            hide_week++;
  294.                                        if(hide_week>3)
  295.                                        hide_week=0;
  296.                      }
  297.                                          else hide_week=0;
  298.                                          show_time();
  299.                                   }while(count==5);break;
  300.                   case 5:do                                                //count=5,調(diào)整日
  301.                           {
  302.                                    hide_week=0;
  303.                                    outkey();
  304.                                    Upkey();
  305.                                    Downkey();
  306.                                    if(up_flag==1||down_flag==1)
  307.                                    {
  308.                                      Write1302(0x8e,0x00); //寫(xiě)入允許
  309.                                      Write1302(0x86,temp); //寫(xiě)入新的日數(shù)
  310.                                      Write1302(0x8e,0x80); //禁止寫(xiě)入
  311.                                      up_flag=0;
  312.                                      down_flag=0;
  313.                                    }
  314.                      if(Down!=0&&Up!=0)
  315.                                      {
  316.                                                 hide_day++;
  317.                                         if(hide_day>3)
  318.                                         hide_day=0;
  319.                                          }
  320.                                     else hide_day=0;
  321.                      show_time();
  322.                                   }while(count==6);break;
  323.                   case 6:do                                                //count=6,調(diào)整月
  324.                           {
  325.                    hide_day=0;
  326.                                    outkey();
  327.                                    Upkey();
  328.                                    Downkey();
  329.                                    if(up_flag==1||down_flag==1)
  330.                                    {
  331.                                       Write1302(0x8e,0x00); //寫(xiě)入允許
  332.                                       Write1302(0x88,temp); //寫(xiě)入新的月數(shù)
  333.                                       Write1302(0x8e,0x80); //禁止寫(xiě)入
  334.                                       up_flag=0;
  335.                                       down_flag=0;
  336.                                    }
  337.                      if(Down!=0&&Up!=0)
  338.                                      {
  339.                                                  hide_month++;
  340.                                          if(hide_month>3)
  341.                                          hide_month=0;
  342.                                          }
  343.                                         else hide_month=0;
  344.                      show_time();
  345.                                   }while(count==7);break;
  346.                   case 7:do                                                //count=7,調(diào)整年
  347.                           {
  348.                    hide_month=0;
  349.                                    outkey();
  350.                                    Upkey();
  351.                                    Downkey();
  352.                                    if(up_flag==1||down_flag==1)
  353.                                    {
  354.                                       Write1302(0x8e,0x00); //寫(xiě)入允許
  355.                                       Write1302(0x8c,temp); //寫(xiě)入新的年數(shù)
  356.                                       Write1302(0x8e,0x80); //禁止寫(xiě)入
  357.                                       up_flag=0;
  358.                                       down_flag=0;
  359.                                   }
  360.                       if(Down!=0&&Up!=0)
  361.                                       {
  362.                                                   hide_year++;
  363.                                          if(hide_year>3)
  364.                                          hide_year=0;
  365.                       }
  366.                                           else hide_year=0;
  367.                       show_time();
  368.                                   }while(count==8);break;
  369.                   case 8: count=0;hide_year=0;  //count8, 跳出調(diào)整模式,返回默認(rèn)顯示狀態(tài)
  370.                       Second=Read1302(DS1302_SECOND);
  371.                   Write1302(0x8e,0x00); //寫(xiě)入允許
  372.                       Write1302(0x80,Second&0x7f);
  373.                       Write1302(0x8E,0x80);          //禁止寫(xiě)入
  374.                                   done=0;
  375.                   break; //count=7,開(kāi)啟中斷,標(biāo)志位置0并退出
  376.                   default:break;

  377.                  }

  378. }
復(fù)制代碼
(5)        主程序

  1. main()
  2. {
  3.   //  flag=1;           //時(shí)鐘停止標(biāo)志
  4.         init_lcd();
  5.         clrram_lcd();
  6.         Init_DS18B20( ) ;      //DS18B20初始化
  7.         Initial_DS1302(); //時(shí)鐘芯片初始化
  8.         up_flag=0;
  9.         down_flag=0;
  10.         done=0;           //進(jìn)入默認(rèn)液晶顯示
  11.         while(1)
  12.         {   
  13.         while(done==1)
  14.           keydone();    //進(jìn)入調(diào)整模式
  15.                 while(done==0)
  16.              {  
  17.             show_time();                //液晶顯示數(shù)據(jù)
  18.            // flag=0;                  
  19.                       Setkey();                                 //掃描各功能鍵
  20.                  }               
  21.         }
  22. }
復(fù)制代碼

20181219221654961.jpg (100.69 KB, 下載次數(shù): 52)

20181219221654961.jpg

51單片機(jī)的萬(wàn)年歷.rar

275.49 KB, 下載次數(shù): 40, 下載積分: 黑幣 -5

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

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

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表