一个完整的DS1302时钟在STM32上的应用(代码位置有点乱).

整理后的完整代码https://blog.csdn.net/weibo1230123/article/details/80372790
<https://blog.csdn.net/weibo1230123/article/details/80372790>
一个完整的DS1302时钟在STM32上的应用 /*DS1302时钟芯片*/ uint8_t read[] =
{0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//读秒、分、时、日、月、周、年的寄存器地址 uint8_t write[] =
{0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//写秒、分、时、日、月、周、年的寄存器地址 uint8_t
start_time2[8]={0,0,10,5,5,6,18};//初始化时间:2018年5月5号10:00:00星期六 //I/O定义 void
GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; //DS1302时钟定义
//SCLK GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed
= GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd =
GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,
GPIO_Pin_12); //RST GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode
= GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA,
&GPIO_InitStructure); GPIO_ResetBits(GPIOA, GPIO_Pin_0);
/*IO:PB2配置为开漏模式,此模式下能够实现真正的双向IO口*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode
= GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB,
&GPIO_InitStructure); GPIO_ResetBits(GPIOB, GPIO_Pin_2); }
//my_itoa:整数转换成相应的字符串 void my_itoa(long i, char *string) { int power = 0, j =
0; j = i; for (power = 1; j>10; j /= 10) power *= 10; for (; power>0; power /=
10) { *string++ = '0' + i / power; i %= power; } *string = '\0';
//printf("%s\n", string); } //标准时间转换成时间戳 long GetTick(char *str_time) { struct
tm stm; int iY, iM, iD, iH, iMin, iS; memset(&stm,0,sizeof(stm)); iY =
atoi(str_time); iM = atoi(str_time+5); iD = atoi(str_time+8); iH =
atoi(str_time+11); iMin = atoi(str_time+14); iS = atoi(str_time+17);
stm.tm_year=iY-1900; stm.tm_mon=iM-1; stm.tm_mday=iD; stm.tm_hour=iH-8;//注意时区转换
stm.tm_min=iMin; stm.tm_sec=iS; /*printf("%d-%0d-%0d %0d:%0d:%0d\n", iY, iM,
iD, iH, iMin, iS);*/ return mktime(&stm); } //写一个字节的数据sck上升沿写数据 void
write_1302byte(uint8_t dat) { uint8_t i = 0; GPIO_ResetBits(GPIOB,GPIO_Pin_12);
//ds1302clk=0 delay_us(2);//延时大约2us //my_delay_us(1); for(i = 0;i < 8;i ++) {
GPIO_ResetBits(GPIOB,GPIO_Pin_12); //ds1302clk=0; if(dat&0x01)
GPIO_SetBits(GPIOB,GPIO_Pin_2); else //ds1302dat=(dat&0x01)
GPIO_ResetBits(GPIOB,GPIO_Pin_2); delay_us(2); //my_delay_us(1);
GPIO_SetBits(GPIOB,GPIO_Pin_12); //发送一位数据,clk上升沿,//ds1302clk=1 dat >>= 1;
delay_us(1); //my_delay_us(1); } } //向DS1302指定寄存器写入一个字节的数据 void
write_1302(uint8_t add,uint8_t dat) { GPIO_ResetBits(GPIOA,GPIO_Pin_0);
//只有在rst为高电平的时候才能进行数据传输 GPIO_ResetBits(GPIOB,GPIO_Pin_12);
//只有clk为低电平的时候,rst才能被置为高电平 //ds1302rst=0; //ds1302clk=0; delay_us(1); //略微延时
//my_delay_us(1); GPIO_SetBits(GPIOA,GPIO_Pin_0); //clk = 0之后,这里将rst拉高,准备传送数据
//ds1302rst=1; delay_us(2); //时间大约2us //my_delay_us(1); write_1302byte(add);
//先发地址 write_1302byte(dat); //然后发数据 GPIO_ResetBits(GPIOA,GPIO_Pin_0); //这里释放总线
GPIO_ResetBits(GPIOB,GPIO_Pin_12); //拉低clk,以备下一次数据发送 //ds1302clk=0;
//ds1302rst=0; delay_us(5); //my_delay_us(1); } //从DS1302指定寄存器读数据 uint8_t
read_1302(uint8_t add) { uint8_t i=0; uint8_t Return_dat = 0x00;
GPIO_ResetBits(GPIOA,GPIO_Pin_0); //ds1302rst=0;
GPIO_ResetBits(GPIOB,GPIO_Pin_12); //ds1302clk=0; delay_us(3); //略微延时2us
//my_delay_us(1); GPIO_SetBits(GPIOA,GPIO_Pin_0); //ds1302rst=1; delay_us(3);
//时间要大约3us // my_delay_us(1); write_1302byte(add); //先写寄存器的地址 for(i=0;i<8;i++)
{ GPIO_SetBits(GPIOB,GPIO_Pin_12); //ds1302clk=1; delay_us(5);
//my_delay_us(1); Return_dat >>= 1; delay_us(5); //my_delay_us(1);
GPIO_ResetBits(GPIOB,GPIO_Pin_12); //ds1302clk=0;//拉低时钟线,以便于数据的读入
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2)==1) //数据线此时为高电平 {Return_dat =
Return_dat|0x80;} } delay_us(1); //my_delay_us(1);
GPIO_ResetBits(GPIOA,GPIO_Pin_0); //ds1302rst=0;释放总线 return Return_dat; }
//初始化1302 void ds1302_init(uint8_t *write,uint8_t *time) { uint8_t i=0,j=0;
write_1302(0x8e,0x00); //关闭写保护 for(i=0;i<7;i++) //十进制转BCD码 { j=time[i]%10;
//个位数部分 time[i]=(time[i]/10)*16+j; } for(i=0;i<7;i++) //进行对时 {
write_1302(write[i],time[i]); //在对应寄存器上写入对应的十六进制数据 } write_1302(0x8e,0x80);
//打开写保护 } //从DS1302中读取出时间赋给myTime(硬件系统时间) void ds1302_data(uint8_t *read) {
write_1302(0x8e,0x00); //关闭写保护 write_1302(0x8e,0x80); //打开写保护 uint8_t
i=0,g[7],time[7]; static uint8_t s=1; for(i=0;i<7;i++) {
time[i]=read_1302(read[i]); //读数据已经完成 } for(i=0;i<7;i++) { g[i]=time[i]%16;
//秒个位数据:BCD转十进制 time[i]=time[i]/16; //秒十位数据 }
//此时已转换成10进制数,g[i]里面存放的是秒分时日月周年的各个位数据 //而此时的time【i】里面存放的则是秒分时日月周年的十位数据
if(s!=(time[0]+g[0])) ACCLOG("DS1302 time is 20%d%d %d%d %d%d %d%d:%d%d:%d%d
%d\n",time[6],g[6],time[4],g[4],time[3],g[3],time[2],g[2],time[1],g[1],time[0],g[0],g[5]);
s=time[0]+g[0]; char str_time[20]; str_time[0] = '2'; str_time[1] = '0';
//N2Char():整数转字符串 str_time[2] = N2Char((int)(time[6])); str_time[3] =
N2Char((int)g[6]); str_time[4] = 32; str_time[5] = N2Char((int)time[4]);
str_time[6] = N2Char((int)g[4]); str_time[7] = 32; str_time[8] =
N2Char((int)time[3]); str_time[9] = N2Char((int)g[3]); str_time[10] = 32;
str_time[11] = N2Char((int)time[2]); str_time[12] = N2Char((int)g[2]);
str_time[13] = 32; str_time[14] = N2Char((int)time[1]); str_time[15] =
N2Char((int)g[1]); str_time[16] = 32; str_time[17] = N2Char((int)time[0]);
str_time[18] = N2Char((int)g[0]); long ConfigureCodeTime = GetTick(str_time);
//ConfigureCodeTime中放的是时间戳 ACCLOG("\nDS1302 turn to Timestamp
is:%ld\n",ConfigureCodeTime); // myTime[11] = ConfigureCodeTime; //memset((char
*) &myTime, 0, sizeof(myTime)); my_itoa(ConfigureCodeTime,myTime);
//再把ConfigureCodeTime保存的时间戳赋给myTime数组 ACCLOG("myTime
is:%ld\n",ConfigureCodeTime); //itoa(ConfigureCodeTime, myTime, 10); }
 

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信