基于DS3231时钟模块的stm32 Hal库程序,源码

关于DS3231模块介绍我在我的博客基于DS3231时钟模块的stm32 程序,源码中有介绍 ,大家可以自己看下。我这篇直接讲HAL的代码。

一、配置IO

/**
  /**
	******************************************************************************
	* @file    bsp_i2c_ds3231.h  
	* @author  兲涳
	* @version V1.0
	* @date    2020-11-18
	* @brief   模拟i2c RTC(DS3231)应用函数bsp
	******************************************************************************
	* @attention
	* 
	******************************************************************************
	*/ 
	  

  /******************************************************************************
  * @attention
  * 
  ******************************************************************************
  */ 
	
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __I2C_DS3231_H
#define	__I2C_DS3231_H

/* Includes ------------------------------------------------------------------*/


#ifdef _I2C_DS3231_PUBLIC_
#define PEXT 
#else
#define PEXT extern
#endif


/* Exported types ------------------------------------------------------------*/
typedef struct 
{
	u8  hour;
	u8  min;
	u8  sec;			
	u32 year;
	u8  month;
	u8  day;
	u8  week;
	u16 temperature;
}_calendar_obj;	


/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/**************************I2C参数定义,I2C1或I2C2*****************************/




//#define	DS3231_I2C_GPIO_APBxClock_FUN   RCC_AHB1PeriphClockCmd
//#define   DS3231_I2C_GPIO_CLK             RCC_APB2Periph_GPIOC    
#define     DS3231_I2C_SCL_PORT             GPIOC  
#define     DS3231_I2C_SCL_PIN              GPIO_PIN_10
#define     DS3231_I2C_SDA_PORT             GPIOC 
#define		DS3231_I2C_SDA_PIN				GPIO_PIN_11


											 
#define 	I2C_WR		0		
#define 	I2C_RD		1


#define		I2C_SCL_1()  			HAL_GPIO_WritePin(DS3231_I2C_SCL_PORT, DS3231_I2C_SCL_PIN,GPIO_PIN_SET)		
#define 	I2C_SCL_0()  			HAL_GPIO_WritePin(DS3231_I2C_SCL_PORT, DS3231_I2C_SCL_PIN,GPIO_PIN_RESET)		
#define 	I2C_SDA_1()           	HAL_GPIO_WritePin(DS3231_I2C_SDA_PORT, DS3231_I2C_SDA_PIN,GPIO_PIN_SET)		
#define 	I2C_SDA_0()           	HAL_GPIO_WritePin(DS3231_I2C_SDA_PORT, DS3231_I2C_SDA_PIN,GPIO_PIN_RESET)		
#define 	I2C_SDA_READ()        	HAL_GPIO_ReadPin(DS3231_I2C_SDA_PORT, DS3231_I2C_SDA_PIN)	


/* STM32 I2C 快速模式 */
#define             I2C_Speed             										 400000  
/* 这个地址只要与STM32外挂的I2C器件地址不一样即可 */
#define 						I2Cx_OWN_ADDRESS7     										 0X0A   
/* DS3231 地址定义 */
#define 						DS3231_ADDRESS 														 0xD0   

/* DS3231寄存器地址 */
																					
#define							DS3231_SECOND															 0x00    //秒
#define 						DS3231_MINUTE      												 0x01    //分
#define 						DS3231_HOUR        												 0x02    //时
#define 						DS3231_WEEK         											 0x03    //星期
#define 						DS3231_DAY          											 0x04    //日
#define 						DS3231_MONTH                      		   0x05    //月
#define             			DS3231_YEAR        						   0x06    //年 											 0x06    //年
/* 闹铃1 */          	
#define             			DS3231_SALARM1ECOND                        0x07    //秒
#define 						DS3231_ALARM1MINUTE                        0x08    //分
#define             			DS3231_ALARM1HOUR                          0x09    //时
#define 						DS3231_ALARM1WEEK  												 0x0A    //星期/日
/* 闹铃2 */
#define 						DS3231_ALARM2MINUTE 											 0x0b    //分
#define 						DS3231_ALARM2HOUR                          0x0c    //时
#define 						DS3231_ALARM2WEEK                          0x0d    //星期/日

