【DS1302驱动】

news/2024/11/23 9:25:35/

DS1302ZN+ 实时时钟芯片驱动

正文

最近使用了DS1302ZN+ 实时时钟芯片,浅浅分享一下我写的驱动。代码也是从其他的博主那改过来的,只是将格式和一些小细节优化了一下。具体的原理懒得写了,其他博主那有很详细的。

说明

使用的平台的STM32F103,用的标准库,用IO口模拟通信时序与DS1302进行通讯。
1、如果你同样是准备移植到STM32上,并且准备使用标准库,只需要在H文件中修改对应的引脚,然后对接一下C文件中的delay_us、delay_ms这两个函数即可。
2、如果你准备移植到别的地方,那在1的基础上你还可能还需要更改一下 ds1302_gpio_init 、 ds1032_DATAOUT_init、ds1032_DATAINPUT_init 的引脚初始化;甚至H文件中下图所示的部分也需要对应修改:
H文件截图
3、在移植的时候C文件中的这个地方注意一下,读引脚电平的函数也需要自己对应修改,而且不容易发现,是一个小坑。
C文件截图

好嘞,该文章仅供参考,不严谨请多包涵。上代码:

H文件

#ifndef __DS1302_H
#define __DS1302_H/************管脚配置**************/
//  CE 配置 
#define DS1302_CE_RCC   RCC_APB2Periph_GPIOA
#define DS1302_CE_PORT	GPIOA			  	    													  
#define DS1302_CE_PIN	GPIO_Pin_5
//  SCLK 配置
#define DS1302_SCLK_RCC   RCC_APB2Periph_GPIOA
#define DS1302_SCLK_PORT  GPIOA			  	    													  
#define DS1302_SCLK_PIN	  GPIO_Pin_7
//  I/O 配置
#define DS1302_DATA_RCC   RCC_APB2Periph_GPIOA
#define DS1302_DATA_PORT  GPIOA			  	    													  
#define DS1302_DATA_PIN	  GPIO_Pin_6#define CE_L     GPIO_ResetBits(DS1302_CE_PORT,DS1302_CE_PIN)     //拉低使能位
#define CE_H     GPIO_SetBits(DS1302_CE_PORT,DS1302_CE_PIN)       //拉高使能位
#define SCLK_L   GPIO_ResetBits(DS1302_SCLK_PORT,DS1302_SCLK_PIN) //拉低时钟线
#define SCLK_H   GPIO_SetBits(DS1302_SCLK_PORT,DS1302_SCLK_PIN)   //拉高时钟线
#define DATA_L   GPIO_ResetBits(DS1302_DATA_PORT,DS1302_DATA_PIN) //拉低数据线
#define DATA_H   GPIO_SetBits(DS1302_DATA_PORT,DS1302_DATA_PIN)   //拉高数据线//创建TIMEData数据结构方便存储时间日期数据
typedef struct    
{uint16_t year;uint8_t  month;uint8_t  day;uint8_t  hour;uint8_t  minute;uint8_t  second;uint8_t  week;
}TIMEData;extern TIMEData TimeData;             //全局变量extern void ds1032_init(void);              //ds1302初始化函数
extern void ds1302_gpio_init(void);         //ds1302端口初始化
extern TIMEData ds1032_read_realTime(void); //获取当前时间
extern void ds1302_wirte_rig(uint8_t address,uint8_t data);//向指定寄存器写一字节数据
extern uint8_t ds1302_read_rig(uint8_t address);           //从指定寄存器读一字节数据#endif

C文件

