生活随笔
收集整理的這篇文章主要介紹了
基于stm32f103zet6的DS1302学习
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
由于硬件出了問題,也就是外部低速晶振沒用,震不起來,然后查看了網上的帖子,STM32的RTC果然口碑不怎么樣,所以果斷換DS1302,在移植的過程中還算順利,記錄下來吧,也算對自己的總結吧!
1、所謂的DS1302
這里面也指明了簡單的SPI協議
然后就直接上代碼了,注釋很詳細的!基本實現單行注釋
1、主函數main
[html]?view plaincopy
#include?"stm32f10x.h"??????#include?"SysTick.h"??#include?"Delay.h"??#include?"Usart.h"??#include?"stdio.h"??#include?"DS1302.h"??/*******由于沒有做外設測試的程序是:按鍵PA0僅一個LED燈??????????????????????????????????******/??/*******由于沒有做外設測試的程序是:串口采用的是PA9->(T<->T),PA9->(R<->R)*****/??/*******由于沒有做外設測試的程序是:ds1302clk?<->?PA4??????????????????????????????????????????????????????????????????????????ds1302dat?<->?PA5??????????????????????????????????????????????????????????????????????????ds1302rst?<->?PA6??????????????????????????????????????*****/????????????????????????????????????????????????????????????????????????????extern?uint8_t?write[];??extern?uint8_t?read[];????int?main(void)??{??????//uint8_t?time[]?=?{0,0,12,11,11,1,13};??????//初始化系統定時器??????SysTick_Init();??????USART1_Config();??????ds1302_GPIO_Configuration();????????????????????????????????????????????????????//一定別忘記了配置GPIO??????printf("\r\n?("__DATE__?"?-?"?__TIME__?")?\r\n");??????//ds1302_init(write,time);??????????????????????????????????????????????????????//設置1302的初始時間??????ds1302_data(read);??????while(1);???????????????????????????????????????????????????????????????????????????????????????????//這個得加,不然的話會有尾巴是亂碼!!!??}??
[html]?view plaincopy
/*******************************************************************************??**?文件名稱?:?ds1302.c??**?編譯環境?:?RealView?MDK-ARM?4.53??**?文件作者?:?????**?功能說明?:?ds1302相關函數定義??**?軟件協議?:模擬SPI協議??**?簡介???????????:clk上升沿發送數據,clk下降沿接收數據??????????????????????????:typedef?unsigned??????????char?uint8_t;??**????????????????????????**???????????????????????????????**??*******************************************************************************/??/*?包含頭文件?*****************************************************************/??#include?"ds1302.h"??#include?"stdio.h"??#include?"Delay.h"????uint8_t?read[]?=?{0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//讀秒、分、時、日、月、周、年的寄存器地址??uint8_t?write[]?=?{0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//寫秒、分、時、日、月、周、年的寄存器地址??/*PA4、PA6為輸出*/??/*PA5配置為開漏模式,此模式下能夠實現真正的雙向IO口*/??void?ds1302_GPIO_Configuration(void)??{??????GPIO_InitTypeDef?GPIO_InitStruct;????????GPIO_InitStruct.GPIO_Mode?=?GPIO_Mode_Out_PP;??????GPIO_InitStruct.GPIO_Pin?=?ds1302clk|ds1302rst;?????????//clk、rst配置為輸出??????GPIO_InitStruct.GPIO_Speed?=?GPIO_Speed_50MHz;??????GPIO_Init(GPIOA,?&GPIO_InitStruct);????????GPIO_InitStruct.GPIO_Mode?=?GPIO_Mode_Out_OD;???????????????//IO配置為雙向??????GPIO_InitStruct.GPIO_Pin?=?ds1302dat;??????GPIO_Init(GPIOA,?&GPIO_InitStruct);????}????void?write_1302byte(uint8_t?dat)????????????????????????????????????????????//寫一個字節的數據sck上升沿寫數據??{??????uint8_t?i?=?0;??????GPIO_ResetBits(GPIOA,ds1302clk);????????????????????????????????????????//ds1302clk=0??????????Delay_us(2);//延時大約2us????????????for(i?=?0;i?<?8;i?++)??????????{??????????????GPIO_ResetBits(GPIOA,ds1302clk);????????????????????????????//ds1302clk=0;??????????????if(dat&0x01)??????????????????GPIO_SetBits(GPIOA,ds1302dat);??????????????else????????????????????????????????????????????????????????????????????????????????????????//ds1302dat=(dat&0x01)??????????????????GPIO_ResetBits(GPIOA,ds1302dat);??????????????????????????????Delay_us(2);??????????????GPIO_SetBits(GPIOA,ds1302clk);??????????????????????????????????//發送一位數據,clk上升沿,//ds1302clk=1??????????????dat?>>=?1;??????????????Delay_us(1);??????????}?????????}????????uint8_t?read_1302(uint8_t?add)??????????????????????????????????????????????//讀數據??{??????uint8_t?i=0;??????uint8_t?Return_dat=0x00;??????GPIO_ResetBits(GPIOA,ds1302rst);????????????????????????????????????//ds1302rst=0;??????GPIO_ResetBits(GPIOA,ds1302clk);????????????????????????????????????????//ds1302clk=0;??????Delay_us(3);????????????????????????????????????????????????????????????????????????????????//略微延時2us??????GPIO_SetBits(GPIOA,ds1302rst);??????????????????????????????????????//ds1302rst=1;??????Delay_us(3);????????????????????????????????????????????????????????????????????????????????//時間要大約3us??????write_1302byte(add);????????????????????????????????????????????????????????????????//先寫寄存器的地址??????for(i=0;i<8;i++)??????{??????????GPIO_SetBits(GPIOA,ds1302clk);??????????????????????????????????????//ds1302clk=1;??????????Return_dat?>>=?1;??????????GPIO_ResetBits(GPIOA,ds1302clk);????????????????????????????????????//ds1302clk=0;//拉低時鐘線,以便于數據的讀入??????????if(GPIO_ReadInputDataBit(GPIOA,ds1302dat)==1)???????????//數據線此時為高電平??????????{Return_dat?=?Return_dat|0x80;}??????}????????Delay_us(1);????????GPIO_ResetBits(GPIOA,ds1302rst);????????????????????????????????//ds1302rst=0;釋放總線????????return?Return_dat;??????}??void?write_1302(uint8_t?add,uint8_t?dat)????????????????????????????//向指定寄存器寫入一個字節的數據??{??????GPIO_ResetBits(GPIOA,ds1302rst);????????????????????????????????????????//只有在rst為高電平的時候才能進行數據傳輸??????GPIO_ResetBits(GPIOA,ds1302clk);????????????????????????????????????????//只有clk為低電平的時候,rst才能被置為高電平??????//ds1302rst=0;??????//ds1302clk=0;??????Delay_us(1);????????????????????????????????????????????????????????????????????????????????//略微延時??????GPIO_SetBits(GPIOA,ds1302rst);??????????????????????????????????????????//clk?=?0之后,這里將rst拉高,準備傳送數據??????//ds1302rst=1;??????Delay_us(2);????????????????????????????????????????????????????????????????????????????????//時間大約2us??????write_1302byte(add);????????????????????????????????????????????????????????????????//先發地址??????write_1302byte(dat);????????????????????????????????????????????????????????????????//然后發數據??????GPIO_ResetBits(GPIOA,ds1302rst);????????????????????????????????????????//這里釋放總線??????GPIO_ResetBits(GPIOA,ds1302clk);????????????????????????????????????????//拉低clk,以備下一次數據發送??????//ds1302clk=0;??????//ds1302rst=0;??????Delay_us(1);????}??void?ds1302_init(uint8_t?*write,uint8_t?*time)??????????????//初始化1302??{??????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);??????????????????????????????????????????????????????//打開寫保護??}??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;?????????????????????????????????????????????????????????????//秒十位數據??????}??????//此時已轉換成10進制數,g[i]里面存放的是秒分時日月周年的各個位數據??????//而此時的time[i]存放的是十位數據????????????????????????????????//if(s?!=?(time[0]+g[0]))??????printf("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]);????????//s?=?time[0]+g[0];?????}??
就是這樣的簡單,然后給出一張效果圖
總結
以上是生活随笔為你收集整理的基于stm32f103zet6的DS1302学习的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。