2020-09-27 15:27:37
使用的DS1302模块:
![](https://img2020.cnblogs.com/blog/1607355/202009/1607355-20200927153134790-899922947.png) ![](https://img2020.cnblogs.com/blog/1607355/202009/1607355-20200927153219098-662741220.png)
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。工作电压宽达2.5~5.5V。采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。DS1302的外部引脚分配如下图所示。DS1302用于数据记录,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。
![](https://img2020.cnblogs.com/blog/1607355/202009/1607355-20200927152928530-1923218802.png)
![](https://img2020.cnblogs.com/blog/1607355/202009/1607355-20200927152936611-51971453.png)
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:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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>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>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>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>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|(1PB5
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:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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详细介绍
|