DS1302的STM32F103c8t6驅動程序(附代碼親測可用)


2020-09-27  15:27:37

  使用的DS1302模塊:

  

 

 

   

  DS1302是美國DALLAS公司推出的一種高性能、低功耗的實時時鍾芯片,附加31字節靜態RAM,采用三線接口與CPU進行同步通信,並可采用突發方式一次傳送多個字節的時鍾信號和RAM數據。實時時鍾可提供秒、分、時、日、星期、月和年,一個月小與31天時可以自動調整,且具有閏年補償功能。工作電壓寬達2.5~5.5V。采用雙電源供電(主電源和備用電源),可設置備用電源充電方式,提供了對后背電源進行涓細電流充電的能力。DS1302的外部引腳分配如下圖所示。DS1302用於數據記錄,特別是對某些具有特殊意義的數據點的記錄上,能實現數據與出現該數據的時間同時記錄,因此廣泛應用於測量系統中。

 

 

 

 

  DS1302的一條指令一個字節8位,其中第七位(即最高位)是固定1,這一位如果是0的話,那寫進去是無效的。第六位是選擇RAM還是CLOCK的,我前邊說過,我們這里主要講CLOCK時鍾的使用,它的RAM功能我們不用,所以如果選擇CLOCK功能,第六位是0,如果要用RAM,那第六位就是1。從第五到第一位,決定了寄存器的5位地址,而第零位是讀寫位,如果要寫,這一位就是0,如果要讀,這一位就是1,如圖15-9所示。
        DS1302時鍾的寄存器,其中8個和時鍾有關的,5位地址分別是00000一直到00111這8個地址,還有一個寄存器的地址是01000,這是涓流充電所用的寄存器,我們這里不講。在DS1302的數據手冊里的地址,直接把第七位、第六位和第零位值給出來了,所以指令就成了80H、81H那些了,最低位是1,那么表示讀,最低位是0表示寫,如圖15-10所示。

 

 

        寄存器一:最高位CH是一個時鍾停止標志位。如果我們的時鍾電路有備用電源部分,上電后,我們要先檢測一下這一位,如果這一位是0,那說明我們的時鍾在系統掉電后,由於備用電源的供給,時鍾是持續正常運行的;如果這一位是1,那么說明我們的時鍾在系統掉電后,時鍾部分不工作了。若我們的Vcc1懸空或者是電池沒電了,當我們下次重新上電時,讀取這一位,那這一位就是1,我們可以通過這一位判斷時鍾在單片機系統掉電后是否持續運行。剩下的7位高3位是秒的十位,低4位是秒的個位,這里注意再提一次,DS1302內部是BCD碼,而秒的十位最大是5,所以3個二進制位就夠了。
        寄存器二:bit7沒意義,剩下的7位高3位是分鍾的十位,低4位是分鍾的個位。
        寄存器三:bit7是1的話代表是12小時制,是0的話代表是24小時制,bit6固定是0,bit5在12小時制下0代表的是上午,1代表的是下午,在24小時制下和bit4一起代表了小時的十位,低4位代表的是小時的個位。
        寄存器四:高2位固定是0,bit5和bit4是日期的十位,低4位是日期的個位。
        寄存器五:高3位固定是0,bit4是月的十位,低4位是月的個位。
        寄存器六:高5位固定是0,低3位代表了星期。
        寄存器七:高4位代表了年的十位,低4位代表了年的個位。這里特別注意,這里的00到99年指的是2000年到2099年。
       寄存器八:bit7是一個保護位,如果這一位是1,那么是禁止給任何其他的寄存器或者那31個字節的RAM寫數據的。因此在寫數據之前,這一位必須先寫成0。

 

可用代碼:

 