#define 						DS3231_CONTROL                             0x0e    //控制寄存器
#define 						DS3231_STATUS                              0x0f    //状态寄存器
#define 						BSY                 											 2       //忙
#define 						OSF                												 7       //振荡器停止标志
#define 						DS3231_XTAL         											 0x10    //晶体老化寄存器
#define 						DS3231_TEMPERATUREH 											 0x11    //温度寄存器高字节(8位)
#define 						DS3231_TEMPERATUREL 											 0x12    //温度寄存器低字节(高2位) 																				



PEXT _calendar_obj calendar;	//日历结构体

/* Exported functions ------------------------------------------------------- */																				
PEXT void I2C_DS3231_Init(void);	
PEXT void i2c_Stop(void);
PEXT uint32_t I2C_DS3231_ByteWrite(u8 WriteAddr, u8 data); 	
PEXT uint8_t I2C_DS3231_DataRead(u8 ReadAddr);																			
PEXT uint8_t BCD_DEC(u8 val);		
PEXT uint8_t DEC_BCD(u8 val);
PEXT void i2c_SendByte(uint8_t _ucByte);
PEXT void I2C_DS3231_SetTime(u8 yea,u8 mon,u8 da,u8 we,u8 hou,u8 min,u8 sec);
PEXT void Time_Regulate_Get(_calendar_obj *tm);

PEXT void I2C_DS3231_getTime(void);
PEXT void I2C_DS3231_getTemperature(void);

PEXT void GregorianDay(_calendar_obj * tm);

#undef PEXT
#endif

/*********************************************END OF FILE**********************/

二、初始化与函数

#define		_I2C_DS3231_PUBLIC_
#include	"common.h"


/**
  ******************************************************************************
  * @file    bsp_i2c_ds3231.c 
  * @author  兲涳
  * @version V1.0
  * @date    2020-11-16
  * @brief   i2c RTC(DS3231)应用函数bsp
  ******************************************************************************
  * @attention
  * 
  ******************************************************************************
  */


/**
  * @brief  转换成BCD码
  * @param  None
  * @retval 返回BCD码
  */
u16 B_BCD(u8 val)
{
  u8 i,j,k;
  i=val/10;
  j=val%10;
  k=j+(i<<4);
  return k;
}

/**
  * @brief  I2C I/O配置
  * @param  None
  * @retval None
  */
static void I2C_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_Initure;
	
	/* 使能与 I2C 有关的时钟 */
  	__HAL_RCC_GPIOC_CLK_ENABLE();           	// 使能GPIOC端口时钟
	
	/* I2C_SCL、I2C_SDA*/
  	GPIO_Initure.Mode=GPIO_MODE_OUTPUT_OD;  	//开漏输出
	GPIO_Initure.Pull=GPIO_PULLUP;          	//上拉
	GPIO_Initure.Speed=GPIO_SPEED_HIGH;    	 	//高速	
	GPIO_Initure.Pin=GPIO_PIN_10|GPIO_PIN_11; 						//PC3
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10|GPIO_PIN_11,GPIO_PIN_SET);	//初始化后置1
}

/**
  * @brief  I2C 外设(DS3231)初始化
  * @param  None
  * @retval None
  */
