使用HAL库操作DS3231
因为DSP2这个项目需要计时间功能所以封装了一下这个芯片的程序
硬件设计
我将它接到了I2C1对应的IO口是(SCL > PB6 | SDA > PB7)
程序封装
CubeMX的I2C配置
DS3231.c
#include "BSP_DS3231.h"
#include "i2c.h"
uint8_t DS3231Buffer[1];
uint8_t DS3231TimeBuffer[8];
int8_t ErrorFlag = 0;
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;
}
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;
}
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;
}
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;
}
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));
}
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]);
}
uint8_t *DS3231_ReadTime_ReturnPoint(void){
return DS3231TimeBuffer;
}
DS3231.h
#ifndef __DS3231_H_
#define __DS3231_H_
#include "main.h"
#define I2C_WR 0x00
#define I2C_RD 0x01
#define DS3231_ADDRESS 0xD0
#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
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);
#endif
使用方法
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]
);
注意:每次取数据之前必须先读数据
实验现象
|