#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);
		
}



