HC32F460PETB写8563的驱动
时间: 2023-09-30 20:09:58 浏览: 196
下面是基于HC32F460PETB的8563实时时钟驱动程序示例:
```c
#include "hc32f460.h"
#include "hc32f4a0_utility.h"
#define RTC_I2C_ADDRESS 0xA2U /*!< RTC I2C Address */
/* I2C function */
#define I2C_UNIT M4_I2C1
#define I2C_MASTER_WRITE_ADDRESS 0x00U
#define I2C_MASTER_READ_ADDRESS 0x01U
/**
* @brief Configure the I2C peripheral for RTC communication.
* @param None
* @retval None
*/
static void I2C_RTC_Configuration(void)
{
stc_i2c_init_t stcI2cInit;
stc_i2c_irq_cb_t stcI2cIrqCallBack;
/* Enable peripheral clock */
PWC_Fcg1PeriphClockCmd(PWC_FCG1_IIC1, Enable);
/* Initialize I2C master */
MEM_ZERO_STRUCT(stcI2cInit);
stcI2cInit.u32Baudrate = 100000UL;
stcI2cInit.u32I2cClkDiv = I2C_CLK_DIV1;
stcI2cInit.u32SclTime = I2C_SCL_TIME;
stcI2cInit.u8AddrMode = I2C_ADDR_7BIT;
stcI2cInit.u8GeneralCall = I2C_GC_DISABLE;
stcI2cInit.u8SlaveAddr = (RTC_I2C_ADDRESS << 1U);
I2C_Init(I2C_UNIT, &stcI2cInit);
/* Configure I2C interrupt */
MEM_ZERO_STRUCT(stcI2cIrqCallBack);
stcI2cIrqCallBack.pfnTxIrqCb = NULL;
stcI2cIrqCallBack.pfnRxIrqCb = NULL;
stcI2cIrqCallBack.pfnStopDetectIrqCb = NULL;
stcI2cIrqCallBack.pfnSlaveAddr0DetectIrqCb = NULL;
stcI2cIrqCallBack.pfnSlaveAddr1DetectIrqCb = NULL;
stcI2cIrqCallBack.pfnSlaveAddr2DetectIrqCb = NULL;
stcI2cIrqCallBack.pfnSlaveAddr3DetectIrqCb = NULL;
stcI2cIrqCallBack.pfnSlaveAddr4DetectIrqCb = NULL;
stcI2cIrqCallBack.pfnSlaveAddr5DetectIrqCb = NULL;
stcI2cIrqCallBack.pfnSlaveAddr6DetectIrqCb = NULL;
stcI2cIrqCallBack.pfnSlaveAddr7DetectIrqCb = NULL;
I2C_IrqInit(I2C_UNIT, &stcI2cIrqCallBack);
/* Enable I2C */
I2C_Cmd(I2C_UNIT, Enable);
}
/**
* @brief Write data to RTC over I2C.
* @param [in] u8RegAddr RTC register address
* @param [in] pu8Data Pointer to data buffer to write
* @param [in] u32DataLen Length of data to write
* @retval None
*/
static void RTC_I2C_Write(uint8_t u8RegAddr, const uint8_t *pu8Data, uint32_t u32DataLen)
{
stc_i2c_transfer_t stcTransfer;
/* Configure I2C transfer */
MEM_ZERO_STRUCT(stcTransfer);
stcTransfer.u8DevAddr = (RTC_I2C_ADDRESS << 1U) | I2C_MASTER_WRITE_ADDRESS;
stcTransfer.enMode = I2cTransMode;
stcTransfer.u32DataLen = u32DataLen + 1UL;
stcTransfer.pu8Data = M4_OSPI_ALLOC(u32DataLen + 1UL);
stcTransfer.pu8Data[0UL] = u8RegAddr;
if (NULL != pu8Data)
{
memcpy(&stcTransfer.pu8Data[1UL], pu8Data, u32DataLen);
}
I2C_MasterTransfer(I2C_UNIT, &stcTransfer, I2C_TIMEOUT);
/* Free allocated memory */
if (NULL != stcTransfer.pu8Data)
{
M4_OSPI_FREE(stcTransfer.pu8Data);
}
}
/**
* @brief Read data from RTC over I2C.
* @param [in] u8RegAddr RTC register address
* @param [out] pu8Data Pointer to data buffer to read
* @param [in] u32DataLen Length of data to read
* @retval None
*/
static void RTC_I2C_Read(uint8_t u8RegAddr, uint8_t *pu8Data, uint32_t u32DataLen)
{
stc_i2c_transfer_t stcTransfer;
/* Configure I2C transfer */
MEM_ZERO_STRUCT(stcTransfer);
stcTransfer.u8DevAddr = (RTC_I2C_ADDRESS << 1U) | I2C_MASTER_READ_ADDRESS;
stcTransfer.enMode = I2cReceiveMode;
stcTransfer.u32DataLen = u32DataLen;
stcTransfer.pu8Data = pu8Data;
I2C_MasterTransfer(I2C_UNIT, &stcTransfer, I2C_TIMEOUT);
}
/**
* @brief Configure the RTC.
* @param None
* @retval None
*/
static void RTC_Configuration(void)
{
uint8_t u8Reg;
/* Enable battery backup for RTC */
PWC_BackupAccessCmd(Enable);
/* Configure RTC */
u8Reg = 0x00U; /* Control register 1 */
u8Reg |= 0x80U; /* Enable RTC */
u8Reg |= 0x04U; /* Set 24-hour mode */
RTC_I2C_Write(0x00U, &u8Reg, 1UL);
u8Reg = 0x01U; /* Control register 2 */
u8Reg |= 0x40U; /* Enable alarm interrupt */
RTC_I2C_Write(0x01U, &u8Reg, 1UL);
u8Reg = 0x02U; /* Control register 3 */
u8Reg |= 0x08U; /* Enable battery backup */
RTC_I2C_Write(0x02U, &u8Reg, 1UL);
}
/**
* @brief Set the RTC time.
* @param [in] pstcTime Pointer to RTC time structure
* @retval None
*/
void RTC_SetTime(const stc_rtc_time_t *pstcTime)
{
uint8_t u8Data[3];
/* Write time */
u8Data[0] = pstcTime->u8Second;
u8Data[1] = pstcTime->u8Minute;
u8Data[2] = pstcTime->u8Hour;
RTC_I2C_Write(0x02U, u8Data, 3UL);
}
/**
* @brief Set the RTC date.
* @param [in] pstcDate Pointer to RTC date structure
* @retval None
*/
void RTC_SetDate(const stc_rtc_date_t *pstcDate)
{
uint8_t u8Data[4];
/* Write date */
u8Data[0] = pstcDate->u8DayOfWeek;
u8Data[1] = pstcDate->u8Day;
u8Data[2] = pstcDate->u8Month;
u8Data[3] = pstcDate->u8Year;
RTC_I2C_Write(0x05U, u8Data, 4UL);
}
/**
* @brief Get the RTC time.
* @param [out] pstcTime Pointer to RTC time structure
* @retval None
*/
void RTC_GetTime(stc_rtc_time_t *pstcTime)
{
uint8_t u8Data[3];
/* Read time */
RTC_I2C_Read(0x02U, u8Data, 3UL);
pstcTime->u8Second = u8Data[0];
pstcTime->u8Minute = u8Data[1];
pstcTime->u8Hour = u8Data[2];
}
/**
* @brief Get the RTC date.
* @param [out] pstcDate Pointer to RTC date structure
* @retval None
*/
void RTC_GetDate(stc_rtc_date_t *pstcDate)
{
uint8_t u8Data[4];
/* Read date */
RTC_I2C_Read(0x05U, u8Data, 4UL);
pstcDate->u8DayOfWeek = u8Data[0];
pstcDate->u8Day = u8Data[1];
pstcDate->u8Month = u8Data[2];
pstcDate->u8Year = u8Data[3];
}
/**
* @brief Set the RTC alarm time.
* @param [in] pstcTime Pointer to RTC time structure
* @retval None
*/
void RTC_SetAlarm(const stc_rtc_time_t *pstcTime)
{
uint8_t u8Data[3];
/* Write alarm */
u8Data[0] = pstcTime->u8Second;
u8Data[1] = pstcTime->u8Minute;
u8Data[2] = pstcTime->u8Hour;
RTC_I2C_Write(0x09U, u8Data, 3UL);
}
```
在使用此驱动程序之前,您需要首先调用 `I2C_RTC_Configuration` 函数来配置I2C总线,然后调用 `RTC_Configuration` 函数来配置RTC。然后,您可以使用 `RTC_SetTime`、`RTC_SetDate` 和 `RTC_SetAlarm` 函数来设置RTC时间、日期和闹钟,并使用 `RTC_GetTime` 和 `RTC_GetDate` 函数来读取当前时间和日期。需要根据8563实时时钟的数据手册来了解和配置其他功能。
阅读全文