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

QQ登錄

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

帖子
查看: 4917|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

[原創(chuàng)設(shè)計(jì)][電子手表制作]第3期V1.2版(DS3231鬧鐘程序)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:884042 發(fā)表于 2021-7-14 12:09 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
本帖最后由 xjx51 于 2021-8-11 16:06 編輯

今天來(lái)做DS23231的鬧鐘功能
前幾天已經(jīng)做好了DS3231的鬧鐘啟動(dòng)函數(shù),現(xiàn)在也測(cè)試成功,
來(lái)曬一下開(kāi)啟和關(guān)閉的程序:
  1. #include <reg51.h>
  2. #include <intrins.h>

  3. /*DS3231使用功能定義*/
  4. typedef unsigned char uchar;   
  5. typedef unsigned int  uint ;   

  6. sbit SDA=P1^3;     //模擬I2C數(shù)據(jù)傳送位SDA      
  7. sbit SCL=P1^1;     //模擬I2C時(shí)鐘控制位SCL
  8. sbit SQW=P3^7;

  9. bit  ack;          //應(yīng)答標(biāo)志位

  10. #define DS3231_WriteAddress 0xD0    //器件寫(xiě)地址
  11. #define DS3231_ReadAddress  0xD1    //器件讀地址

  12. #define DS3231_SECOND       0x00    //秒
  13. #define DS3231_MINUTE       0x01    //分
  14. #define DS3231_HOUR         0x02    //時(shí)
  15. #define DS3231_WEEK         0x03    //星期
  16. #define DS3231_DAY          0x04    //日
  17. #define DS3231_MONTH        0x05    //月
  18. #define DS3231_YEAR         0x06    //年
  19. //鬧鈴1           
  20. #define DS3231_SALARM1ECOND 0x07    //秒
  21. #define DS3231_ALARM1MINUTE 0x08    //分
  22. #define DS3231_ALARM1HOUR   0x09    //時(shí)
  23. #define DS3231_ALARM1WEEK   0x0A    //星期/日
  24. //鬧鈴2
  25. #define DS3231_ALARM2MINUTE 0x0b    //分
  26. #define DS3231_ALARM2HOUR   0x0c    //時(shí)
  27. #define DS3231_ALARM2WEEK   0x0d    //星期/日
  28. #define DS3231_CONTROL      0x0e    //控制寄存器
  29. #define DS3231_STATUS       0x0f    //狀態(tài)寄存器
  30. #define BSY                 2       //忙
  31. #define OSF                 7       //振蕩器停止標(biāo)志
  32. #define DS3231_XTAL         0x10    //晶體老化寄存器
  33. #define DS3231_TEMPERATUREH 0x11    //溫度寄存器高字節(jié)(8位)
  34. #define DS3231_TEMPERATUREL 0x12    //溫度寄存器低字節(jié)(高2位)
  35. uchar  DS3231Time[9]={0x40,0x59,0x05,0x21,0x05,0x08,0x06,0x00,0x00}; //秒分時(shí)年月日周溫度高字節(jié)溫度低字節(jié)
  36. /*全局函數(shù)定義*/
  37. extern void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec,uchar wee);
  38. extern void  get_show_Temperature(void);
  39. extern void READ_Time();
  40. extern void DS3231_Init();                        
  41. extern uchar DS3231_Time[9];
  42. void delayus(uint us)
  43. {
  44.     while(us--);
  45. }
  46. uchar BCD2HEX(uchar val)    //BCD轉(zhuǎn)換為Byte
  47. {
  48.     uchar temp;
  49.     temp=val&0x0f;                          
  50.     val>>=4;
  51.     val&=0x0f;
  52.     val*=10;
  53.     temp+=val;
  54.   
  55.     return temp;
  56. }


  57. uchar HEX2BCD(uchar val)    //B碼轉(zhuǎn)換為BCD碼
  58. {
  59.     uchar i,j,k;
  60.     i=val/10;
  61.     j=val;
  62.     k=j+(i<<4);
  63.     return k;
  64. }
  65. void Start_I2C()
  66. {
  67.     SDA=1;                  //發(fā)送起始條件的數(shù)據(jù)信號(hào)
  68.     delayus(1);
  69.     SCL=1;
  70.     delayus(5);             //起始條件建立時(shí)間大于4.7us,延時(shí)
  71.   
  72.     SDA=0;                  //發(fā)送起始信號(hào)
  73.     delayus(5);             // 起始條件鎖定時(shí)間大于4μs
  74.       
  75.     SCL=0;                  //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
  76.     delayus(2);
  77. }


  78. void Stop_I2C()
  79. {
  80.     SDA=0;                  //發(fā)送結(jié)束條件的數(shù)據(jù)信號(hào)
  81.     delayus(1);             //發(fā)送結(jié)束條件的時(shí)鐘信號(hào)
  82.     SCL=1;                  //結(jié)束條件建立時(shí)間大于4us
  83.     delayus(5);
  84.   
  85.     SDA=1;                  //發(fā)送I2C總線結(jié)束信號(hào)
  86.     delayus(4);
  87. }


  88. void SendByte(uchar c)
  89. {
  90.     uchar BitCnt;
  91.   
  92.     for(BitCnt=0;BitCnt<8;BitCnt++)         //要傳送的數(shù)據(jù)長(zhǎng)度為8位
  93.     {
  94.         if((c<<BitCnt)&0x80)
  95.             SDA=1;                          //判斷發(fā)送位
  96.         else
  97.             SDA=0;              
  98.           delayus(1);
  99.           SCL=1;                            //置時(shí)鐘線為高,通知被控器開(kāi)始接收數(shù)據(jù)位
  100.           delayus(5);                       //保證時(shí)鐘高電平周期大于4μs  
  101.           SCL=0;
  102.     }
  103.   
  104.     delayus(2);
  105.     SDA=1;                                  //8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位
  106.     delayus(2);
  107.     SCL=1;
  108.     delayus(3);
  109.     if(SDA==1)
  110.         ack=0;   
  111.     else
  112.         ack=1;                              //判斷是否接收到應(yīng)答信號(hào)
  113.     SCL=0;
  114.     delayus(2);
  115. }


  116. uchar RcvByte()
  117. {
  118.    uchar retc;
  119.    uchar BitCnt;

  120.    retc=0;
  121.    SDA=1;                           //置數(shù)據(jù)線為輸入方式
  122.    for(BitCnt=0;BitCnt<8;BitCnt++)
  123.    {
  124.         delayus(1);
  125.         SCL=0;                      //置時(shí)鐘線為低,準(zhǔn)備接收數(shù)據(jù)位
  126.       
  127.         delayus(5);                 //時(shí)鐘低電平周期大于4.7μs
  128.      
  129.         SCL=1;                      //置時(shí)鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效
  130.         delayus(3);
  131.         retc=retc<<1;
  132.         if(SDA==1)
  133.             retc=retc+1;            //讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中
  134.         delayus(2);
  135.    }
  136.    SCL=0;
  137.    delayus(2);
  138.    return(retc);
  139. }




  140. void Ack_I2C(bit a)
  141. {

  142.     if(a==0)
  143.         SDA=0;              //在此發(fā)出應(yīng)答或非應(yīng)答信號(hào)
  144.     else
  145.         SDA=1;
  146.     delayus(3);   
  147.     SCL=1;
  148.   
  149.     delayus(5);             //時(shí)鐘低電平周期大于4μs
  150.   
  151.     SCL=0;                  //清時(shí)鐘線,鉗住I2C總線以便繼續(xù)接收
  152.     delayus(2);  
  153. }




  154. uchar write_byte(uchar addr, uchar write_data)
  155. {
  156.     Start_I2C();
  157.     SendByte(DS3231_WriteAddress);
  158.     if (ack == 0)
  159.         return 0;
  160.   
  161.     SendByte(addr);  
  162.     if (ack == 0)
  163.         return 0;
  164.   
  165.     SendByte(write_data);
  166.     if (ack == 0)
  167.         return 0;
  168.   
  169.     Stop_I2C();
  170.     delayus(10);     
  171.     return 1;
  172. }




  173. uchar read_current()
  174. {
  175.     uchar read_data;
  176.     Start_I2C();
  177.     SendByte(DS3231_ReadAddress);
  178.     if(ack==0)
  179.         return(0);
  180.   
  181.     read_data = RcvByte();
  182.     Ack_I2C(1);
  183.     Stop_I2C();
  184.     return read_data;
  185. }




  186. uchar read_random(uchar random_addr)
  187. {
  188.     Start_I2C();
  189.     SendByte(DS3231_WriteAddress);
  190.     if(ack==0)
  191.         return(0);
  192.   
  193.     SendByte(random_addr);
  194.     if(ack==0)
  195.         return(0);
  196.   
  197.     return(read_current());
  198. }




  199. void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec,uchar wee)
  200. {
  201.     uchar temp=0;
  202.   
  203.     //temp=HEX2BCD(yea);
  204.     write_byte(DS3231_YEAR,yea);   //修改年
  205.   
  206.     //temp=HEX2BCD(mon);
  207.     write_byte(DS3231_MONTH,mon);  //修改月
  208.   
  209.     //temp=HEX2BCD(da);
  210.     write_byte(DS3231_DAY,da);    //修改日
  211.          
  212.     //temp=HEX2BCD(hou);
  213.     write_byte(DS3231_HOUR,hou);   //修改時(shí)
  214.   
  215.     //temp=HEX2BCD(min);
  216.     write_byte(DS3231_MINUTE,min); //修改分
  217.          
  218.     //temp=HEX2BCD(sec);
  219.     write_byte(DS3231_SECOND,sec); //修改秒

  220.         write_byte(DS3231_WEEK,wee); //修改周
  221. }
  222. void  get_show_Temperature(void)
  223. {
  224.     uchar Ttemp1,Ttemp2;
  225.           write_byte(0x0e,0x20);
  226.     Ttemp1=read_random(DS3231_TEMPERATUREH);    //溫度 高字節(jié)
  227.           DS3231Time[7]=Ttemp1;
  228.     Ttemp2=read_random(DS3231_TEMPERATUREL);    //溫度低字節(jié)
  229.         Ttemp2=(Ttemp2>>6)*25;
  230.         DS3231Time[8]=Ttemp2;
  231. }
  232. void READ_Time()
  233. {
  234.    
  235.     DS3231Time[0]=read_random(DS3231_SECOND);
  236.         DS3231Time[1]=read_random(DS3231_MINUTE);
  237.         DS3231Time[2]=read_random(DS3231_HOUR);
  238.         DS3231Time[3]=read_random(DS3231_YEAR);
  239.         DS3231Time[4]=read_random(DS3231_MONTH);
  240.         DS3231Time[5]=read_random(DS3231_DAY);
  241.         DS3231Time[6]=read_random(DS3231_WEEK);
  242.         get_show_Temperature();
  243. }
  244. void DS3231_opennz1(uchar second,minute,hour,day)
  245. {
  246.     write_byte(0x0e,0x1d);  
  247.         write_byte(DS3231_SALARM1ECOND,second);//秒
  248.         write_byte(DS3231_ALARM1MINUTE,minute);//分
  249.         write_byte(DS3231_ALARM1HOUR,hour);//時(shí)
  250.         write_byte(DS3231_ALARM1WEEK,day);//星期/日
  251. }
  252. void DS3231_opennz2(minute,hour,day)
  253. {
  254.     write_byte(0x0e,0x1e);  
  255.         write_byte(DS3231_ALARM2MINUTE,minute);//分
  256.         write_byte(DS3231_ALARM2HOUR,hour);//時(shí)
  257.         write_byte(DS3231_ALARM2WEEK,day);//星期/日
  258. }
  259. void DS3231_Init()
  260. {
  261.     ModifyTime(DS3231Time[3],DS3231Time[4],DS3231Time[5],DS3231Time[2],DS3231Time[1],DS3231Time[0],DS3231Time[6]);
  262. }