DS1302.c:

  1 #include"DS1302.h"
  2 
  3  /*****************************************
  4  * 函數名:void DS1302_GPIOInit(void)
  5  * 描述  :    DS1302 GPIO配置
  6  * 輸入  :
  7  * 輸出  :無
  8  * 調用  :
  9         CLK---PB5,
 10         IO--->PB6,
 11         RES--->PB7,
 12  *************************************/
 13 void DS1302_GPIOInit(void)
 14 {
 15   GPIO_InitTypeDef GPIO_InitStructre;
 16   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);            /*open GPIO  clock*/
 17   GPIO_InitStructre.GPIO_Pin= GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
 18   GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
 19   GPIO_InitStructre.GPIO_Mode=GPIO_Mode_Out_PP;
 20   GPIO_Init(DS1302_PORT, &GPIO_InitStructre);
 21 }
 22  /*****************************************
 23  * 函數名:void DS1302_IO_GPIO(void)
 24  * 描述  :    DS1302 之 IO GPIO 輸入輸出配置
 25  * 輸入  :FLAG標志位
 26  * 輸出  :無
 27 * 調用  :OUT:表示輸出,IN:表示輸入
 28           FLAG:
 29  *************************************/
 30 void DS1302_IO_GPIO(uchar FLAG)
 31 {
 32   GPIO_InitTypeDef GPIO_InitStructre;
 33   //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);            /*open GPIO  clock*/
 34     /**********配置數據IO端口 輸出 **********/
 35     if(FLAG==0x01)
 36   {
 37     GPIO_InitStructre.GPIO_Pin= GPIO_Pin_6;//配置IO_GPIO
 38   GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
 39   GPIO_InitStructre.GPIO_Mode=GPIO_Mode_Out_PP;
 40   GPIO_Init(DS1302_PORT, &GPIO_InitStructre);
 41   }
 42     /**********配置數據IO端口 輸入**********/
 43     else if(FLAG==0x00)
 44   {
 45      GPIO_InitStructre.GPIO_Pin= GPIO_Pin_6;//配置IO_GPIO
 46    GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
 47    GPIO_InitStructre.GPIO_Mode=GPIO_Mode_IPU;  //配置上拉輸入 
 48    GPIO_Init(DS1302_PORT, &GPIO_InitStructre);
 49    }
 50 }
 51   /*****************************************
 52  * 函數名:void DS1302_delay(u8 dd)
 53  * 描述  :簡單延時
 54  * 輸入  :
 55  * 輸出  :無
 56  * 調用  :
 57  *************************************/
 58 void DS1302_delay(u8 dd)
 59 {
 60     u8 i;
 61     for(;dd>0;dd--)
 62   for(i=110;i>0;i--);
 63 }
 64 
 65   /*****************************************
 66  * 函數名:void DS1302_Write(uchar add,uchar dat)
 67  * 描述  :DS1302寫指令和數據
 68 *  輸入  :add:發送地址,dat:所在數據
 69  * 輸出  :無
 70  * 調用  :
 71  *************************************/
 72  void DS1302_Write(uchar add,uchar dat)
 73  {
 74  uchar i,temp1,temp2;
 75  temp1=add;
 76  temp2=dat;
 77  RES_Set_1;//RET=1;    
 78 //發送地址     
 79 for(i=0;i<8;i++)
 80  {
 81         if(temp1&0x01)
 82          {IO_Set_1;  }     //IO=1;      
 83         else
 84         { IO_Reset_0;}   //IO=0;     
 85         temp1=temp1>>1;
 86         CLK_Set_1;            //CLK=1;
 87         DS1302_delay(2);    
 88         CLK_Reset_0;    //CLK=0;
 89   }
 90 
 91 //發送數據
 92 for(i=0;i<8;i++)
 93     {
 94         /*IO=(temp2>>i)&0x01;這一句代替下面屏蔽的內容  */
 95         if(temp2&0x01)
 96          {IO_Set_1;  }     //IO=1;  
 97         else 
 98          { IO_Reset_0;}    //IO=0;
 99             temp2=temp2>>1;
100             CLK_Set_1;            //CLK=1;
101             DS1302_delay(2);    
102             CLK_Reset_0;    //CLK=0;
103     } 
104 RES_Reset_0;// RET=0;
105  }
106  
107  
108  
109 
110 /*****************************************
111  * 函數名:uchar DS1302_Read(uchar add)
112  * 描述  :DS1302讀數據
113  *  輸入  :add:發送所在地址
114  * 輸出  :
115  * 調用  :
116  *************************************/
117 uchar DS1302_Read(uchar add)
118 {
119   uchar i,suf,temp,mm,nn,value;
120    temp=add;
121    RES_Set_1;//RET=1;  
122     //寫地址
123   for(i=0;i<8;i++)
124       {
125        if(temp&0x01)
126        {IO_Set_1;  }     //IO=1; 
127       else
128          { IO_Reset_0;}    //IO=0;
129       temp=temp>>1;
130         CLK_Set_1;            //CLK=1;
131         DS1302_delay(2);    
132         CLK_Reset_0;    //CLK=0;  
133       }
134  //讀數據
135         
136 DS1302_IO_GPIO(IN);//配置IO為輸入        
137   for(i=0;i<8;i++)
138     { 
139      suf=suf>>1;//讀數據變量
140      if(IO_Read)    //IO=1
141      {
142          suf=suf|0x80; 
143      }
144      else     //IO=0
145      {
146      suf=suf&0x7f;  
147      }
148      
149         CLK_Set_1;            //CLK=1;
150         DS1302_delay(2);    
151         CLK_Reset_0;    //CLK=0;  
152     }
153     RES_Reset_0;    // RET=0;
154     
155 DS1302_IO_GPIO(OUT);//配置IO為輸出,恢復正常狀態        
156 //數據處理轉化十進制    
157 mm=suf/16;
158 nn=suf%16;
159 value=mm*10+nn;
160 return value;        
161 }
162 /*****************************************
163  * 函數名:void DS1302_SetTime(uchar *ad)
164  * 描述  :DS1302 寫入設置時間
165  *  輸入  :add:發送所在地址
166  * 輸出  :
167  * 調用  :
168  *************************************/
169 void DS1302_SetTime(uchar *ad)    
170   {     
171    DS1302_Write(0x8e,0x00);   //WP=0 允許數據寫入DS1302
172 /**********以下對時分秒的初始化*************/
173         DS1302_Write(ds1302_sec_addr,ad[5]);  //
174         DS1302_Write(ds1302_min_addr,ad[4]);   //
175         DS1302_Write(ds1302_hour_addr,ad[3]);   //
176       /**********以下對年月日的初始化*************/
177      DS1302_Write(ds1302_day_addr,ad[2]);
178    DS1302_Write(ds1302_month_addr,ad[1]);
179       DS1302_Write(ds1302_year_addr,ad[0]);     
180         
181      DS1302_Write(0x8e,0x80);   //0x8e控制字節地址,bit7=WP WP=1 禁止數據寫入DS1302
182   }
183     
184     
185 /*****************************************
186  * 函數名: void DS1302_OFF(void)
187  * 描述  :DS1302時間禁止走時
188  *  輸入  :
189  * 輸出  :
190  * 調用  :
191  *************************************/    
192   void DS1302_OFF(void)
193   {
194    uchar temp;
195    temp=DS1302_Read(0x81);//讀取表地址時間
196    DS1302_Write(0x8e,0x00);//WP=0 允許數據寫入DS1302
197    temp=temp|(1<<7);
198    DS1302_Write(0x80,temp);//WP=1 禁止數據寫入DS1302
199   
200   }
201 /*****************************************
202  * 函數名: void DS1302_ON(void)
203  * 描述  :DS1302時間開始運行,走時
204  *  輸入  :
205  * 輸出  :
206  * 調用  :
207  *************************************/    
208   void DS1302_ON(void)
209   {
210    uchar temp;
211    temp=DS1302_Read(0x81);
212    DS1302_Write(0x8e,0x00);//WP=0 允許數據寫入DS1302
213    temp=temp|(0<<7);
214    DS1302_Write(0x80,temp);//WP=0 允許數據寫入DS1302
215   
216   }
217  
218  
219  
220  
221  
222 
223  /*****************************************
224  * 函數名:void DS1302_init(uchar *time)
225  * 描述  :    DS1302初始化
226  * 輸入  :無
227  * 輸出  :無
228 * 調用  :
229  *************************************/
230 void DS1302_init(uchar *time)
231 {
232     DS1302_GPIOInit();//GPIO初始化配置
233     DS1302_delay(2);
234   RES_Reset_0; //RET=0;
235   CLK_Reset_0;// CLK=0;
236     //下面是對DS1302啟動電池,不掉電   設置時間
237     DS1302_Write(0x8e,0x00);//WP=0 允許數據寫入DS1302
238     DS1302_Write(0x90,0xA7);//充電(1個二極管+8K電阻)
239     DS1302_Write(0x8E,0X80);//開啟保護 WP=1
240     if(DS1302_Read(0X81)&0X80)//查詢DS302時鍾是否啟動,如果時鍾停止走動:啟動時鍾+初始化時鍾
241     { 
242         DS1302_SetTime(time);//設置設置初始時鍾
243     }
244     //否則跳過
245     
246 }
247  /*****************************************
248  * 函數名:void DS1302_Readtime(void)
249  * 描述  :    DS1302時間讀出
250  * 輸入  :無
251  * 輸出  :無
252 * 調用  :
253  *************************************/
254 void DS1302_Readtime(void)
255 {
256     label2[0]=DS1302_Read( 0x8D)/10;      //年:十位
257     label2[1]=DS1302_Read( 0x8D)%10;      //年:個位
258     label2[2]='/';
259     label2[3]=DS1302_Read( 0x89)/10;     //月 :
260     label2[4]=DS1302_Read( 0x89)%10;     //月 :
261     label2[5]='/';
262     label2[6]=DS1302_Read( 0x87)/10;     //
263     label2[7]=DS1302_Read( 0x87)%10;     //
264     label2[8]=DS1302_Read( 0x85)/10;     //
265     label2[9]=DS1302_Read( 0x85)%10;     //
266     label2[10]=':';    
267     label2[11]=DS1302_Read( 0x83)/10;     //讀分
268     label2[12]=DS1302_Read( 0x83)%10;     //讀分
269     label2[13]=':';
270     label2[14]=DS1302_Read( 0x81)/10;     //讀秒 
271     label2[15]=DS1302_Read( 0x81)%10;     //讀秒 
272 }
View Code

 

