ds1302程序-stm32
- 格式:docx
- 大小:21.69 KB
- 文档页数:18
#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit LCD1602_E=P3^6;sbit LCD1602_RW=P3^5;sbit LCD1602_RS=P3^4;sbit DSIO=P0^7;sbit RST=P0^5;sbit SCLK=P0^6;extern uchar TIME[7];void Ds1302Write(uchar addr, uchar dat);uchar Ds1302Read(uchar addr);void Ds1302Init();void Ds1302ReadTime();void Lcd1602_Delay1ms(uint c); //误差0usvoid LcdWriteCom(uchar com);void LcdWriteData(uchar dat) ;void LcdInit();void LcdDisplay();uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13};void main(){LcdInit();Ds1302Init();while(1){Ds1302ReadTime();LcdDisplay();}}void Ds1302Write(uchar addr, uchar dat){uchar n;RST = 0;_nop_();SCLK = 0;//先将SCLK置低电平。
stm32驱动DS1302//DS1302.H#ifndef __DS1302_H#define __DS1302_H#include "stm32f10x.h"//*****************DS1302控制命令*******************#define RdSec 0x81#define RdMin 0x83#define RdHour 0x85#define RdDate 0x87#define RdMonth 0x89#define RdWeek 0x8b#define RdYear 0x8d#define RdControl 0x8f#define RdTrickleCharge 0x91#define RdClockBurst 0xbf#define WrSec 0x80#define WrMin 0x82#define WrHour 0x84#define WrDate 0x86#define WrMonth 0x88#define WrWeek 0x8a#define WrYear 0x8c#define WrControl 0x8e#define WrTrickleCharge 0x90#define WrClockBurst 0xbe//对应IO口配置#define DS1302_IORCC RCC_APB2Periph_GPIOC //DS18B20对应IO的时钟#define DS1302_PORT GPIOC#define DS1302_SCK_PIN GPIO_Pin_15 //定义DS18B20对应的IO口#define DS1302_IO_PIN GPIO_Pin_13#define DS1302_CE_PIN GPIO_Pin_14#define DS1302_CLRSCK() (GPIOC->BRR = DS1302_SCK_PIN) //寄存器操作IO状态#define DS1302_SETSCK() (GPIOC->BSRR = DS1302_SCK_PIN)#define DS1302_CLRIO() (GPIOC->BRR = DS1302_IO_PIN)#define DS1302_SETIO() (GPIOC->BSRR = DS1302_IO_PIN) #define DS1302_CLRCE() (GPIOC->BRR = DS1302_CE_PIN)#define DS1302_SETCE() (GPIOC->BSRR = DS1302_CE_PIN) #define DS1302_READ_SDA() (GPIO_ReadInputDataBit(DS1302_PORT, DS1302_IO_PIN)) //定义时间的结构体typedef struct{u8 year;u8 month;u8 date;u8 week;u8 hour;u8 min;u8 sec;}TIME_TypeDef;//内部函数void DS1302_Write8bit(u8 code);u8 DS1302_Read8bit(void);//外部函数void delay_us(u8 us);void RTC_init (void);u8 DS1302_ReadByte(u8 con);void DS1302_WriteByte(u8 con,u8 code);void DS1302_WrintTime(TIME_TypeDef* time);void DS1302_ReadTime(TIME_TypeDef* time);void DS1302_IO_OUT(void);void DS1302_IO_IN(void);u8 NumT oBCD(u8 Num);u8 BCDT oNum(u8 BCD);void time_set();#endif /* __DS1302_H *///DS1302.C#include "stm32f10x.h"#include "DS1302.h"TIME_TypeDef rtc_time={0};//DS1302初始化函数void RTC_init (void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(DS1302_IORCC, ENABLE );GPIO_InitStructure.GPIO_Pin = (DS1302_SCK_PIN | DS1302_IO_PIN | DS1302_CE_PIN);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init(DS1302_PORT, &GPIO_InitStructure);DS1302_WriteByte(WrControl,0x00); //关闭写保护,可以写入数据delay_us(10);if(DS1302_ReadByte(RdTrickleCharge) != 0xA6){delay_us(10);DS1302_WriteByte(WrTrickleCharge,0xA6);}delay_us(10);DS1302_WriteByte(WrControl,0x80); //开启写保护,禁止写入数据}//DS1302?8bitvoid DS1302_Write8bit(u8 code){u8 i;DS1302_IO_OUT();DS1302_CLRSCK();for(i=0;i<8;i++){delay_us(5);if(code&0x01) (DS1302_SETIO());else (DS1302_CLRIO());delay_us(5);DS1302_SETSCK();delay_us(5);DS1302_CLRSCK();code = code >> 1;}}//DS1302?8bitu8 DS1302_Read8bit(void){u8 i,code;DS1302_IO_IN();code=0;DS1302_CLRSCK();delay_us(5);for(i=0;i<8;i++){code = code >>1;if(DS1302_READ_SDA()) code = code|0x80; delay_us(5);DS1302_SETSCK();delay_us(5);DS1302_CLRSCK();}return code;}//读DS1302指定的1Byteu8 DS1302_ReadByte(u8 con){u8 code;DS1302_CLRCE(); //关闭DS1302delay_us(5);DS1302_CLRSCK();delay_us(5);//DS13CLK =0;DS1302_SETCE(); //使能DS1302delay_us(5);DS1302_Write8bit(con); //读代码code=DS1302_Read8bit(); //返回读取的数字delay_us(5);DS1302_SETSCK();delay_us(5);DS1302_CLRCE(); //关闭DS1302return code;}//?DS13021Bytevoid DS1302_WriteByte(u8 con,u8 code){DS1302_CLRCE(); //关闭DS1302delay_us(5);DS1302_CLRSCK();delay_us(5);//DS13CLK =0;DS1302_SETCE(); //使能DS1302delay_us(5);DS1302_Write8bit(con); //写控制命令DS1302_Write8bit(code); //写入数据delay_us(5);DS1302_SETSCK();delay_us(5);DS1302_CLRCE(); //关闭DS1302}//写入时间void DS1302_WrintTime(TIME_TypeDef* time) {DS1302_WriteByte(WrControl,0x00); //关闭写保护DS1302_WriteByte(WrYear,time->year);DS1302_WriteByte(WrMonth,time->month); DS1302_WriteByte(WrDate,time->date);DS1302_WriteByte(WrWeek,time->week);DS1302_WriteByte(WrHour,time->hour);DS1302_WriteByte(WrMin,time->min);DS1302_WriteByte(WrSec,time->sec);DS1302_WriteByte(WrControl,0x80); //开启写保护,禁止写入数据}//读出时间void DS1302_ReadTime(TIME_TypeDef* time){time->year = DS1302_ReadByte(RdYear);time->month = DS1302_ReadByte(RdMonth);time->date = DS1302_ReadByte(RdDate);time->week = DS1302_ReadByte(RdWeek);time->hour = DS1302_ReadByte(RdHour);time->min = DS1302_ReadByte(RdMin);time->sec = DS1302_ReadByte(RdSec);}void delay_us(u8 us){while(us--){__NOP();}}void DS1302_IO_OUT(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DS1302_IO_PIN ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init(DS1302_PORT, &GPIO_InitStructure);void DS1302_IO_IN(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DS1302_IO_PIN ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init(DS1302_PORT, &GPIO_InitStructure);}//**数值转化为BCD码u8 NumT oBCD(u8 Num){return (Num/10)<<4 | (Num%10);}//***BCD码转化为数值u8 BCDT oNum(u8 BCD){return ((BCD&0x70)>>4)*10 + (BCD&0x0F);}void time_set(){rtc_time.year=NumToBCD(14);rtc_time.month=NumT oBCD(3);rtc_time.date=NumToBCD(12);rtc_time.hour=NumToBCD(21);rtc_time.min=NumToBCD(23);rtc_time.week=NumToBCD(3);rtc_time.sec=NumToBCD(30);DS1302_WrintTime(&rtc_time);// DS1302_ReadTime(&rtc_time);// rt_kprintf("20%d年%d月%d日星期%d\r\n",BCDT oNum(rtc_time.year),BCDToNum(rtc_time.month ),BCDT oNum(rtc_time.date),r tc_time.week);//rt_kprintf("%d : %d : %d\r\n",BCDT oNum(rtc_time.hour),BCD ToNum(rtc_time.min),BCDToNu m(rtc_time.sec));// rt_thread_delay( RT_TICK_PER_SECOND*5); /* sleep 0.5 second and switch to other thread */。
/******************************************************************************* File name --> <strong><font color="#FF0000">ds1302</font></strong>.c * Author--> By Sam Chan* Version--> V1.0* Date--> 08 - 23 - 2012* Brief--> 时钟芯片DS1302驱动** Copyright (C) 20*** All rights reserved*********************************************************************************File Update* Version--> V1.0.1* Author--> By Sam Chan* Date--> 10 - 20 - 2013* Revise--> A、增加对STM32控制的移植支持* --> B、增加对内置的RAM操作相关函数* --> C、增加检测DS1302是否存在,是否第一次上电检测函数* --> D、增加对DS1302内置的锂电池充电寄存器参数设置函数和结构体*******************************************************************************/#include "ds1302.h"/******************************************************************************定义变量******************************************************************************/#define Date TimeValue.date#define Min TimeValue.minute#define Sec TimeValue.second#define Hour TimeValue.hour#define Week TimeValue.week#define Month TimeValue.month#define Year TimeValue.yearTime_Typedef TimeValue;//定义时间数据指针void Time_Init(){TimeValue.date=24;TimeValue.hour=6;TimeValue.minute=12;TimeValue.month=5;TimeValue.second=0;TimeValue.week=2;TimeValue.year=16;}Charge_Typedef ChargeValue;//定义充电寄存器/******************************************************************************* Function Name --> GPIO初始化* Description--> none* Input--> none* Output--> none* Reaturn--> none******************************************************************************/void DS1302_GPIOInit(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//开启GPIOC外设时钟/*初始化GPIOC*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);}/******************************************************************************* Function Name --> DS1302写入一个字节数据* Description--> none* Input--> dat:要写入的数据* Output--> none* Reaturn--> none******************************************************************************/void DS1302_Write_Byte(u8 dat){u8 i;DS1302_SDA_OUT();//设置为输出口for(i=0;i<8;i++){DS1302_SCL = 0;//时钟线拉低if(dat & 0x01)DS1302_SDA = 1;//数据线放上数据,先发低位else DS1302_SDA = 0;dat >>= 1;//数据右移一位DS1302_SCL = 1;//发送数据,上升沿有效}}/****************************************************************************** * Function Name --> DS1302读出一个字节数据* Description--> none* Input--> none* Output--> none* Reaturn--> 读到的数据******************************************************************************/ unsigned DS1302_Read_Byte(){u8 ReData=0x00;u8 i;DS1302_SDA_IN();//设置为输入口for(i=0;i<8;i++){if(DS1302_IN_SDA == 1){ReData |= 0x80;}//读出一位数据是“1”DS1302_SCL = 0;//时钟线拉低ReData >>= 1;//数据右移一位,先读取低位,数据补“0”DS1302_SCL = 1;//上升沿读取数据}return(ReData);//返回读取到的数据}/****************************************************************************** * Function Name --> 向DS1302某地址写入数据* Description--> none* Input--> add:要操作的地址*dat:要写入的数据* Output--> none* Reaturn--> none******************************************************************************/ void DS1302_Write_Data(u8 add,u8 dat){DS1302_RST = 0;//复位脚拉低DS1302_SCL = 0;//时钟线拉低DS1302_RST = 1;//复位脚拉高DS1302_Write_Byte(add);//写入要操作地址DS1302_Write_Byte(dat);//写入数据//delay_us(5);DS1302_RST = 0;DS1302_SCL = 0;}/******************************************************************************* Function Name --> 从DS1302某地址读取数据* Description--> none* Input--> add:要操作的地址* Output--> none* Reaturn--> 要读取的寄存器的数值******************************************************************************/unsigned DS1302_Read_Data(u8 add){u8 Temp;DS1302_RST = 1;DS1302_Write_Byte(add);//写入要操作地址Temp = DS1302_Read_Byte();//开始读取数据DS1302_RST = 0;return(Temp);//返回读取到的数据}/******************************************************************************* Function Name --> 主电源对备用电池充电设置* Description--> 如果备用电池接的是可充电的锂电池或者其他可充电电池的时候,*可以打开DS1302的充电电路,利用主供电对电池进行充电,免的换电池的麻烦* Input--> *CHG_dat:寄存器控制指针* Output--> none* Reaturn--> none******************************************************************************/void DS1302_Charge_Manage(Charge_Typedef* CHG_dat){u8 CHG_Value;CHG_Value = (CHG_dat->TCSx << 4) | (CHG_dat->DSx << 2) | CHG_dat->RSx;DS1302_WP_Disable();//取消写保护DS1302_Write_Data(Trickle_Charger_Address,CHG_Value);DS1302_WP_Enable();//打开写保护}/******************************************************************************* Function Name --> DS1302内置的RAM读写操作* Description--> none* Input--> *pBuff:读写数据存放区*WRadd:读写起始地址,范围在RAM_Address0 ~ RAM_Address28之间,最后一位地址有其他用途*num:读写字节数据的数量,范围在1 ~ 28之间*RW:读写判断位。
/****************************************************************************** * @ File name --> <strong><font color="#FF0000">ds1302</font></strong>.c* @ Author --> By@ Sam Chan* @ Version --> V1.0* @ Date --> 08 - 23 - 2012* @ Brief --> 时钟芯片DS1302驱动** @ Copyright (C) 20*** @ All rights reserved******************************************************************************* ** File Update* @ Version --> V1.0.1* @ Author --> By@ Sam Chan* @ Date --> 10 - 20 - 2013* @ Revise --> A、增加对STM32控制的移植支持* @ --> B、增加对内置的RAM操作相关函数* @ --> C、增加检测DS1302是否存在,是否第一次上电检测函数* @ --> D、增加对DS1302内置的锂电池充电寄存器参数设置函数和结构体*******************************************************************************/ #include "ds1302.h"/****************************************************************************** 定义变量******************************************************************************/ #define Date TimeValue.date#define Min TimeValue.minute#define Sec TimeValue.second#define Hour TimeValue.hour#define Week TimeValue.week#define Month TimeValue.month#define Year TimeValue.yearTime_Typedef TimeValue; //定义时间数据指针void Time_Init(){TimeValue.date=24;TimeValue.hour=6;TimeValue.minute=12;TimeValue.month=5;TimeValue.second=0;TimeValue.week=2;TimeValue.year=16;}Charge_Typedef ChargeValue; //定义充电寄存器/****************************************************************************** * Function Name --> GPIO初始化* Description --> none* Input --> none* Output --> none* Reaturn --> none******************************************************************************/void DS1302_GPIOInit(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //开启GPIOC外设时钟/* 初始化GPIOC */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);}/****************************************************************************** * Function Name --> DS1302写入一个字节数据* Description --> none* Input --> dat:要写入的数据* Output --> none* Reaturn --> none******************************************************************************/ void DS1302_Write_Byte(u8 dat){u8 i;DS1302_SDA_OUT(); //设置为输出口for(i=0;i<8;i++){DS1302_SCL = 0; //时钟线拉低if(dat & 0x01) DS1302_SDA = 1; //数据线放上数据,先发低位else DS1302_SDA = 0;dat >>= 1; //数据右移一位DS1302_SCL = 1; //发送数据,上升沿有效}}/****************************************************************************** * Function Name --> DS1302读出一个字节数据* Description --> none* Input --> none* Output --> none* Reaturn --> 读到的数据******************************************************************************/ unsigned DS1302_Read_Byte(){u8 ReData=0x00;u8 i;DS1302_SDA_IN(); //设置为输入口for(i=0;i<8;i++){if(DS1302_IN_SDA == 1){ ReData |= 0x80; } //读出一位数据是“1”DS1302_SCL = 0; //时钟线拉低ReData >>= 1; //数据右移一位,先读取低位,数据补“0”DS1302_SCL = 1; //上升沿读取数据}return(ReData); //返回读取到的数据}/****************************************************************************** * Function Name --> 向DS1302某地址写入数据* Description --> none* Input --> add:要操作的地址* dat:要写入的数据* Output --> none* Reaturn --> none******************************************************************************/ void DS1302_Write_Data(u8 add,u8 dat){DS1302_RST = 0; //复位脚拉低DS1302_SCL = 0; //时钟线拉低DS1302_RST = 1; //复位脚拉高DS1302_Write_Byte(add); //写入要操作地址DS1302_Write_Byte(dat); //写入数据//delay_us(5);DS1302_RST = 0;DS1302_SCL = 0;}* Function Name --> 从DS1302某地址读取数据* Description --> none* Input --> add:要操作的地址* Output --> none* Reaturn --> 要读取的寄存器的数值******************************************************************************/ unsigned DS1302_Read_Data(u8 add){u8 Temp;DS1302_RST = 1;DS1302_Write_Byte(add); //写入要操作地址Temp = DS1302_Read_Byte(); //开始读取数据DS1302_RST = 0;return(Temp); //返回读取到的数据}/****************************************************************************** * Function Name --> 主电源对备用电池充电设置* Description --> 如果备用电池接的是可充电的锂电池或者其他可充电电池的时候,* 可以打开DS1302的充电电路,利用主供电对电池进行充电,免的换电池的麻烦* Input --> *CHG_dat:寄存器控制指针* Output --> none* Reaturn --> none******************************************************************************/ void DS1302_Charge_Manage(Charge_Typedef* CHG_dat){u8 CHG_Value;CHG_Value = (CHG_dat->TCSx << 4) | (CHG_dat->DSx << 2) | CHG_dat->RSx;DS1302_WP_Disable(); //取消写保护DS1302_Write_Data(Trickle_Charger_Address,CHG_Value);DS1302_WP_Enable(); //打开写保护}/****************************************************************************** * Function Name --> DS1302内置的RAM读写操作* Description --> none* Input --> *pBuff:读写数据存放区* WRadd:读写起始地址,范围在RAM_Address0 ~ RAM_Address28之间,最后一位地址有其他用途* num:读写字节数据的数量,范围在1 ~ 28之间* RW:读写判断位。
#include "stm32f10x_conf.h"#include "mrhh_f1.h"#include "HPF_TIME.h"#include "HpfDS1302Drive.h"//---------------------------------------------------------------------------------------------------------------// DS1302Çý¶¯F103IO¿ÚÅäÖÃ// Ver1.0 By MrHDS// 2016,4.23//---------------------------------------------------------------------------------------------------------------#if 1#define clkreset GPIOE->BRR=GPIO_Pin_1#define clkset GPIOE->BSRR=GPIO_Pin_1#define rstreset GPIOE->BRR=GPIO_Pin_2#define rstset GPIOE->BSRR=GPIO_Pin_2#define datreset GPIOE->BRR=GPIO_Pin_0#define datset GPIOE->BSRR=GPIO_Pin_0#define datred GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_0) //¶ÁÈ¡Êý¾Ý#define DS1302Enable HpfDS1302WritByte(control_add,0x80) //´ò¿ª±£»¤#define DS1302DisEnable HpfDS1302WritByte(control_add,0x00) //¹Ø±Õ±£»¤#define testdat 0x25#define cheaken 0#endif#define dstim 1Ds1302Time DSTime={21,16,1,1,12,0,0,1};void HpfDS1302PinInData(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//ÉÏÀ-ÊäÈëGPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOE,&GPIO_InitStructure);}void HpfDS1302PinOutData(void){GPIO_InitTypeDef GPIO_InitSyructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);GPIO_InitSyructure.GPIO_Mode=GPIO_Mode_Out_PP;//ÍÆÃâÊä³öGPIO_InitSyructure.GPIO_Pin=GPIO_Pin_0;GPIO_InitSyructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOE,&GPIO_InitSyructure);}void HpfDS1302PinClkRst(void){GPIO_InitTypeDef GPIO_InitSyructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);GPIO_InitSyructure.GPIO_Mode=GPIO_Mode_Out_PP;//ÍÆÃâÊä³öGPIO_InitSyructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2;GPIO_InitSyructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOE,&GPIO_InitSyructure);}void HpfDS1302Init(void){HpfDS1302PinClkRst();clkreset;rstreset;//¼Ä´æÆ÷Ö±½ÓÅäÖÃÊä³öµÍµçƽ}//---------------------------------------------------------------------------------------------------------------// DS1302Çý¶¯Ð´ÈëÒ»¸öµØÖ·ºÍÊý¾Ý// Ver1.0 By MrHDS// 2016,4.23//---------------------------------------------------------------------------------------------------------------void HpfDS1302WritByte(u8 addr,u8 data) //дÈëÊý¾ÝÔÚÉÏÉýÑØÓÐЧ {u8 i;HpfDS1302PinOutData();addr&=0xfe; //дÊý¾Ý£¬µØÖ·×îµÍλΪ¸ß rstreset;clkreset;HpfDealyUs(dstim);rstset;HpfDealyUs(dstim);for(i=0;i<8;i++) // дÈëµØÖ·{clkreset;HpfDealyUs(dstim);if(addr&0x01)datset;elsedatreset;clkset;HpfDealyUs(dstim);addr>>=1;// HpfDealyUs(10);}for(i=0;i<8;i++) //дÈëÊý¾Ýdata {clkreset;HpfDealyUs(dstim);if(data&0x01)datset;elsedatreset;clkset;HpfDealyUs(dstim);data>>=1;}rstreset; //Í£Ö¹×ÜÏßclkreset;}//--------------------------------------------------------------------------------------------------------------- // DS1302Çý¶¯¶Áȡһ¸öÊý¾Ý// Ver1.0 By MrHDS// 2016,4.23//---------------------------------------------------------------------------------------------------------------u8 HpfDS1302ReadByte(u8 addr)//¶Áȡһ¸öÊý¾ÝÔÚϽµÑØÓÐЧ£¬Ð´ÈëµØÖ·ÔÚÉÏÉýÑØÓÐЧ {u8 i,tem=0;addr|=0x01; //¶ÁÊý¾Ý£¬µØÖ·×îµÍλΪ1rstreset;clkreset;HpfDealyUs(dstim);rstset; //Æô¶¯×ÜÏßHpfDealyUs(dstim);HpfDS1302PinOutData();for(i=0;i<8;i++){clkreset;HpfDealyUs(dstim);if(addr&0x01)datset;elsedatreset;clkset;HpfDealyUs(dstim);addr>>=1;}HpfDS1302PinInData();for(i=0;i<8;i++){clkreset;HpfDealyUs(dstim);if(datred)tem|=0x80;if(i<7)tem>>=1;clkset;HpfDealyUs(dstim);}rstreset;clkreset;return tem;}u8 HpfDSBCDToNum(u8 BCD) //8421BCDÂëת»»ÎªÊý×Ö{u8 temp,temp1;temp1=BCD&0x0f;temp=((BCD&0xf0)>>4)*10+temp1;return temp;}u8 HpfDSNumToBCD(u8 NUM) //Êý×Öת»»Îª8421BCDÂë{u8 temp;temp=((NUM/10)<<4)|(NUM%10);return temp;}//--------------------------------------------------------------------------------------------------------------- // DS1302Çý¶¯»ñÈ¡Óû§Ê±¼ä²¢×ª»»ÎªbcdÂë²¢¸´ÖƵ½DS1302bufferÖÐ// Ver1.0 By MrHDS// 2016,4.23//---------------------------------------------------------------------------------------------------------------void HpfDSTimrSet(void){HpfWTime *p;Ds1302Time *s;p=GetWRTime();s=&DSTime;s->century=p->MyYear/100+1;s->year=HpfDSNumToBCD(p->MyYear-(s->century-1)*100);s->month=HpfDSNumToBCD(p->MyMon);s->day=HpfDSNumToBCD(p->MyDay);s->hh=HpfDSNumToBCD(p->MyHH);s->mm=HpfDSNumToBCD(p->MyMM);s->ss=HpfDSNumToBCD(p->MySS);s->week=HpfDSNumToBCD(GetWNLWeek(p,s->day));}//--------------------------------------------------------------------------------------------------------------- // DS1302°ÑbufferÖеÄʱ¼äÊý¾ÝдÈëµ½ds1302ÖÐ// Ver1.0 By MrHDS// 2016,4.23//---------------------------------------------------------------------------------------------------------------void HpfDS1302WritData(void){Ds1302Time *s;s=&DSTime;DS1302DisEnable; //¹Ø±Õд±£»¤HpfDS1302WritByte(sec_add,0x80); //ÔÝͣʱÖÓHpfDS1302WritByte(year_add,s->year);HpfDS1302WritByte(month_add,s->month);HpfDS1302WritByte(day_add,s->day);HpfDS1302WritByte(hh_add,s->hh);HpfDS1302WritByte(min_add,s->mm);HpfDS1302WritByte(sec_add,s->ss);HpfDS1302WritByte(week_add,s->week);HpfDS1302WritByte(RAM_Address29,testdat);DS1302Enable;}//--------------------------------------------------------------------------------------------------------------- // DS1302¶Áȡʱ¼äÊý¾Ý²¢×ª»»ÎªÊý×Ö²¢´æÈ뻺´æÆ÷ÖÐ// Ver1.0 By MrHDS// 2016,4.23//---------------------------------------------------------------------------------------------------------------void HpfDS1302ReadData(void){Ds1302Time *s;s=&DSTime;s->year=HpfDSBCDToNum(HpfDS1302ReadByte(year_add));s->month=HpfDSBCDToNum(HpfDS1302ReadByte(month_add));s->day=HpfDSBCDToNum(HpfDS1302ReadByte(day_add));s->hh=HpfDSBCDToNum(HpfDS1302ReadByte(hh_add));s->mm=HpfDSBCDToNum(HpfDS1302ReadByte(min_add));s->ss=HpfDSBCDToNum(HpfDS1302ReadByte(sec_add));s->week=HpfDSBCDToNum(HpfDS1302ReadByte(week_add));}//--------------------------------------------------------------------------------------------------------------- // DS1302°Ñʱ¼äͬ²½µ½Óû§Ê±¼ä// Ver1.0 By MrHDS// 2016,4.23//---------------------------------------------------------------------------------------------------------------void HpfDS1302TimeSyn(void){HpfWTime *p;p=GetWRTime();p->MyYear=(DSTime.century-1)*100+DSTime.year;p->MyMon=DSTime.month;p->MyDay=DSTime.day;p->MyHH=DSTime.hh;p->MyMM=DSTime.mm;p->MySS=DSTime.ss;}//--------------------------------------------------------------------------------------------------------------- // DS1302Çý¶¯»ñÈ¡»º´æÆ÷µØÖ·// Ver1.0 By MrHDS// 2016,4.23//---------------------------------------------------------------------------------------------------------------Ds1302Time *HpfDS1302GetTime(void){HpfDS1302Init();HpfDS1302ReadData();return &DSTime;}//--------------------------------------------------------------------------------------------------------------- // DS1302Çý¶¯RAM²Ù×÷// Ver1.0 By MrHDS// 2016,4.23////bufferΪ»º´æÆ÷µØÖ·£¬ramaddrΪÄÚ´æµØÖ·£¬numΪÁ¬Ðø²Ù×÷µÄ·¶Î§£¬rwΪ1£¬±íʾдÈëÊý¾Ý£¬Îª0±íʾ¶ÁÈ¡Êý¾Ý////////////---------------------------------------------------------------------------------------------------------------void HpfDs1302RamWR(u8 *buffer,u8 ramaddr,u8 num,u8 rw){u8 i;if(ramaddr==RAM_Address29)return;if(rw){for(i=0;i<num;i++){DS1302DisEnable;HpfDS1302WritByte(ramaddr+(i<<1),buffer[i]);DS1302Enable;}}else{for(i=0;i<num;i++)buffer[i]=HpfDS1302ReadByte(ramaddr+(i<<1));}}//---------------------------------------------------------------------------------------------------------------// DS1302Çý¶¯¼ì²éÉ豸ÊÇ·ñºÃ»µ¡£·µ»Ø0±íʾÕý³££¬·µ»Ø1±íʾÊý¾Ý»òÉ豸³öÎÊÌâ//µ±cheakenΪ1ʱ£¬·µ»Ø1±íʾÉ豸Õý³££¬Ê±¼äδ³õʼ»¯£¬·µ»Ø2±íʾӲ¼þ¹ÊÕÏ// Ver1.0 By MrHDS// 2016,4.23//---------------------------------------------------------------------------------------------------------------u8 HpfDS1302Check(void){u8 testnum;// DS1302DisEnable;testnum=HpfDS1302ReadByte(RAM_Address29);// DS1302Enable;if(testnum==testdat)return 0;else{#if cheakenDS1302DisEnable;HpfDS1302WritByte(RAM_Address29,testdat);DS1302Enable;HpfDealyUs(10);testnum=HpfDS1302ReadByte(RAM_Address29);if(testnum==testdat)return 1;#elsereturn 1;#endif}#if !cheakenreturn 2;#endif}。
#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar table0[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //液晶显示数字0——9代码sbit SCLK=P1^0;sbit DATA=P1^1;sbit CE=P1^2;sbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit FB=P0^7;sbit start=P1^4;sbit stop=P1^5;uchar i;/*******************延时n微秒函数*****************/void delaynus(uchar n) //n us延时函数{// uchar i;for(i=n;i>0;i--);}/*******************写数据函数*****************/void write1302(uchar add,uchar dat){CE=0;SCLK=0;CE=1;for(i=0;i<8;i++) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=0;i<8;i++) //写入数据{DATA=dat&0x01;SCLK=1;SCLK=0;dat>>=1;}SCLK=1;CE=0;}/*******************读数据函数*****************/uchar read1302(uchar add){uchar dat;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=8;i>0;i--) //读出数据/********************为神马???**************************/{dat>>=1;if(DATA==1)dat=dat|0x80;SCLK=1;SCLK=0;}SCLK=1;CE=0;return dat;}/*******************DS1302初始化函数*****************/void init1302(){uchar flag;flag=read1302(0x81);if(flag&0x80){write1302(0x8e,0x00);write1302(0x80,0x00);write1302(0x82,(((1/10)<<4)|(1%10)));write1302(0x84,(((20/10)<<4)|(20%10)));write1302(0x86,(((19/10)<<4)|(19%10)));write1302(0x88,(((7/10)<<4)|(7%10)));write1302(0x8a,((2/10)<<4)|(2%10));write1302(0x8c,(((11/10)<<4)|(11%10)));write1302(0x90,0xa5); //充电。
关于STM32驱动DS1302实时时钟的一点思考之前用51 驱动过DS1302,没用多久就输出了正确的时间。
当时以为这块芯片其实没啥,很简单。
但是现在用STM32 做项目,用到同样的芯片,以为这有何难,只要把那个程序拿过来复制黏贴改一下IO 设置不就行了?但是事情远没有想想的那么简单。
经过3 天的挣扎,现在才知道当时自己是多么天真。
关于DS1302 的基本操作可以看这里:cnblogs/qsyll0916/p/7712695.html好了,废话少说了,进入正题。
首先DS1302 读写方式属于3 线SPI。
CE、SCK、IO。
其中IO 口属于双向IO 口,我们读写都要经过这个IO 口。
在用51 开发的时候,因外他是准双向IO,不需要我们额外关心他的输入输出设置。
需要输出的时候直接写P0= 1;需要检测外部输入的时候直接写if(P0== 1) ,都很方便,但是方便的同时带来的是读写速度上的限制。
那么在STM32 中,每个IO 口都有8 种输出模式。
复杂的同时也意味着每一种模式都是专门定制的,带来了速度上的优势。
所以在移植这个程序的时候,就需要注意这个双向IO 的设置问题。
一开始我也不是很懂,各种百度查资料,各种问人。
最后才知道有两种方式可以实现双向的IO 读写设置。
第一:#define DS1302_DATIN PBin(6)#define DS1302_DATOUT PBout(6)#define DS1302_DAT_INPUT() {GPIOB->CRL&= 0XF0FFFFFF;GPIOB- >CRL|= 8#define DS1302_DAT_OUTPUT() {GPIOB->CRL&=。
1简介主控芯片是STM32F103ZET6,DS1302模块在某宝购买,测试两个小时,发现一个小时大概差1秒钟。
芯片受温度、电压影响较大。
输出结果用串口打印到串口调试助手。
如果要oled或者其他显示需要转换为十进制。
2.代码部分2.1 led部分------------led.h--------------------#ifndef __LED_H#define __LED_H#include "sys.h"void LED_Init(void);//初始化#endif------------led.c--------------------#include "led.h"//LED IO初始化void LED_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数初始化GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB5 输出高}2.2 usart部分---------------usart.h------------------------#ifndef __USART_H#define __USART_H#include "stdio.h"#include "sys.h"void uart_init(u32 bound);void usart1_send_string(u8 *BuffToSend);void usart1_sendbyte(u8 data);#endif---------------usart.c-----------------------#include "sys.h"#include "usart.h"void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Peri ph_GPIOA, ENABLE); //使能USART1,GPIOA时钟//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器//USART 初始化设置USART_ART_BaudRate = bound;//串口波特率USART_ART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_ART_StopBits = USART_StopBits_1;//一个停止位USART_ART_Parity = USART_Parity_No;//无奇偶校验位USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART1, ENABLE); //使能串口1 }//打印字节void usart1_sendbyte(u8 data){USART_SendData(USART1, data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);}//打印字符串void usart1_send_string(u8 *BuffToSend){u8 i=0;while(BuffToSend[i]!='\0'){USART_SendData(USART1, BuffToSend[i]);while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);i++;}}2.3 ds1302部分---------------ds1302.h-----------------------#ifndef __DS1302_H#define __DS1302_H#include "sys.h"//写年月日时间寄存器#define WriteSecond 0x80#define WriteMinute 0x82#define WriteHour 0x84#define WriteDay 0x86#define WriteMonth 0x88#define writeWeek 0x8a#define writeYear 0x8c//读年月日时间寄存器#define ReadSecond 0x81#define ReadMinute 0x83#define ReadHour 0x85#define ReadDay 0x87#define ReadMonth 0x89#define ReadWeek 0x8b#define ReadYear 0x8d//引脚分配 SDA-PC3 SCL-PC4 RST-PC5#define DS_SDA_IN {GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)8<<12;}#define DS_SDA_OUT{GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)3<<12;}#define DS_SDA_DATA GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)//SDA#define DS_SDA_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_3)#define DS_SDA_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_3)#define DS_SCK_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_4)//SCL#define DS_SCK_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_4)#define DS_RST_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_5)//CE#define DS_RST_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_5)void ds1302_init(void);void write_one_byte(u8 data);u8 read_one_byte(void);void ds1302_write_data(u8 reg,u8 data);u8 ds1302_read_data(u8 reg);void time_init(void);void time_read(void);u8 hex_to_bcd(u8 hex_data);u8 bcd_to_hex(u8 bcd_data);#endif---------------ds1302.c-----------------------#include "ds1302.h"#include "delay.h"u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear;u8 time[7]={0x18,0x06,0x10,0x19,0x23,0x59,0x30};//年星期月日时分秒void ds1302_init(){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_ResetBits(GPIOC,GPIO_Pin_5);//CE拉低GPIO_SetBits(GPIOC, GPIO_Pin_3|GPIO_Pin_4); //拉高}//写入一个字节void write_one_byte(u8 data){u8 i;DS_SDA_OUT;for(i=0;i<8;i++){DS_SCK_LOW;if(data&0x01) //从低位开始{DS_SDA_HIGH;}else{DS_SDA_LOW;}delay_us(2);DS_SCK_HIGH;data>>=1;delay_us(2);}}//读一个字节u8 read_one_byte(){u8 i,data;DS_SDA_IN ;for(i=0;i<8;i++){data>>=1;DS_SCK_HIGH;if(DS_SDA_DATA==1){data|=0x80;}else{data&=0x7F;}delay_us(2);DS_SCK_LOW;}return data;}//ds1302写寄存器写数据void ds1302_write_data(u8 reg,u8 data) {DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;write_one_byte(data); //sck低到高delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;}//读ds1302寄存器数据u8 ds1302_read_data(u8 reg){u8 temp;DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 delay_us(2);write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;temp=read_one_byte(); //sck由高到低delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;return temp;}u8 hex_to_bcd(u8 hex_data){u8 temp;temp=(hex_data/10*16 + hex_data%10);return temp;}u8 bcd_to_hex(u8 bcd_data){u8 temp;temp=(bcd_data/16*10 + bcd_data%16);return temp;}//time初始化void time_init(){ds1302_write_data(0x8e,0x00);//关闭写保护ds1302_write_data(writeYear ,(time[0]));//写入hex格式数据ds1302_write_data(writeWeek,(time[1]));ds1302_write_data(WriteMonth,(time[2]));ds1302_write_data(WriteDay,(time[3]));ds1302_write_data(WriteHour,(time[4]));ds1302_write_data(WriteMinute,(time[5]));//ds1302_write_data(WriteSecond,(time[6]));//ds1302_write_data(0x8e,0x80);//开启写保护}//读取寄存器时间void time_read(){DSyear=ds1302_read_data(ReadYear);DSweek=ds1302_read_data(ReadWeek);DSmonth=ds1302_read_data(ReadMonth);DSday=ds1302_read_data(ReadDay);DShour=ds1302_read_data(ReadHour);DSminute=ds1302_read_data(ReadMinute);DSsecond=ds1302_read_data(ReadSecond);}2.4主函数---------------main-----------------------#include "sys.h"#include "delay.h"#include "usart.h"#include "led.h"#include "ds1302.h"Extern u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear;int main(void){delay_init();LED_Init();uart_init(115200);ds1302_init();time_init();while(1){time_read();//更新时间usart1_sendbyte(DSyear);usart1_sendbyte(DSmonth);usart1_sendbyte(DSday);usart1_sendbyte(DShour);usart1_sendbyte(DSminute);usart1_sendbyte(DSsecond);usart1_sendbyte(DSweek);GPIO_ResetBits(GPIOB,GPIO_Pin_5); //LED0闪烁delay_ms(250);GPIO_SetBits(GPIOB,GPIO_Pin_5); //delay_ms(250);}}3.结果串口调试助手hex显示,打印的是十六进制数据。
#include<reg52.h>#define uchar unsigned charsbit RST=P1^2;sbit SDA=P1^1;sbit SCLK=P1^0;sbit rs=P1^3;sbit lcden=P1^4;sbit key1=P3^7;sbit key2=P3^6;sbit key3=P3^5;uchar t,addr,x,y;void delay(unsigned char t){unsigned char i,j;for(i=t;i>0;i--)for(j=110;j>0;j--);}void delayus(unsigned char t1){for(;t1>0;t1--);}void write_com(unsigned char com)//写lcd1602控制命令{rs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_dat(unsigned char dat) //写lcd1602显示数据命令{rs=1;P0=dat;delay(5);lcden=1;delay(5);lcden=0;}void DS1302WriteByte(uchar dat){uchar i;SCLK=0;delayus(2);for(i=0;i<8;i++){SDA=dat&0x01;delayus(2);SCLK=1;delayus(2);SCLK=0;dat>>=1;}}void DS1302Read(uchar cmd) //读ds1302的时间信息并显示出来{uchar dat,a2,i;RST=0;SCLK=0;RST=1;DS1302WriteByte(cmd);delayus(2);for(i=0;i<8;i++){dat>>=1;if(SDA==1)dat|=0x80;SCLK=1;delayus(2);SCLK=0;delayus(2);}SCLK=1;RST=0;if(cmd==0x8b){dat=dat%16;write_dat(0x30+dat);}else{a2=dat%16;dat=dat/16;write_dat(0x30+a2);write_dat(0x30+dat);}}void DS1302Write(uchar cmd, uchar dat) //写时间信息到ds1302 {RST=0;SCLK=0;RST=1;DS1302WriteByte(cmd);DS1302WriteByte(dat);SCLK=1;RST=0;}void init() //初始化部分{P2=0; //关闭锁存器端口write_com(0x01);write_com(0x38);write_com(0x0c);write_com(0x04);DS1302Write(0x8e,0x00);}void key() //按键控制部分{ uchar q;if(key1==0){DS1302Write(0x80,0x80);write_com(0x0f);delay(40);if(key1==0){t++;if(t==9)t=1;switch(t){case 1:write_com(0x85); addr=0x85;break;case 2:write_com(0x88); addr=0x88;break;case 3:write_com(0x8b); addr=0x8b;break;case 4:write_com(0x8e); addr=0x8e;break;case 5:write_com(0xc5); addr=0xc5;break;case 6:write_com(0xc8); addr=0xc8;break;case 7: write_com(0xcb); addr=0xcb;break;case 8: x=x*16+y;DS1302Write(0x80,x);write_com(0x0c);t=0;break;}while(key1==0);x=0;y=0;}}if(key2==0||key3==0){delay(40);if(key2==0){if(t==4)y=0;elsex++;}if(key3==0)y++;switch (t){case 1: if(x==10)x=0;if(y==10)y=0;q=x*16+y;DS1302Write(0x8c,q);break;case 2: if(x==0){if(y==10)y=0;}if(x==1){ if(y==3)y=0;}if(x==2)x=0;q=x*16+y;DS1302Write(0x88,q); break;case 3: if(x==4)x=0;if(y==32)y=0;q=x*16+y;DS1302Write(0x86,q);break;case 4:if(y==8)y=0;q=x*16+y;DS1302Write(0x8a,q); break;case 5: if(x==0||x==1){if(y==10)y=0;}if(x==2){ if(y==4)y=0;}if(x==3)x=0;q=x*16+y;DS1302Write(0x84,q); break;case 6:if(x==6)x=0;if(y==10)y=0;q=x*16+y;DS1302Write(0x82,q);break;case 7: if(x==6)x=0;if(y==10)y=0;q=x*16+y+0x80;DS1302Write(0x80,q);break;}if(addr==0x8e){write_com(addr);write_dat(0x30+y);write_com(addr);}else{write_com(addr);write_dat(0x30+y);write_dat(0x30+x);write_com(addr);}while(key2==0||key3==0);}}void main(){init();while(1){key();if(t==0){write_com(0xcb); // 在第二行显示DS1302Read(0x81); // 读秒write_dat(0x3a);DS1302Read(0x83); // 读分write_dat(0x3a);DS1302Read(0x85); // 读时write_com(0x8e); // 在第一行显示DS1302Read(0x8b); // 读星期write_dat(0x2a);write_dat(' ');DS1302Read(0x87); // 读日write_dat(0x2f);DS1302Read(0x89); // 读月write_dat(0x2f);DS1302Read(0x8d); // 读年write_dat(0x30);write_dat(0x32);} }}。
/****************************************************************************** * @ File name --> <strong><font color="#FF0000">ds1302</font></strong>.c* @ Author --> By@ Sam Chan* @ Version --> V1.0* @ Date --> 08 - 23 - 2012* @ Brief --> 时钟芯片DS1302驱动** @ Copyright (C) 20*** @ All rights reserved******************************************************************************* ** File Update* @ Version --> V1.0.1* @ Author --> By@ Sam Chan* @ Date --> 10 - 20 - 2013* @ Revise --> A、增加对STM32控制的移植支持* @ --> B、增加对内置的RAM操作相关函数* @ --> C、增加检测DS1302是否存在,是否第一次上电检测函数* @ --> D、增加对DS1302内置的锂电池充电寄存器参数设置函数和结构体*******************************************************************************/ #include "ds1302.h"/****************************************************************************** 定义变量******************************************************************************/ #define Date TimeValue.date#define Min TimeValue.minute#define Sec TimeValue.second#define Hour TimeValue.hour#define Week TimeValue.week#define Month TimeValue.month#define Year TimeValue.yearTime_Typedef TimeValue; //定义时间数据指针void Time_Init(){TimeValue.date=24;TimeValue.hour=6;TimeValue.minute=12;TimeValue.month=5;TimeValue.second=0;TimeValue.week=2;TimeValue.year=16;}Charge_Typedef ChargeValue; //定义充电寄存器/****************************************************************************** * Function Name --> GPIO初始化* Description --> none* Input --> none* Output --> none* Reaturn --> none******************************************************************************/void DS1302_GPIOInit(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //开启GPIOC外设时钟/* 初始化GPIOC */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);}/****************************************************************************** * Function Name --> DS1302写入一个字节数据* Description --> none* Input --> dat:要写入的数据* Output --> none* Reaturn --> none******************************************************************************/ void DS1302_Write_Byte(u8 dat){u8 i;DS1302_SDA_OUT(); //设置为输出口for(i=0;i<8;i++){DS1302_SCL = 0; //时钟线拉低if(dat & 0x01) DS1302_SDA = 1; //数据线放上数据,先发低位else DS1302_SDA = 0;dat >>= 1; //数据右移一位DS1302_SCL = 1; //发送数据,上升沿有效}}/****************************************************************************** * Function Name --> DS1302读出一个字节数据* Description --> none* Input --> none* Output --> none* Reaturn --> 读到的数据******************************************************************************/ unsigned DS1302_Read_Byte(){u8 ReData=0x00;u8 i;DS1302_SDA_IN(); //设置为输入口for(i=0;i<8;i++){if(DS1302_IN_SDA == 1){ ReData |= 0x80; } //读出一位数据是“1”DS1302_SCL = 0; //时钟线拉低ReData >>= 1; //数据右移一位,先读取低位,数据补“0”DS1302_SCL = 1; //上升沿读取数据}return(ReData); //返回读取到的数据}/****************************************************************************** * Function Name --> 向DS1302某地址写入数据* Description --> none* Input --> add:要操作的地址* dat:要写入的数据* Output --> none* Reaturn --> none******************************************************************************/ void DS1302_Write_Data(u8 add,u8 dat){DS1302_RST = 0; //复位脚拉低DS1302_SCL = 0; //时钟线拉低DS1302_RST = 1; //复位脚拉高DS1302_Write_Byte(add); //写入要操作地址DS1302_Write_Byte(dat); //写入数据//delay_us(5);DS1302_RST = 0;DS1302_SCL = 0;}* Function Name --> 从DS1302某地址读取数据* Description --> none* Input --> add:要操作的地址* Output --> none* Reaturn --> 要读取的寄存器的数值******************************************************************************/ unsigned DS1302_Read_Data(u8 add){u8 Temp;DS1302_RST = 1;DS1302_Write_Byte(add); //写入要操作地址Temp = DS1302_Read_Byte(); //开始读取数据DS1302_RST = 0;return(Temp); //返回读取到的数据}/****************************************************************************** * Function Name --> 主电源对备用电池充电设置* Description --> 如果备用电池接的是可充电的锂电池或者其他可充电电池的时候,* 可以打开DS1302的充电电路,利用主供电对电池进行充电,免的换电池的麻烦* Input --> *CHG_dat:寄存器控制指针* Output --> none* Reaturn --> none******************************************************************************/ void DS1302_Charge_Manage(Charge_Typedef* CHG_dat){u8 CHG_Value;CHG_Value = (CHG_dat->TCSx << 4) | (CHG_dat->DSx << 2) | CHG_dat->RSx;DS1302_WP_Disable(); //取消写保护DS1302_Write_Data(Trickle_Charger_Address,CHG_Value);DS1302_WP_Enable(); //打开写保护}/****************************************************************************** * Function Name --> DS1302内置的RAM读写操作* Description --> none* Input --> *pBuff:读写数据存放区* WRadd:读写起始地址,范围在RAM_Address0 ~ RAM_Address28之间,最后一位地址有其他用途* num:读写字节数据的数量,范围在1 ~ 28之间* RW:读写判断位。