復(fù)制代碼
其中void DS3231_opennz1(uchar second,minute,hour,day)和void DS3231_opennz2(minute,hour,day)分別是鬧鐘1和鬧鐘2的啟動(dòng)程序,
下面是鬧鐘的關(guān)閉程序:
unsigned char i;
write_byte(0x0f,i|=0x00);
這是停止鬧鐘2和鬧鐘1。
鬧鐘判斷程序:
void nz_if()
{
    unsigned char i;
        i=read_random(0x0f);//讀取狀態(tài)寄存器
        i=i&0x02;//鬧鐘2寫(xiě)i=i&0x02;鬧鐘1寫(xiě)i=i&0x01;
        if(i == 0x02)//鬧鐘2寫(xiě)i==0x02;鬧鐘1寫(xiě)i==0x01;
        {        
            //鬧鐘提醒程序,你們想怎么搞就怎么搞
        }

希望能幫到你們!




評(píng)分

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

查看全部評(píng)分

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

使用道具 舉報(bào)

沙發(fā)
ID:934353 發(fā)表于 2021-7-15 15:42 | 只看該作者
厲害了,值得參考
回復(fù)

使用道具 舉報(bào)

板凳
ID:898540 發(fā)表于 2021-10-21 20:50 | 只看該作者
uchar  DS3231Time[9]={0x40,0x59,0x05,0x21,0x05,0x08,0x06,0x00,0x00}; //秒分時(shí)年月日周溫度高字節(jié)溫度低字節(jié)        請(qǐng)問(wèn)這行的數(shù)據(jù)是什么意思,怎么數(shù)據(jù)手冊(cè)沒(méi)有看到?
回復(fù)

使用道具 舉報(bào)

地板
ID:898540 發(fā)表于 2021-11-12 23:03 | 只看該作者

uchar  DS3231Time[9]={0x40,0x59,0x05,0x21,0x05,0x08,0x06,0x00,0x00};   同問(wèn)這個(gè),什么意思?
回復(fù)

使用道具 舉報(bào)

5#
ID:884042 發(fā)表于 2022-7-25 01:05 | 只看該作者
combo111 發(fā)表于 2021-11-12 23:03
uchar  DS3231Time[9]={0x40,0x59,0x05,0x21,0x05,0x08,0x06,0x00,0x00};   同問(wèn)這個(gè),什么意思?

好久沒(méi)上論壇,所以沒(méi)看到,請(qǐng)諒解,這個(gè)是時(shí)鐘數(shù)據(jù),用一個(gè)數(shù)組,比如要讀秒就調(diào)用:
i=DS3231Time[0];
這里用的是BCD碼,所以還需解碼,
second=(i/16*10)+(i&0x0f);
回復(fù)

使用道具 舉報(bào)

6#
ID:1093241 發(fā)表于 2023-10-5 19:35 | 只看該作者
如何能設(shè)置多個(gè)鬧鐘呢
回復(fù)

使用道具 舉報(bào)

7#
ID:1112603 發(fā)表于 2024-5-1 11:33 | 只看該作者
學(xué)習(xí)了,非常感謝!
回復(fù)

使用道具 舉報(bào)

8#
ID:871721 發(fā)表于 2024-8-12 18:45 來(lái)自手機(jī) | 只看該作者
yongquan 發(fā)表于 2023-10-5 19:35
如何能設(shè)置多個(gè)鬧鐘呢

ds1302就只有兩個(gè)鬧鐘的地址
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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