DS1302时钟芯片在STM32F0中的完整应用代码
生活随笔
收集整理的這篇文章主要介紹了
DS1302时钟芯片在STM32F0中的完整应用代码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?DS1302在STM32F0中的應用
/** *作者:魏波 *時間:2017.6.6 * **///DS1302在STM32F0中的應用/**********************第一:首先對端口進行配置****************/ //DS1302時鐘端口定義 void GPIO_Configuration(void) {GPIO_InitTypeDef GPIO_InitStructure;//SCLKGPIO_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);//RSTGPIO_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);}uint8_t read_1302(uint8_t add); void ds1302_data(uint8_t *read); void write_1302byte(uint8_t dat) ; void write_1302(uint8_t add,uint8_t dat); void ds1302_init(uint8_t *write,uint8_t *time);uint8_t read[] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//讀秒、分、時、日、月、周、年的寄存器地址 uint8_t write[] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//寫秒、分、時、日、月、周、年的寄存器地址void main(char src[]) {/**********************第二:把一個十進制時間戳轉換成常規格式的時間****************/char myTime[11] = "1516766898";//存放十進制時間戳time_t t; struct tm *p;t=atoi(myTime);//time(&t);p=gmtime(&t); uint8_t Second=0,Min=0,Hour=0,Day=0,Month=0,Weekday=0,Year=0,Year_end=0;Second = (uint8_t)(p->tm_sec);Min = (uint8_t)(p->tm_min);Hour = (uint8_t)(p->tm_hour+8);Day = (uint8_t)(p->tm_mday);Month = (uint8_t)(1+p->tm_mon);Weekday = (uint8_t)(p->tm_wday);//Year = (uint8_t)(1900+p->tm_year);int unitPlace,tenPlace;unitPlace = (1900+p->tm_year)/1%10; //獲取年的個位tenPlace = (1900+p->tm_year)/10%10; //獲取年的十位Year_end = (uint8_t)(tenPlace*10 + unitPlace);uint8_t start_time[] = {Second,Min,Hour,Day,Month,Weekday,Year_end};ACCLOG("Second = %d\nMin = %d\nHour = %d\nDay = %d\nMonth = %d\nWeekday = %d\nYear_end = %d\n",Second,Min,Hour,Day,Month,Weekday,Year_end);/**********************第三:ds1302_init()函數:用常規格式的時間初始化DS1302***/ds1302_init(write,start_time);/**********************第四:ds1302_data()函數*******************************(1)把時間寫入DS1302(2)讀出DS1302里的時間(3)把讀出的時間轉換成十進制時間戳(4)把這個十進制時間戳轉換成字符串存入一個字符數組里******************************************************************/ ds1302_data(read); }/**********************************DS1302時鐘子函數如下*****************************************///寫一個字節的數據sck上升沿寫數據 void write_1302byte(uint8_t dat) { uint8_t i = 0; GPIO_ResetBits(GPIOB,GPIO_Pin_12); //ds1302clk=0 delay_us(2);//延時大約2us 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); GPIO_SetBits(GPIOB,GPIO_Pin_12); //發送一位數據,clk上升沿,//ds1302clk=1 dat >>= 1; 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); //略微延時 GPIO_SetBits(GPIOA,GPIO_Pin_0); //clk = 0之后,這里將rst拉高,準備傳送數據 //ds1302rst=1; delay_us(2); //時間大約2us 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); } //從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 GPIO_SetBits(GPIOA,GPIO_Pin_0); //ds1302rst=1; delay_us(3); //時間要大約3us write_1302byte(add); //先寫寄存器的地址 for(i=0;i<8;i++) { GPIO_SetBits(GPIOB,GPIO_Pin_12); //ds1302clk=1; delay_us(5);Return_dat >>= 1; delay_us(5);GPIO_ResetBits(GPIOB,GPIO_Pin_12); //ds1302clk=0;//拉低時鐘線,以便于數據的讀入 if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2)==1) //數據線此時為高電平 {Return_dat = Return_dat|0x80;} } delay_us(1); GPIO_ResetBits(GPIOA,GPIO_Pin_0); //ds1302rst=0;釋放總線 return Return_dat; }//標準時間轉換成時間戳 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; return mktime(&stm); }//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); } //處理數據 void ds1302_data(uint8_t *read) { 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; //秒十位數據 } ACCLOG("20%d%d年%d%d月%d%d日%d%d:%d%d:%d%d 星期%d\r\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]); char str_time[14];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("ConfigureCodeTime is:%ld\n",ConfigureCodeTime); //itoa(ConfigureCodeTime, myTime, 10); //所用stdlib.h庫中沒有itoa函數,只能自己寫my_itoa(ConfigureCodeTime,myTime); //再把ConfigureCodeTime保存的時間戳賦給myTime數組 }//初始化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); //打開寫保護 } //整數轉字符串 char N2Char(long n) { int i; //char flag = 'a'; char c; if ((i=n/10)!=0) N2Char(i); c = n%10 + '0'; printf("%c", c); //return flag;return c;}?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的DS1302时钟芯片在STM32F0中的完整应用代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MF RC522读卡芯片手册
- 下一篇: 一个完整的DS1302时钟在STM32上