基于stm32f103zet6的DS1302学习

来源:互联网 发布:php curl post 图片流 编辑:程序博客网 时间:2024/05/17 09:13

由于硬件出了问题,也就是外部低速晶振没用,震不起来,然后查看了网上的帖子,STM32的RTC果然口碑不怎么样,所以果断换DS1302,在移植的过程中还算顺利,记录下来吧,也算对自己的总结吧!

1、所谓的DS1302


这里面也指明了简单的SPI协议

然后就直接上代码了,注释很详细的!基本实现单行注释

1、主函数main

#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 <-> PA4ds1302dat <-> PA5ds1302rst <-> 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();//一定别忘记了配置GPIOprintf("\r\n ("__DATE__ " - " __TIME__ ") \r\n");//ds1302_init(write,time);//设置1302的初始时间ds1302_data(read);while(1);//这个得加,不然的话会有尾巴是乱码!!!}

/********************************************************************************* 文件名称 : 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);//略微延时2usGPIO_SetBits(GPIOA,ds1302rst);  //ds1302rst=1;Delay_us(3);//时间要大约3uswrite_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);//时间大约2uswrite_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];}
就是这样的简单,然后给出一张效果图