基于stm32f103zet6的DS1302学习

由于硬件出了问题,也就是外部低速晶振没用,震不起来,然后查看了网上的帖子,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 <-> 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);																							//这个得加,不然的话会有尾巴是乱码!!!
}

/*******************************************************************************
** 文件名称 : 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];	
}
就是这样的简单,然后给出一张效果图


  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
stm32f103zet6是一款由意法半导体(STMicroelectronics)公司推出的32位ARM Cortex-M3内核的微控制器。它内置有大容量闪存和SRAM,并支持多种外设接口,例如通用串行总线(USART)、SPI、I2C等,能够广泛应用于各种嵌入式系统中。 ds1302是一种低功耗实时时钟(RTC)芯片,能够提供精确的时间和日期信息。它采用数字式时钟和31个字节的静态RAM,支持连续时钟运行和多种时钟计数模式。ds1302通过一组并行接口与微控制器通信,实现时间信息的读取和设置。 在stm32f103zet6ds1302的原理图中,会包括它们之间的电路连接和接口通信。通常会使用GPIO(通用输入输出)引脚来实现通信,例如使用串行外设接口(SPI)或I2C总线进行数据传输。 具体来说,在原理图中,stm32f103zet6的GPIO引脚和ds1302的对应引脚之间会有连接线,以实现它们之间的通信。例如,可以使用SPI总线,将stm32f103zet6的SPI引脚与ds1302的SCLK(时钟)、SDI(数据输入)和SDO(数据输出)引脚相连。通过串行通信,stm32f103zet6可以读取和设置ds1302的时间和日期信息。 除了通信接口,原理图中还会包括其他必要的电路,如时钟电路、电源电路等。这些电路起到支持和保护芯片正常运行的作用。 通过这样的原理图设计,stm32f103zet6ds1302可以进行互相通信,实现精确的时间和日期信息的获取和设置,为嵌入式系统提供时间基准。这些信息在很多应用中都非常重要,如日历、实时数据采集等,并且能够为系统的功能提供更强的实时性。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值