void I2C_DS3231_Init(void)
{
  I2C_GPIO_Config(); 
	
	/* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
	i2c_Stop();
}

/**
  * @brief  I2C总线位延迟,最快400KHz
  * @param  None
  * @retval None
  */
static void i2c_Delay(void)
{
	uint8_t i;

	/* 
	 	下面的时间是通过逻辑分析仪测试得到的。
    工作条件:CPU主频72MHz ,MDK编译环境,1级优化
  
		循环次数为10时,SCL频率 = 205KHz 
		循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 
	 	循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us 
	*/
	for (i = 0; i < 10; i++);
}

/**
  * @brief  I2C总线启动信号
  * @param  None
  * @retval None
  */
void i2c_Start(void)
{
	/* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
	I2C_SDA_1();
	I2C_SCL_1();
	i2c_Delay();
	I2C_SDA_0();
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();
}

/**
  * @brief  I2C总线停止信号
  * @param  None
  * @retval None
  */
void i2c_Stop(void)
{
	/* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
	I2C_SDA_0();
	I2C_SCL_1();
	i2c_Delay();
	I2C_SDA_1();
}

/**
  * @brief  MCU向I2C总线设备发送8bit数据
  * @param   
  *		@arg 	_ucByte:发送的字节
	* @retval None
  */
void i2c_SendByte(uint8_t _ucByte)
{
	uint8_t i;

	/* 先发送字节的高位bit7 */
	for (i = 0; i < 8; i++)
	{		
		if (_ucByte & 0x80)
		{
			I2C_SDA_1();
		}
		else
		{
			I2C_SDA_0();
		}
		i2c_Delay();
		I2C_SCL_1();
		i2c_Delay();	
		I2C_SCL_0();
		if (i == 7)
		{
			 I2C_SDA_1(); // 释放总线
		}
		_ucByte <<= 1;	/* 左移一个bit */
		i2c_Delay();
	}
}

/**
  * @brief  MCU从I2C总线设备读取8bit数据
  * @param  None
	* @retval 读到的数据
  */
uint8_t i2c_ReadByte(void)
{
	uint8_t i;
	uint8_t value;

	/* 读到第1个bit为数据的bit7 */
	value = 0;
	for (i = 0; i < 8; i++)
	{
		value <<= 1;
		I2C_SCL_1();
		i2c_Delay();
		if (I2C_SDA_READ())
		{
			value++;
		}
		I2C_SCL_0();
		i2c_Delay();
	}
	return value;
}

/**
  * @brief  MCU产生一个时钟,并读取器件的ACK应答信号
  * @param  None
	* @retval 返回0表示正确应答,1表示无器件响应
  */
uint8_t i2c_WaitAck(void)
{
	uint8_t re;

	I2C_SDA_1();	/* CPU释放SDA总线 */
	i2c_Delay();
	I2C_SCL_1();	/* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
	i2c_Delay();
	if (I2C_SDA_READ())	/* CPU读取SDA口线状态 */
	{
		re = 1;
	}
	else
	{
		re = 0;
	}
	I2C_SCL_0();
	i2c_Delay();
	return re;
}

/**
  * @brief  MCU产生一个ACK信号
  * @param  None
	* @retval None
  */
void i2c_Ack(void)
{
	I2C_SDA_0();	/* CPU驱动SDA = 0 */
	i2c_Delay();
	I2C_SCL_1();	/* CPU产生1个时钟 */
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();
	I2C_SDA_1();	/* CPU释放SDA总线 */
}

/**
  * @brief  MCU产生1个NACK信号
  * @param  None
	* @retval None
  */
void i2c_NAck(void)
{
	I2C_SDA_1();	/* CPU驱动SDA = 1 */
	i2c_Delay();
	I2C_SCL_1();	/* CPU产生1个时钟 */
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();	
}

/**
  * @brief  检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
  * @param   
  *		@arg  _Address:设备的I2C总线地址
	* @retval 返回值 0 表示正确, 返回1表示未探测到
  */
uint8_t i2c_CheckDevice(uint8_t _Address)
{
	uint8_t ucAck;

	I2C_DS3231_Init();		/* 配置GPIO */

	
	i2c_Start();		/* 发送启动信号 */

	/* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
	i2c_SendByte(_Address | I2C_WR);
	ucAck = i2c_WaitAck();	/* 检测设备的ACK应答 */

	i2c_Stop();			/* 发送停止信号 */

	return ucAck;
}

//
/**
  * @brief	写一个字节到I2C DS3231中
  * @param   
  *		@arg data:要写入的字节
  *		@arg WriteAddr:写地址 
	* @retval 返回1,表示写入成功.
  */
uint32_t I2C_DS3231_ByteWrite(u8 WriteAddr, u8 data) 
{
	/* 第1步:发起I2C总线启动信号 */
	i2c_Start();
	
	/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
	i2c_SendByte(DS3231_ADDRESS| I2C_WR);	/* 此处是写指令 */
	
	/* 第3步:等待ACK */
	if (i2c_WaitAck() != 0)
	{
 		goto cmd_fail;	/* EEPROM器件无应答 */
	}
	
	/* 第4步:发送寄存器地址 */
	i2c_SendByte((uint8_t)WriteAddr);
	
  /* 第5步:等待ACK */
	if (i2c_WaitAck() != 0)
	{
	  goto cmd_fail;	/* EEPROM器件无应答 */
	}
	
	/* 第6步:开始写入数据 */
	i2c_SendByte(data);
	
	/* 第7步:等待ACK */
	if (i2c_WaitAck() != 0)
	{
		goto cmd_fail;	/* EEPROM器件无应答 */
	}
	
  /* 命令执行成功,发送I2C总线停止信号 */
	i2c_Stop();
	return 1;
cmd_fail: /* 命令执行失败后,发送停止信号 */
	/* 发送I2C总线停止信号 */
	i2c_Stop();
	return 0;
}

/**
  * @brief	从DS3231里面读取一个字节数据 
  * @param   
  *		@arg data:存放从DS3231读取的数据
  *		@arg ReadAddr:读取数据的DS3231的地址
	* @retval data:返回数据.
  */
uint8_t I2C_DS3231_DataRead(u8 ReadAddr)
{
	uint8_t data;

	/* 第1步:发起I2C总线启动信号 */
	i2c_Start();

	/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
	i2c_SendByte(DS3231_ADDRESS|I2C_WR);	/* 此处是写指令 */
  
	/* 第3步:等待ACK */
	if (i2c_WaitAck() != 0)
	{
		goto cmd_fail;	/* EEPROM器件无应答 */
	}
	
	/* 第4步:发送DS3231寄存器地址 */
	i2c_SendByte((uint8_t)ReadAddr);
	
	/* 第5步:等待ACK */
	if (i2c_WaitAck() != 0)
	{
		goto cmd_fail;	/* EEPROM器件无应答 */
	}
	
	/* 第6步:产生第二次 I2C 起始信号 */  
  	i2c_Start();
	
	/* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
	//i2c_SendByte(DS3231_ADDRESS | I2C_RD);	/* 此处是读指令 */
	i2c_SendByte(DS3231_ADDRESS | I2C_RD);	/* 此处是读指令 */
	
	/* 第8步:发送ACK */
	if (i2c_WaitAck() != 0)
	{
		goto cmd_fail;	/* EEPROM器件无应答 */
	}	
   
  	/* 第9步:读取数据 */
	data = i2c_ReadByte(); 
 
  	i2c_NAck();	
	i2c_Stop();
	return data;
	
  	cmd_fail: /* 命令执行失败后,发送停止信号 */
	/* 发送I2C总线停止信号 */
	i2c_Stop();
	return 0;
}

/**
  * @brief	BCD(8421)转DEC.
  * @param  val:BCD码.
  * @retval i:DEC码.
  */
uint8_t BCD_DEC(u8 val)
{
	u8 i;
	i= val&0x0f;
	val >>= 4;
	val &= 0x0f;
	val *= 10;
	i += val;    
	return i;
}

/**
  * @brief	BCD(8421)转DEC.
  * @param  val:DEC码.
  * @retval k:BCD码.
  */
uint8_t DEC_BCD(u8 val)
{
  u8 i,j,k;
  i=val/10;
  j=val%10;
  k=j+(i<<4);
  return k;
}

/**
  * @brief	时间设置
  * @param   
  *		@arg 	分别输入 年 月 日 星期 时 分 秒
  * @retval 无
  */
void I2C_DS3231_SetTime(u8 yea,u8 mon,u8 da,u8 we,u8 hou,u8 min,u8 sec)
{
  u8 temp=0;
  yea-=2000;
  temp=DEC_BCD(yea);
  I2C_DS3231_ByteWrite(0x06,temp);
  temp=DEC_BCD(mon);
  I2C_DS3231_ByteWrite(0x05,temp);
   
  temp=DEC_BCD(da);
  I2C_DS3231_ByteWrite(0x04,temp);
  
//	temp=DEC_BCD(we);
//  I2C_DS3231_ByteWrite(0x03,temp);
	
  temp=DEC_BCD(hou);
  I2C_DS3231_ByteWrite(0x02,temp);
  
  temp=DEC_BCD(min);
  I2C_DS3231_ByteWrite(0x01,temp);
  
  temp=DEC_BCD(sec);
  I2C_DS3231_ByteWrite(0x00,temp);
}	

/**
  * @brief	获取时间
  * @param   
  *		@arg pBuffer:存放从DS3231读取的数据的缓冲区指针
  *		@arg ReadAddr:读取数据的DS3231的地址
  *   @arg NumByteToWrite:要从DS3231读取的字节数
  * @retval 返回1,表示读取成功.
  */
void I2C_DS3231_getTime(void)
{
	calendar.year=I2C_DS3231_DataRead(0x06);  
	calendar.year=BCD_DEC(calendar.year)+2000;

	calendar.month=I2C_DS3231_DataRead(0x05); 
	calendar.month=BCD_DEC(calendar.month);

	calendar.day=I2C_DS3231_DataRead(0x04);  
	calendar.day=BCD_DEC(calendar.day);

	calendar.week=I2C_DS3231_DataRead(0x03);  
	calendar.week=BCD_DEC(calendar.week);

	calendar.hour=I2C_DS3231_DataRead(0x02); 
	calendar.hour&=0x3f;                   
	calendar.hour=BCD_DEC(calendar.hour);

	calendar.min=I2C_DS3231_DataRead(0x01);
	calendar.min=BCD_DEC(calendar.min);


	calendar.sec=I2C_DS3231_DataRead(0x00);
	calendar.sec=BCD_DEC(calendar.sec);
}

/**
  * @brief 保存用户使用串口设置的时间
  * @param   
  *		@arg tm:用于设置RTC时间的结构体指针
  * @retval 
  */
void Time_Regulate_Get(_calendar_obj *tm)
{
	  uint32_t temp_num = 0;
		uint8_t day_max=0 ;

	  printf("\r\n=========================设置时间==================");
		
	  do 
	  {
			printf("\r\n  请输入年份(Please Set Years),范围[2000~2255],输入字符后请加回车:");
			scanf("%d",&temp_num);
			if(temp_num <2000 || temp_num >2255)
			{
				printf("\r\n 您输入的数字是:%d,不符合要求",temp_num);
					  
			}
			else
			{	  
				printf("\n\r  年份被设置为: %d\n\r", temp_num);
        temp_num-=2000;
				DEC_BCD(temp_num);
				tm->year = temp_num;
				break;
			}
	  }while(1);


	 do 
	  {
			printf("\r\n  请输入月份(Please Set Months):范围[1~12],输入字符后请加回车:");
			scanf("%d",&temp_num);
			if(temp_num <1 || temp_num >12)
			{
				printf("\r\n 您输入的数字是:%d,不符合要求",temp_num);
					  
			}
			else
			{	  
				printf("\n\r  月份被设置为: %d\n\r", temp_num);
        DEC_BCD(temp_num);
				tm->month = temp_num;
				break;
			}
	  }while(1);
		
		/*根据月份计算最大日期*/
		switch(tm->month)
			{
				case 1:
				case 3:
				case 5:
				case 7:
				case 8:
				case 10:
				case 12:					
						day_max = 31;
					break;
				
				case 4:
				case 6:
				case 9:
				case 11:
						day_max = 30;
					break;
				
				case 2:					
				     /*计算闰年*/
						if(((tm->year+2000)%4==0) &&
							 (((tm->year+2000)%100!=0) || ((tm->year+2000)%400==0))) 
								{
									day_max = 29;
								} else 
								{
									day_max = 28;
								}
					break;			
			}

		do 
	  {				
			printf("\r\n  请输入日期(Please Set Months),范围[1~%d],输入字符后请加回车:",day_max);
			scanf("%d",&temp_num);
			
			if(temp_num <1 || temp_num >day_max)
			{
				printf("\r\n 您输入的数字是:%d,不符合要求",temp_num);
			}
			else
			{
				printf("\n\r  日期被设置为: %d\n\r", temp_num);
        DEC_BCD(temp_num);
				tm->day = temp_num;
				break;
			}
	  }while(1);
		
		GregorianDay( tm );
		
		do 
	  {				
			printf("\r\n  请输入时钟(Please Set Hours),范围[0~23],输入字符后请加回车:");
			scanf("%d",&temp_num);
			
			if( temp_num >23)
			{
				printf("\r\n 您输入的数字是:%d,不符合要求",temp_num);
			}
			else
			{
				printf("\n\r  时钟被设置为: %d\n\r", temp_num);
        DEC_BCD(temp_num);
				tm->hour = temp_num;
				break;
			}
	  }while(1);

		do 
	  {				
			printf("\r\n  请输入分钟(Please Set Minutes),范围[0~59],输入字符后请加回车:");
			scanf("%d",&temp_num);
			
			if( temp_num >59)
			{
				printf("\r\n 您输入的数字是:%d,不符合要求",temp_num);
			}
			else
			{
				printf("\n\r  分钟被设置为: %d\n\r", temp_num);
        DEC_BCD(temp_num);
				tm->min = temp_num;
				break;
			}
	  }while(1);

		do 
	  {				
			printf("\r\n  请输入秒钟(Please Set Seconds),范围[0~59],输入字符后请加回车:");
			scanf("%d",&temp_num);
			
			if( temp_num >59)
			{
				printf("\r\n 您输入的数字是:%d,不符合要求",temp_num);
			}
			else
			{
				printf("\n\r  秒钟被设置为: %d\n\r", temp_num);
        DEC_BCD(temp_num);
				tm->sec = temp_num;
				break;
			}
	  }while(1);
		__HAL_UART_ENABLE_IT(&UART1_Handler,UART_IT_RXNE);	//开启接收中断
}


/**
  * @brief	获取温度
  * @param  无
  * @retval 无
  */
void I2C_DS3231_getTemperature(void)
{
	I2C_DS3231_ByteWrite(DS3231_CONTROL, 0x20|0x05);
	calendar.temperature=I2C_DS3231_DataRead(DS3231_TEMPERATUREH);
}

/*计算公历天数得出星期*/
void GregorianDay(_calendar_obj * tm)
{
	int leapsToDate;
	int lastYear;
	int day;
	int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };

	lastYear=tm->year-1;

	/*计算从公元元年到计数的前一年之中一共经历了多少个闰年*/
	leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;      

     /*如若计数的这一年为闰年,且计数的月份在2月之后,则日数加1,否则不加1*/
	if((tm->year%4==0) &&
	   ((tm->year%100!=0) || (tm->year%400==0)) &&
	   (tm->month>2)) {
		/*
		 * We are past Feb. 29 in a leap year
		 */
		day=1;
	} else {
		day=0;
	}

	day += lastYear*365 + leapsToDate + MonthOffset[tm->month-1] + tm->day; /*计算从公元元年元旦到计数日期一共有多少天*/

	tm->week=day%7; //算出星期
}

/*********************************************END OF FILE**********************/

三、函数调用(我用标准库的代码,如果在hal库有问题自己改下。调用方式是一样的)

/**
  ******************************************************************************
  * @file    main.c 
  * @author  兲涳
  * @version V1.0
  * @date    2020-11-16
  * @brief   
  ******************************************************************************
  * @attention
  * I2C_2 RTC(DS3231)测试,测试信息通过USART1打印在电脑调试助手上,通过串口设置时间
	* !!!串口输入  t  回车 ,进行设置时间。
  ******************************************************************************
  */  
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "bsp_usart.h"
#include "bsp_i2c_ds3231.h" 
#include 
/* Private typedef -----------------------------------------------------------*/
uint8_t i=0;
extern _calendar_obj calendar;	//日历结构体
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define SOFT_DELAY		Delay(0x4FFFFF);
/* Private variables ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void Delay(__IO u32 nCount); 
/**
  * @brief  主函数
  * @param  无  
  * @retval 无
  */
int main(void)
{ 
	/* 初始化USART 配置模式为 115200 8-N-1 */
  USART_Config();
  printf("\nDS3231   RTC时钟\n");
	/* I2C 外设初(DS3231)始化 */
	I2C_DS3231_Init();
//  I2C_DS3231_SetTime(20,8,24,1,13,43,20);
  while(1)
	{
		SOFT_DELAY;
		if(i==1)
		{
			Time_Regulate_Get( &calendar );
			I2C_DS3231_SetTime(calendar.year, calendar.month, calendar.date, calendar.week, calendar.hour, calendar.min, calendar.sec);
			i=0;
		}
		I2C_DS3231_getTime();		//获取时间
		I2C_DS3231_getTemperature();		//获取温度
		printf("%d年%d月%d日%d时%d分%d秒 星期%d 温度%d\n",calendar.year+2000,calendar.month,calendar.date,\
						calendar.hour,calendar.min,calendar.sec,calendar.week,calendar.temperature);//打印到串口屏不能有printf("\n");换行!!!	
	}
}	
/**
  * @brief  延时函数
  * @param  无  
  * @retval 无
  */
void Delay(__IO uint32_t nCount)	 //简单的延时函数
{
	for(; nCount != 0; nCount--);
}
/*********************************************END OF FILE**********************/

 

 

 

你可能感兴趣的:(Stm32,DS3231时钟模块的,stm32,程序,HAL库)