DS1302.h:

 1 #ifndef __DS1302_H__
 2 #define __DS1302_H__
 3 #include <stm32f10x.h>
 4 #define uchar unsigned char
 5 #define uint unsigned int
 6 /***DS1302時鍾芯片****************************/
 7 //CLK--->PB5
 8 //IO---->PB6
 9 //RES--->PB7
10 /****************************/
11 
12 #define OUT   0x01
13 #define IN    0x00
14 extern uchar label2[16];//時間存放數組
15 //extern uchar Settime[6]={0x17,0x04,0x18,0x16,0x57,0x30}; //設置時間函數
16 #define DS1302_PORT   GPIOB
17 
18 #define CLK_Reset_0  GPIOB->BRR=GPIO_Pin_5    
19 #define CLK_Set_1    GPIOB->BSRR=GPIO_Pin_5   
20 
21 #define IO_Reset_0   GPIOB->BRR=GPIO_Pin_6    
22 #define IO_Set_1     GPIOB->BSRR=GPIO_Pin_6 
23 
24 #define RES_Reset_0  GPIOB->BRR=GPIO_Pin_7   
25 #define RES_Set_1    GPIOB->BSRR=GPIO_Pin_7
26 
27 #define IO_Read   GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6) 
28 /*************************/
29 #define Time_24_Hour    0x00    //24小時制
30 #define Time_Start     0x00    //開始走時
31 //DS1302寄存器操作指令定義時間地址
32 #define ds1302_sec_addr   0x80       //
33 #define ds1302_min_addr   0x82       //
34 #define ds1302_hour_addr  0x84       //
35 #define ds1302_day_addr   0x86       //
36 #define ds1302_month_addr 0x88       //
37 #define ds1302_year_addr  0x8c       //
38 /********************/
39 void DS1302_GPIOInit(void);
40 void DS1302_IO_GPIO(uchar FLAG);//配置IO的方向
41 void DS1302_delay(u8 dd);
42 void DS1302_Write(uchar add,uchar dat);
43 uchar DS1302_Read(uchar add);
44 void DS1302_SetTime(uchar *ad);
45 void DS1302_OFF(void);
46 void DS1302_ON(void);
47 void DS1302_init(uchar *time);
48 void DS1302_Readtime(void);
49 
50 
51 
52 #endif
View Code

 

 main.c:

 1 #include "stm32f10x.h"
 2 #include "led.h"
 3 #include "key.h" 
 4 #include "usart1.h"
 5 #include "delay.h"
 6 #include "DS1302.h"  
 7 
 8 #define AHB_INPUT 72
 9 
