#include "Data_deal.h" #include "DS1302.h" #include "sys_delay.h" uint8_t time_buf[7] = {0x20,0x20,0x05,0x29,0x17,0x20,0x14}; //初始时间2020年5月29号17点41分14秒 星期五 //DS1302初始化 void ds1302_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); GPIO_InitStruct.Pin = DS1302_RST; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); GPIO_InitStruct.Pin = DS1302_DATA; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); GPIO_InitStruct.Pin = DS1302_SCK; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_WritePin(GPIOE, DS1302_DATA,GPIO_PIN_SET); //拉高 HAL_GPIO_WritePin(GPIOE, DS1302_RST,GPIO_PIN_SET); //置低 HAL_GPIO_WritePin(GPIOB, DS1302_SCK,GPIO_PIN_RESET); //置低 } void DS1302_IO_IN(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOE_CLK_ENABLE(); GPIO_InitStruct.Pin = DS1302_DATA; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); } void DS1302_IO_OUT(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOE_CLK_ENABLE(); GPIO_InitStruct.Pin = DS1302_DATA; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); } //void delay_us(uint32_t us) //{ // uint32_t delay = (HAL_RCC_GetHCLKFreq() / 6000000 * us); // while (delay--) // { // ; // } //} //向DS1302写入一个字节数据 void ds1302_Write_Byte(uint8_t addr, uint8_t data) { uint8_t i; DS1302_RST_0; //停止DS1302总线 delay_us(10); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); DS1302_RST_1; //启动DS1302总线 addr = addr & 0xFE; //最低位置零,写数据 DS1302_IO_OUT(); for(i = 0; i < 8; i ++) //写地址 { if (addr & 0x01) DS1302_DATA_OUT_1; else DS1302_DATA_OUT_0; DS1302_SCK_1; //产生时钟 delay_us(10); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); DS1302_SCK_0; addr = addr>>1; } for (i = 0; i < 8; i ++) //写数据 { if(data & 0x01) DS1302_DATA_OUT_1; else DS1302_DATA_OUT_0; DS1302_SCK_1; //产生时钟 delay_us(10); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); DS1302_SCK_0; data = data>>1; } DS1302_RST_0; //停止DS1302总线 } //从DS1302读出一个字节数据 uint8_t ds1302_Read_Byte(uint8_t addr) { uint8_t i,temp; DS1302_RST_0; //停止DS1302总线 delay_us(10); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); DS1302_RST_1; //启动DS1302总线 addr = addr | 0x01; //最低位置高,读数据 DS1302_IO_OUT(); for(i = 0; i < 8; i ++) //写地址 { if (addr & 0x01) DS1302_DATA_OUT_1; else DS1302_DATA_OUT_0; DS1302_SCK_1; //产生时钟 delay_us(10); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); DS1302_SCK_0; addr = addr>>1; } DS1302_IO_IN(); for (i = 0; i < 8; i ++) //读数据 { temp = temp >> 1; if(DS1302_DATA_IN()) temp |= 0x80; else temp &= 0x7F; DS1302_SCK_1; //产生时钟 delay_us(10); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); DS1302_SCK_0; } DS1302_RST_0; //停止DS1302总线 return temp; } //向DS1302写入时间数据 void ds1302_Write_Time(uint8_t *Time_buf) { ds1302_Write_Byte(ds1302_control_add, 0x00); //关闭写保护 ds1302_Write_Byte(ds1302_sec_add, 0x80); //暂停时钟 //DS1302_Write_Byte(ds1302_charger_add, 0xA9); //涓流充电 ds1302_Write_Byte(ds1302_year_add,HEX2BCD(Time_buf[1])); //年 ds1302_Write_Byte(ds1302_month_add,HEX2BCD(Time_buf[2])); //月 ds1302_Write_Byte(ds1302_date_add,HEX2BCD(Time_buf[3])); //日 ds1302_Write_Byte(ds1302_hr_add,HEX2BCD(Time_buf[4])); //时 ds1302_Write_Byte(ds1302_min_add,HEX2BCD(Time_buf[5])); //分 ds1302_Write_Byte(ds1302_sec_add,HEX2BCD(Time_buf[6])); //秒 //ds1302_Write_Byte(ds1302_day_add,time_buf[7]); //周 ds1302_Write_Byte(ds1302_control_add,0x80); //打开写保护 } //从DS302读出时钟数据 void ds1302_Read_Time(void) { time_buf[1] = ds1302_Read_Byte(ds1302_year_add); //年 time_buf[2] = ds1302_Read_Byte(ds1302_month_add); //月 time_buf[3] = ds1302_Read_Byte(ds1302_date_add); //日 time_buf[4] = ds1302_Read_Byte(ds1302_hr_add); //时 time_buf[5] = ds1302_Read_Byte(ds1302_min_add); //分 time_buf[6] = (ds1302_Read_Byte(ds1302_sec_add))&0x7f; //秒,屏蔽秒的第7位,避免超出59 //time_buf[7] = ds1302_Read_Byte(ds1302_day_add); //周 //Can_Send_Hu_Msg(0xb1,time_buf,8,0x1b,0x00000012); } void ds1302_SynTime(SDateTime * datetime) { ds1302_Read_Time(); datetime->year = BCD2HEX(time_buf[1]); datetime->month = BCD2HEX(time_buf[2]); datetime->day = BCD2HEX(time_buf[3]); datetime->hour = BCD2HEX(time_buf[4]); datetime->min = BCD2HEX(time_buf[5]); datetime->sec = BCD2HEX(time_buf[6]); return; } //DS1302向上层返回时间数据 void ds1302_Get_Time(uint8_t *time) { ds1302_Read_Time(); time[0]=(time_buf[0]>>4); //年 time[1]=(time_buf[0]&0x0f); time[2]=(time_buf[1]>>4); time[3]=(time_buf[1]&0x0f); time[4]=(time_buf[2]>>4); //月 time[5]=(time_buf[2]&0x0f); time[6]=(time_buf[3]>>4); //日 time[7]=(time_buf[3]&0x0f); //time[8]=(time_buf[7]&0x07); //星期 time[9]=(time_buf[4]>>4); //时 time[10]=(time_buf[4]&0x0f); time[11]=(time_buf[5]>>4); //分 time[12]=(time_buf[5]&0x0f); time[13]=(time_buf[6]>>4); //秒 time[14]=(time_buf[6]&0x0f); } //////////////////////////////////////--以下李伟添加 李伟修改 20210613 //ds1302------stm32f746vgt6 //pin5 rst--pin98--Pe1 //pin6 io pin97--PE0 //pin7 sck pin96--PB9 /* 1、 初始化IO口。 void GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); } 2、 ds1302_init(); // 调用ds1302初始化程序 3、 get_result() ; //定时读取ds1302时间 这个函数每隔一段时间调用一次。比如50ms调用一次。 */ #define RST_1 HAL_GPIO_WritePin(GPIOE, DS1302_RST, GPIO_PIN_SET) //GPIO_SetBits(GPIOE, GPIO_PIN_1); #define RST_0 HAL_GPIO_WritePin(GPIOE, DS1302_RST, GPIO_PIN_RESET) //GPIO_ResetBits(GPIOE, GPIO_PIN_1); #define IO_1 HAL_GPIO_WritePin(GPIOE, DS1302_DATA, GPIO_PIN_SET) //GPIO_SetBits(GPIOD, GPIO_Pin_13); #define IO_0 HAL_GPIO_WritePin(GPIOE, DS1302_DATA, GPIO_PIN_RESET) //GPIO_ResetBits(GPIOD, GPIO_Pin_13); #define SCLK_1 HAL_GPIO_WritePin(GPIOB, DS1302_SCK, GPIO_PIN_SET) //GPIO_SetBits(GPIOB, GPIO_Pin_9); #define SCLK_0 HAL_GPIO_WritePin(GPIOB, DS1302_SCK, GPIO_PIN_RESET) //DS1302_SCK_0 //GPIO_ResetBits(GPIOB, GPIO_Pin_9); /*定义待设置的时间: 秒、 分、 时、 日、 月、 星期、年、控制字*/ volatile char time_tab[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; char tableDS1302[7]; char date_1302[6]; char time_1302[6]; unsigned int year; unsigned char month; unsigned char date; unsigned char hour; unsigned char min; unsigned char sec; /******************************************************************** 函 数 ds1302_initV2()DS1302初始化函数 功 能:DS1302初始化 入口参数:无 返 回 值:无 ***********************************************************************/ void ds1302_initV2(void) { SCLK_0; RST_0; RST_1; ds1302_writeV2(0x8e); ds1302_writeV2(0); RST_0; } /******************************************************************** 函 数 名:ds1302_write()写一个字节数据函数 功 能:DS1302中写入一个字节 入口参数:time_tx 要写入的一个字节 返 回 值:无 ***********************************************************************/ void ds1302_writeV2(unsigned char time_tx) { int j; Set_IO_OUT(); for(j=0;j<8;j++) { IO_0; SCLK_0; if((time_tx&0x01)!=0) IO_1; time_tx=time_tx>>1; SCLK_1; } SCLK_0; } /******************************************************************** 函 数 名:ds1302_read()读一个字节函数 功 能:从DS1302读一个字节 入口参数:无 返 回 值:unsigned char :读取的数据 ***********************************************************************/ unsigned char ds1302_readV2(void) { int j; unsigned char time_rx=0; Set_IO_INPUT(); for(j=0;j<8;j++) { SCLK_0; time_rx=time_rx>>1; //if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_13)==1) time_rx|=0x80;//把接收到的数据放到接收寄存器的最高位 if (DS1302_DATA_IN()==1) time_rx|=0x80;//把接收到的数据放到接收寄存器的最高位 SCLK_1; } SCLK_0; return(time_rx); } /******************************************************************** 函 数 名:set_time()设置时间函数 功 能:设置初始时间 说 明:使用了多字节写方式 入口参数:无 返 回 值:无 ***********************************************************************/ void set_time(void) { int i; RST_1; ds1302_writeV2(0xbe); for(i=0;i<8;i++) { ds1302_writeV2(time_tab[i]); } RST_0; } /******************************************************************** 函 数 名:get_all()读取全部时间信息函数 功 能:读取DS1302内部的全部时间信息 入口参数:无 返 回 值:无。 ***********************************************************************/ void DS1302_get_all(void) { int i; RST_1; ds1302_writeV2(0xbf); for(i=0;i<7;i++) { tableDS1302[i]=ds1302_readV2(); } RST_0; } /******************************************************************** 函 数 名:get_time()读取时间函数 功 能:读取DS1302当前时间 入口参数:无 返 回 值:无。 ***********************************************************************/ void get_timeV2(void) { DS1302_get_all(); time_1302[0]=tableDS1302[0]&0x0F;//求秒的个位 time_1302[1]=tableDS1302[0]&0x70; //求秒的十位 time_1302[1]>>=4;//右移4位 time_1302[2]=tableDS1302[1]&0x0F; //求分的个位 time_1302[3]=tableDS1302[1]&0x70; //求分的十位 time_1302[3]>>=4; time_1302[4]=tableDS1302[2]&0x0F; //求时的个位 time_1302[5]=tableDS1302[2]&0x70; //求时的十位 time_1302[5]>>=4; } /******************************************************************** 函 数 名:get_date()读取日期函数 功 能:读取DS1302当前日期 入口参数:无 返 回 值:无。 ***********************************************************************/ void get_date(void) { DS1302_get_all(); date_1302[0]=tableDS1302[3]&0x0F;//求日的个位 date_1302[1]=tableDS1302[3]&0x30; //求日的十位 date_1302[1]>>=4;//右移4位 date_1302[2]=tableDS1302[4]&0x0F; //求月的个位 date_1302[3]=tableDS1302[4]&0x10; //求月的十位 date_1302[3]>>=4; date_1302[4]=tableDS1302[6]&0x0F; //求年的个位 date_1302[5]=tableDS1302[6]&0xF0; //求年的十位 date_1302[5]>>=4; } void get_result(void) { int i; int j; get_date(); i=date_1302[5]; j=date_1302[4]; year=i*10+j; i=date_1302[3]; j=date_1302[2]; month=i*10+j; i=date_1302[1]; j=date_1302[0]; date=i*10+j; get_timeV2(); i=time_1302[5]; j=time_1302[4]; hour=i*10+j; i=time_1302[3]; j=time_1302[2]; min=i*10+j; i=time_1302[1]; j=time_1302[0]; sec=i*10+j; } void Set_IO_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; /*定义一个GPIO_InitTypeDef类型的结构体*/ __HAL_RCC_GPIOE_CLK_ENABLE(); GPIO_InitStructure.Pin = DS1302_DATA; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // /设置引脚模式为输入 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM; //GPIO_Init(GPIOE, &GPIO_InitStructure); HAL_GPIO_Init(GPIOE, &GPIO_InitStructure); } void Set_IO_INPUT(void) { GPIO_InitTypeDef GPIO_InitStructure; /*定义一个GPIO_InitTypeDef类型的结构体*/ __HAL_RCC_GPIOE_CLK_ENABLE(); GPIO_InitStructure.Pin = DS1302_DATA; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;//GPIO_MODE_INPUT; // /设置引脚模式为输入 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM; //GPIO_Init(GPIOE, &GPIO_InitStructure); HAL_GPIO_Init(GPIOE, &GPIO_InitStructure); }