#include "systick.h"
#include "stm32f10x.h"
#include "ds1302.h"TIMEData TimeData;    //定义一个存放时间数据的变量TimeData/**********************************************************************************************************
*	函 数 名:  ds1302_gpio_init
*	功能说明:  初始化DS1302的CE和SCLK引脚
*	形    参:  无
*	返 回 值:  无
**********************************************************************************************************/
void ds1302_gpio_init(void) //CE,SCLK端口初始化
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(DS1302_CE_RCC, ENABLE);GPIO_InitStructure.GPIO_Pin = DS1302_CE_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(DS1302_CE_PORT, &GPIO_InitStructure);GPIO_ResetBits(DS1302_CE_PORT,DS1302_CE_PIN); RCC_APB2PeriphClockCmd(DS1302_SCLK_RCC, ENABLE);GPIO_InitStructure.GPIO_Pin = DS1302_SCLK_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(DS1302_SCLK_PORT, &GPIO_InitStructure);GPIO_ResetBits(DS1302_SCLK_PORT,DS1302_SCLK_PIN); 
}/**********************************************************************************************************
*	函 数 名:  ds1032_DATAOUT_init
*	功能说明:  将DS1302的数据引脚配置为输出
*	形    参:  无
*	返 回 值:  无
**********************************************************************************************************/
void ds1032_DATAOUT_init(void) 
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(DS1302_DATA_RCC, ENABLE);GPIO_InitStructure.GPIO_Pin = DS1302_DATA_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(DS1302_DATA_PORT, &GPIO_InitStructure);GPIO_ResetBits(DS1302_DATA_PORT,DS1302_DATA_PIN);
}/**********************************************************************************************************
*	函 数 名:  ds1032_DATAINPUT_init
*	功能说明:  将DS1302的数据引脚配置为输入
*	形    参:  无
*	返 回 值:  无
*   注      :  无
**********************************************************************************************************/
void ds1032_DATAINPUT_init(void)//配置双向I/O端口为输入态
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(DS1302_DATA_RCC, ENABLE);GPIO_InitStructure.GPIO_Pin = DS1302_DATA_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(DS1302_DATA_PORT, &GPIO_InitStructure);
}/**********************************************************************************************************
*	函 数 名:  ds1302_write_onebyte
*	功能说明:  向DS1302发送一字节数据
*	形    参:  data 要发送的数据
*	返 回 值:  无
*     注    :  被读写DS1302寄存器的函数调用
**********************************************************************************************************/
void ds1302_write_onebyte(uint8_t data)
{ds1032_DATAOUT_init(); //配置数据引脚为输出uint8_t count=0;SCLK_L;for(count=0;count<8;count++){	SCLK_L;      //拉高时钟线if(data&0x01)  DATA_H;else           DATA_L; SCLK_H;      //拉高时钟线,发送数据data>>=1;}
}/**********************************************************************************************************
*	函 数 名:  ds1302_wirte_rig
*	功能说明:  向指定寄存器地址写数据
*	形    参:  address:要写的寄存器地址  data:要发送的数据
*	返 回 值:  无
**********************************************************************************************************/
void ds1302_wirte_rig(uint8_t address,uint8_t data)
{uint8_t temp1=address;uint8_t temp2=data;CE_L;SCLK_L;delay_us(1);CE_H;delay_us(2);ds1302_write_onebyte(temp1); //写地址ds1302_write_onebyte(temp2); //写数据CE_L;SCLK_L;delay_us(2);
}/**********************************************************************************************************
*	函 数 名:  ds1302_read_rig
*	功能说明:  读取指定寄存器的一字节数据
*	形    参:  address:要读的寄存器地址
*	返 回 值:  读到的数据
**********************************************************************************************************/
uint8_t ds1302_read_rig(uint8_t address)
{uint8_t temp3=address;uint8_t count=0;uint8_t return_data=0x00;CE_L;SCLK_L;delay_us(3);CE_H;delay_us(3);ds1302_write_onebyte(temp3);//写寄存器地址ds1032_DATAINPUT_init();    //配置数据引脚为输入delay_us(2);for(count=0;count<8;count++){delay_us(2);        //使电平持续一段时间return_data>>=1;    //将数据移位保存SCLK_H;delay_us(4); //使高电平持续一段时间SCLK_L;delay_us(14);//延时14us后再去读取电平,更加准确if(GPIO_ReadInputDataBit(DS1302_DATA_PORT,DS1302_DATA_PIN)) //读取数据引脚的电平return_data=return_data|0x80;                           //记录数据		}delay_us(2);CE_L;DATA_L;return return_data;
}/**********************************************************************************************************
*	函 数 名:  ds1032_SetTime
*	功能说明:  更改DS1302的当前时间
*	形    参:  year: 年份    mon: 月份	 date: 日期	 hours:小时   min:分钟  sec:秒钟   week:星期
*	返 回 值:  无
*     注    :  形参为(0x22,0x06,0x30,0x17,0x30,0x25,0x04)  即设置当前时间为 2022-06-30-17:30-25秒-星期四
**********************************************************************************************************/
void ds1032_SetTime(uint8_t year,uint8_t mon,uint8_t date,uint8_t hours,uint8_t min,uint8_t sec,uint8_t week)
{ds1302_wirte_rig(0x8e,0x00); //关闭写保护ds1302_wirte_rig(0x80,sec);  //sec    ds1302_wirte_rig(0x82,min);  //min    ds1302_wirte_rig(0x84,hours);//hours  ds1302_wirte_rig(0x86,date); //date   ds1302_wirte_rig(0x88,mon);  //mon    ds1302_wirte_rig(0x8a,week); //week   ds1302_wirte_rig(0x8c,year); //year   ds1302_wirte_rig(0x8e,0x80); //关闭写保护
}/**********************************************************************************************************
*	函 数 名:  ds1032_read_time
*	功能说明:  读取当前的时间(BCD格式)
*	形    参:  无
*	返 回 值:  无
**********************************************************************************************************/
TIMEData ds1032_read_realTime(void)
{TIMEData time;        //暂时保存时间数据uint8_t read_time[7]; //暂时保存BCD格式的时间数据 //读取BCD格式的时间数据read_time[0]=ds1302_read_rig(0x81);//读秒read_time[1]=ds1302_read_rig(0x83);//读分read_time[2]=ds1302_read_rig(0x85);//读时read_time[3]=ds1302_read_rig(0x87);//读日read_time[4]=ds1302_read_rig(0x89);//读月read_time[5]=ds1302_read_rig(0x8B);//读星期read_time[6]=ds1302_read_rig(0x8D);//读年 //BCD码转换为10进制time.second=(read_time[0]>>4)*10+(read_time[0]&0x0f);time.minute=((read_time[1]>>4)&(0x07))*10+(read_time[1]&0x0f);time.hour  =(read_time[2]>>4)*10+(read_time[2]&0x0f);time.day   =(read_time[3]>>4)*10+(read_time[3]&0x0f);time.month =(read_time[4]>>4)*10+(read_time[4]&0x0f);time.week  =read_time[5];time.year  =(read_time[6]>>4)*10+(read_time[6]&0x0f)+2000;return time;
}void ds1032_init(void)
{ds1302_gpio_init(); //初始化ds1302端口delay_ms(5); //	ds1032_SetTime(0x22,0x06,0x30,0x17,0x30,0x25,0x04);//设置时间为:2022-06-30-17:30-25秒-星期四delay_ms(5);      
}