10 unsigned char uart1_buf[11]={0}; 
11 volatile u32 time; // ms 計時變量
12 
13 u16    t=0,mode=0,flag=0;    
14 u8 label2[16]; //時間存放數組顯示格式  
15 u8 Settime[6]={0x20,0x09,0x16,0x20,0x59,0x50};  // 初始時間設置: 年 月 日  時 分 秒
16 
17 int main(void)
18 {      
19     int tt = 0;
20 
21     SystemInit();    // 配置系統時鍾為72M 
22     delay_init();
23     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);            //配置完中斷向量表以后才能初始化其他東西
24     uart_init(9600);     
25 
26     TIM2_NVIC_Configuration();                                                     // TIM2 定時配置 
27     TIM2_Configuration();     
28     START_TIME;                                                                                     // TIM2 開始計時     
29     
30     DS1302_init(Settime);                                                                //時間初始化
31   DS1302_SetTime(Settime);                                                        //設置初始時間
32     
33 
34     while(1)                    
35   {        
36         tt++;
37         if(tt>=3200000)
38         {
39                 tt = 0;
40             DS1302_Readtime();
41         printf("%lld,",num);
42                 printf("20");
43                 printf("%d",label2[0]);                
44                 printf("%d",label2[1]);                
45                 printf("%c",label2[2]);                
46                 printf("%d",label2[3]);                
47                 printf("%d",label2[4]);                
48                 printf("%c",label2[5]);                
49                 printf("%d",label2[6]);                
50                 printf("%d, ",label2[7]);    
51 
52                 printf("%d",label2[8]);                            
53                 printf("%d",label2[9]);                
54                 printf("%c",label2[10]);    
55                 printf("%d",label2[11]);                
56                 printf("%d",label2[12]);                
57                 printf("%c",label2[13]);                
58                 printf("%d",label2[14]);                
59                 printf("%d, ",label2[15]);                
60                 printf("%.2f, %.2f ",PM25,PM10);
61                 printf("%c",0x0d);
62                 printf("%c",0x0a);
63         }
64 
65   }
66 }
View Code

 

參考:

【轉】stm32驅動DS1302芯片

STM32之DS1302時鍾模塊程序(穩定並且有詳細代碼注釋)

實時時鍾DS1302詳細介紹

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM