STM32CubeMX配置I2C读取DS3231

使用HAL库操作DS3231

因为DSP2这个项目需要计时间功能所以封装了一下这个芯片的程序

硬件设计

在这里插入图片描述
我将它接到了I2C1对应的IO口是(SCL > PB6 | SDA > PB7)

程序封装

CubeMX的I2C配置
在这里插入图片描述

DS3231.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : DS3231.c
  * @brief          : DS3231 program body
  * @author         : Lesterbor
  *	@time			: 2021-09-26
  ******************************************************************************
  * @attention
  *
  *
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

	#include "BSP_DS3231.h"
	#include "i2c.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PT */
	
	uint8_t DS3231Buffer[1];
	uint8_t DS3231TimeBuffer[8];
	int8_t ErrorFlag = 0;
	
/* USER CODE END PT */

/* Function definition -------------------------------------------------------*/
/* USER CODE BEGIN FD */
/**
  * @Function name  BCD_DEC
  * @Introduce  	BCD(8421)转DEC
  * @Parameter		BCD(8421)值	
  * @Return 		DEC值
  */
	uint8_t BCD_DEC(uint8_t BCD_Data){
		uint8_t DEC_Data;
	
		DEC_Data= BCD_Data&0x0f;
		BCD_Data >>= 4;
		BCD_Data &= 0x0f;
		BCD_Data *= 10;
		DEC_Data += BCD_Data;    
		return DEC_Data;
	}
	
/**
  * @Function name  DEC_BCD
  * @Introduce  	DEC转BCD(8421)
  * @Parameter		DEC值	
  * @Return 		BCD(8421)值
  */
	uint8_t DEC_BCD(uint8_t DEC_Data){
		uint8_t BCD_DataA,BCD_DataB,BCD_Data;
		
		BCD_DataA=DEC_Data/10;
		BCD_DataB=DEC_Data%10;
		BCD_Data=BCD_DataB+(BCD_DataA<<4);
		return BCD_Data;
	}
	
/**
  * @Function name  I2C_DS3231_ReadData
  * @Introduce  		DS3231通过I2C读取一个字节
	* @Parameter			ReadAddr I2C读取地址
  * @Return 				失败返回 -1 成功返回 0
  */
	uint8_t I2C_DS3231_ReadData(uint8_t ReadAddr){
		uint8_t DS3231_DataAddr[1];
		DS3231_DataAddr[0]= ReadAddr;

		if(HAL_I2C_Master_Transmit(&hi2c1,(DS3231_ADDRESS|I2C_WR),DS3231_DataAddr,sizeof(DS3231_DataAddr), 1000) != HAL_OK){
			ErrorFlag = -1;
			return ErrorFlag;
		}
		if(HAL_I2C_Master_Receive(&hi2c1,(DS3231_ADDRESS|I2C_RD),DS3231Buffer,sizeof(DS3231Buffer), 1000) != HAL_OK){
			ErrorFlag = -1;
			return ErrorFlag;
		}
		return ErrorFlag;	
	}

/**
  * @Function name  I2C_DS3231_WriteData
  * @Introduce  	DS3231通过I2C写一个字节
  * @Parameter		WriteAddr I2C写入地址 Data I2C写入数据
  * @Return 		失败返回 -1 成功返回 0
  */
	uint8_t I2C_DS3231_WriteData(uint8_t WriteAddr,uint8_t Data){
		uint8_t DS3231_Data[2];
 		DS3231_Data[0]	= WriteAddr;
		DS3231_Data[1]	= Data;
		
		if(HAL_I2C_Master_Transmit(&hi2c1,(DS3231_ADDRESS|I2C_WR),DS3231_Data,sizeof(DS3231_Data), 1000) != HAL_OK){
			ErrorFlag = -1;
			return ErrorFlag;
		}
		return ErrorFlag;	
	}
	
/**
  * @Function name  DS3231_SetTime
  * @Introduce  	DS3231通过I2C设置时间
  * @Parameter		Yea 年份范围在0~99
  *					Mon	月份范围在0~12
  *					Dat	日	范围在1~31
  *					Wee	周	范围在1~7
  *					Hou	小时范围在0~23
  *					Min	分钟范围在0~59
  *					Sec	秒	范围在0~59
  * @Return 		NULL
  */
	void DS3231_SetTime(uint8_t Yea,uint8_t Mon,uint8_t Dat,uint8_t Wee,uint8_t Hou,uint8_t Min,uint8_t Sec){
		I2C_DS3231_WriteData(Year_Register		,DEC_BCD(Yea));
		I2C_DS3231_WriteData(Month_Register		,DEC_BCD(Mon));
		I2C_DS3231_WriteData(Date_Register		,DEC_BCD(Dat));
		I2C_DS3231_WriteData(Day_Register			,DEC_BCD(Wee));
		I2C_DS3231_WriteData(Hour_Register		,DEC_BCD(Hou));
		I2C_DS3231_WriteData(Minutes_Register	,DEC_BCD(Min));
		I2C_DS3231_WriteData(Seconds_Register	,DEC_BCD(Sec));
	}
	
/**
  * @Function name  DS3231_ReadTime
  * @Introduce  	DS3231通过I2C读取时间
  * @Return 		NULL
  */
	void DS3231_ReadTime(void){
		
		I2C_DS3231_ReadData(Seconds_Register);
		DS3231TimeBuffer[7] = BCD_DEC(DS3231Buffer[0]);
		I2C_DS3231_ReadData(Minutes_Register);
		DS3231TimeBuffer[6] = BCD_DEC(DS3231Buffer[0]);
		I2C_DS3231_ReadData(Hour_Register);
		DS3231TimeBuffer[5] = BCD_DEC(DS3231Buffer[0]);
		I2C_DS3231_ReadData(Day_Register);
		DS3231TimeBuffer[4] = BCD_DEC(DS3231Buffer[0]);
		I2C_DS3231_ReadData(Date_Register);
		DS3231TimeBuffer[3] = BCD_DEC(DS3231Buffer[0]);
		I2C_DS3231_ReadData(Month_Register);
		DS3231TimeBuffer[2] = BCD_DEC(DS3231Buffer[0]);
		I2C_DS3231_ReadData(Year_Register);
		DS3231TimeBuffer[1] = BCD_DEC(DS3231Buffer[0]);
	}
	
/**
  * @Function name  DS3231_ReadTime_ReturnPoint
  * @Introduce  	将读到的时间数据通过指针返回 
  * @attention		DS3231_ReadTime_ReturnPoint()[7] 秒数据
  *					DS3231_ReadTime_ReturnPoint()[6] 分数据
  *					DS3231_ReadTime_ReturnPoint()[5] 时数据
  *					DS3231_ReadTime_ReturnPoint()[4] 周数据
  *					DS3231_ReadTime_ReturnPoint()[3] 日数据
  *					DS3231_ReadTime_ReturnPoint()[2] 月数据
  *					DS3231_ReadTime_ReturnPoint()[1] 年数据
  *					DS3231_ReadTime_ReturnPoint()[0] 空数据
  * @Return 		NULL
  */
	uint8_t *DS3231_ReadTime_ReturnPoint(void){
		return DS3231TimeBuffer;
	}

/* USER CODE END FD */
/************************ (C) COPYRIGHT Lesterbor *****END OF FILE****/

DS3231.h

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : DS3231.h
  * @brief          : Header for DS3231.c file.
  *                   This file provides code for the configuration
  *                   of the DS3231 instances
  * @author         : Lesterbor
  *	@time			:	2021-09-26
  ******************************************************************************
  * @attention
  *
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DS3231_H_
#define __DS3231_H_
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

	#include "main.h"
	