http://www.ppmy.cn/news/200352.html

相关文章

常见摄像头接口USB、DVP、MIPI接口的对比

常见摄像头接口DVP、MIPI、USB的比较 引言 摄像头传感器已经广泛用于嵌入式设备了&#xff0c;现在的手机很多都支持多个摄像头。 在物联网领域&#xff0c;摄像头传感器也越来越被广泛使用。今天就来简单聊一聊几种常见的摄像头接口。 传感器与主控设备进行通信&#xff0…

Windows安装Dolby Vision 杜比视界插件

前言 使用普通的播放器播放杜比视界视频时会出现发紫和发绿&#xff0c;两者来回切换的情况&#xff0c;要么使用专门的播放器&#xff0c;要么使用Windows自带播放器加上安装相应拓展 在使用Windows自带的“电影和电视”播放杜比视界(Dolby Vision)的视频时&#xff0c;需要安…

DCMI接口之OV2640摄像头

一、OV2640简介 OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA&#xff08;1632 * 1232&#xff09;图像传感器。该传感器体积小、工作电压低&#xff0c;提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB 总线控制&#xff0c;可以输出整帧、子采样、缩放和取窗口等…

DV2020T 综合

在这里插入代码片//audio内存泄漏 //audio pts //ENCInterface.h //绿条 //没有设备时崩 //接口 //如何把硬件编码对接webrtc中 //video/audio开启或关闭 //码率分辨率帧率控制 //导播离开房间重进房间 网络中途断开socket.io重连&#xff0c;srs->close 重联成功srs->st…

基于android的条码识别技术,基于Android手机的条码识别系统研究

摘要&#xff1a; 当前,条码技术在商品管理、生产自动化、邮政系统、交通运输等领域得到了广泛的应用。与此同时,随着网络信息技术的发展,尤其是近几年以智能手机为代表的智能终端设备的兴起,移动互联网获得了蓬勃发展,为条码技术提供了新的发展机遇和更大的发展空间,从而为促进…

4g android 手机排行榜,全球最结实的4G安卓手机开卖

致力于打造结实手机的制造商Sonim发起了一项Indiegogo众筹活动&#xff0c;这个活动的主角是Sonim XP7 Extreme新款智能手机。这款手机被称为“全球最结实的LTE安卓智能手机”&#xff0c;用户群体是运动爱好者&#xff0c;号称是滑雪、爬山、自行车骑行、钓鱼、徒步远行划船等…

条码防伪检测技术介绍,如何通过扫描商品条码判断产品的真伪-鸿顺捷条码防伪技术介绍

条码防伪检测技术的典型应用 经常有人问:如何通过条形码判断一个产品的真伪&#xff1f;(此处条形码应指商品代码) 这可能是对条形码功能的误解。一般来说&#xff0c;不能单纯通过商品上的条形码来判断商品的真伪。 商品编码是国家为使商品在公开市场(如商场、超市)上能被公开…

制作条形码的手机App推荐

条形码自发明以来&#xff0c;给我们的生活带来极大便利&#xff0c;怎么才能快速的用手机创建条形码呢&#xff1f;下面就给大家介绍一款小编常用的制作条形码的App–二维码和条形码生成器。使用它&#xff0c;不仅可以制作条形码、制作二维码&#xff0c;还能快速扫描二维码和…