/* USER CODE END Includes */
	
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PT */



	#define 	I2C_WR					0x00		//写指令
	#define 	I2C_RD					0x01		//读指令
	#define 	DS3231_ADDRESS 			0xD0   		//DS3231地址
	
	#define 	Seconds_Register      	0x00     	//秒钟寄存器
	#define 	Minutes_Register		0x01     	//分钟寄存器
	#define 	Hour_Register  			0x02     	//小时寄存器
	#define 	Day_Register       		0x03     	//星期寄存器
	#define 	Date_Register      		0x04		//日期寄存器
	#define	 	Month_Register     		0x05    	//月份寄存器(第七位是世纪位)
	#define 	Year_Register       	0x06    	//年份寄存器

/* USER CODE END PT */
	
/* Exported functions prototypes ---------------------------------------------*/
/* USER CODE BEGIN EFP */

	uint8_t BCD_DEC(uint8_t BCD_Data);
	uint8_t DEC_BCD(uint8_t DEC_Data);
	uint8_t I2C_DS3231_ReadData(uint8_t ReadAddr);
	uint8_t I2C_DS3231_WriteData(uint8_t WriteAddr,uint8_t Data);
	void DS3231_SetTime(uint8_t Yea,uint8_t Mon,uint8_t Dat,uint8_t Wee,uint8_t Hou,uint8_t Min,uint8_t Sec);
	void DS3231_ReadTime(void);
	uint8_t *DS3231_ReadTime_ReturnPoint(void);

/* USER CODE END EFP */

#endif /* __DS3231_H_ */
/************************ (C) COPYRIGHT Lesterbor *****END OF FILE*************/

使用方法

		DS3231_ReadTime();
		printf("Now Time :\n20%02d-%02d-%02d-%02d-%02d-%02d",
			DS3231_ReadTime_ReturnPoint()[1],
			DS3231_ReadTime_ReturnPoint()[2],
			DS3231_ReadTime_ReturnPoint()[3],
			DS3231_ReadTime_ReturnPoint()[5],
			DS3231_ReadTime_ReturnPoint()[6],
			DS3231_ReadTime_ReturnPoint()[7]
		);

注意:每次取数据之前必须先读数据

实验现象请添加图片描述

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
STM32F103是一款基于ARM Cortex-M3内核的微控制器,有丰富的外设资源。其中包括硬件I2C接口,可以用于连接DS3231时钟芯片。 DS3231是一款高精度的实时时钟芯片,可以提供秒、分、时、日、月、年等多种时间信息,并支持温度补偿功能。 在实现硬件I2C读写DS3231的程序中,需要先定义好相关的I2C参数,包括芯片地址、传输速率等。然后通过STM32F103的I2C外设库函数,可以方便地向DS3231写入或读取相关的数据。 需要注意的是,DS3231芯片提供了多种时间格式,如BCD码、十进制等。在程序中需要根据具体的应用场景选择合适的时间格式,并进行相应的转换。 代码示例: 1. 定义I2C参数 #define DS3231_ADDR 0xD0 #define I2C_SPEED 200000 2. 初始化I2C接口 I2C_InitTypeDef I2C_InitStructure; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; I2C_Cmd(I2C1, ENABLE); 3. 写入时间信息 uint8_t TimeBuf[7]; for(int i=0; i<7; i++){ TimeBuf[i] = ... //根据具体格式填充时间数据 } I2C_Start(); I2C_SendData(DS3231_ADDR<<1); I2C_WaitAck(); I2C_SendData(0x00); I2C_WaitAck(); for(int i=0; i<7; i++){ I2C_SendData(TimeBuf[i]); I2C_WaitAck(); } I2C_Stop(); 4. 读取时间信息 uint8_t TimeBuf[7]; I2C_Start(); I2C_SendData(DS3231_ADDR<<1); I2C_WaitAck(); I2C_SendData(0x00); I2C_WaitAck(); I2C_Start(); I2C_SendData((DS3231_ADDR<<1)|0x01); I2C_WaitAck(); for(int i=0; i<6; i++){ TimeBuf[i] = I2C_ReceiveData(); I2C_Ack(); } TimeBuf[6] = I2C_ReceiveData(); I2C_Stop(); 以上代码示例仅为示范,实际使用时需要根据具体情况进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值