261 lines
6.6 KiB
C
261 lines
6.6 KiB
C
/**
|
||
******************************************************************************
|
||
* @file bsp_i2c_ee.c
|
||
* @author STMicroelectronics
|
||
* @version V1.0
|
||
* @date 2015-xx-xx
|
||
* @brief i2c EEPROM(AT24C02)应用函数bsp
|
||
******************************************************************************
|
||
* @attention
|
||
*
|
||
* 实验平台:秉火 STM32 H750 开发板
|
||
* 论坛 :http://www.firebbs.cn
|
||
* 淘宝 :http://firestm32.taobao.com
|
||
*
|
||
******************************************************************************
|
||
*/
|
||
|
||
#include "./i2c/bsp_i2c_ee.h"
|
||
#include "./usart/bsp_debug_usart.h"
|
||
|
||
|
||
I2C_HandleTypeDef I2C_Handle;
|
||
|
||
/**
|
||
* @brief I2C1 I/O配置
|
||
* @param 无
|
||
* @retval 无
|
||
*/
|
||
static void I2C_GPIO_Config(void)
|
||
{
|
||
|
||
GPIO_InitTypeDef GPIO_InitStructure;
|
||
// RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
|
||
|
||
/*使能I2C时钟*/
|
||
EEPROM_I2C_CLK_ENABLE();
|
||
|
||
/*使能I2C的IO口时钟*/
|
||
EEPROM_I2C_SCL_GPIO_CLK_ENABLE();
|
||
EEPROM_I2C_SDA_GPIO_CLK_ENABLE();
|
||
|
||
/*配置I2C的SCL口*/
|
||
GPIO_InitStructure.Pin = EEPROM_I2C_SCL_PIN;
|
||
GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
|
||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
|
||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||
GPIO_InitStructure.Alternate = EEPROM_I2C_SCL_AF;
|
||
HAL_GPIO_Init(EEPROM_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
|
||
|
||
/*配置I2C的SDA口*/
|
||
GPIO_InitStructure.Pin = EEPROM_I2C_SDA_PIN;
|
||
HAL_GPIO_Init(EEPROM_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
|
||
|
||
/* Force the I2C peripheral clock reset */
|
||
EEPROM_I2C_FORCE_RESET();
|
||
|
||
/* Release the I2C peripheral clock reset */
|
||
EEPROM_I2C_RELEASE_RESET();
|
||
|
||
}
|
||
|
||
/**
|
||
* @brief I2C 工作模式配置
|
||
* @param 无
|
||
* @retval 无
|
||
*/
|
||
static void I2C_Mode_Config(void)
|
||
{
|
||
/* I2C 配置 */
|
||
I2C_Handle.Instance = EEPROM_I2C;
|
||
I2C_Handle.Init.Timing = 0x40604E73;//100KHz
|
||
I2C_Handle.Init.OwnAddress1 = 0;
|
||
I2C_Handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||
I2C_Handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||
I2C_Handle.Init.OwnAddress2 = 0;
|
||
I2C_Handle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
|
||
I2C_Handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||
I2C_Handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||
|
||
/* Init the I2C */
|
||
HAL_I2C_Init(&I2C_Handle);
|
||
|
||
HAL_I2CEx_AnalogFilter_Config(&I2C_Handle, I2C_ANALOGFILTER_ENABLE);
|
||
}
|
||
|
||
/**
|
||
* @brief I2C 外设(EEPROM)初始化
|
||
* @param 无
|
||
* @retval 无
|
||
*/
|
||
void I2C_EE_Init(void)
|
||
{
|
||
|
||
I2C_GPIO_Config();
|
||
I2C_Mode_Config();
|
||
|
||
}
|
||
|
||
/**
|
||
* @brief 将缓冲区中的数据写到I2C EEPROM中
|
||
* @param
|
||
* @arg pBuffer:缓冲区指针
|
||
* @arg WriteAddr:写地址
|
||
* @arg NumByteToWrite:写的字节数
|
||
* @retval 无
|
||
*/
|
||
void I2C_EE_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
|
||
{
|
||
uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
|
||
|
||
Addr = WriteAddr % EEPROM_PAGESIZE;
|
||
count = EEPROM_PAGESIZE - Addr;
|
||
NumOfPage = NumByteToWrite / EEPROM_PAGESIZE;
|
||
NumOfSingle = NumByteToWrite % EEPROM_PAGESIZE;
|
||
|
||
/* If WriteAddr is I2C_PageSize aligned */
|
||
if(Addr == 0)
|
||
{
|
||
/* If NumByteToWrite < I2C_PageSize */
|
||
if(NumOfPage == 0)
|
||
{
|
||
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
|
||
}
|
||
/* If NumByteToWrite > I2C_PageSize */
|
||
else
|
||
{
|
||
while(NumOfPage--)
|
||
{
|
||
I2C_EE_PageWrite(pBuffer, WriteAddr, EEPROM_PAGESIZE);
|
||
WriteAddr += EEPROM_PAGESIZE;
|
||
pBuffer += EEPROM_PAGESIZE;
|
||
}
|
||
|
||
if(NumOfSingle!=0)
|
||
{
|
||
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
|
||
}
|
||
}
|
||
}
|
||
/* If WriteAddr is not I2C_PageSize aligned */
|
||
else
|
||
{
|
||
/* If NumByteToWrite < I2C_PageSize */
|
||
if(NumOfPage== 0)
|
||
{
|
||
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
|
||
}
|
||
/* If NumByteToWrite > I2C_PageSize */
|
||
else
|
||
{
|
||
NumByteToWrite -= count;
|
||
NumOfPage = NumByteToWrite / EEPROM_PAGESIZE;
|
||
NumOfSingle = NumByteToWrite % EEPROM_PAGESIZE;
|
||
|
||
if(count != 0)
|
||
{
|
||
I2C_EE_PageWrite(pBuffer, WriteAddr, count);
|
||
WriteAddr += count;
|
||
pBuffer += count;
|
||
}
|
||
|
||
while(NumOfPage--)
|
||
{
|
||
I2C_EE_PageWrite(pBuffer, WriteAddr, EEPROM_PAGESIZE);
|
||
WriteAddr += EEPROM_PAGESIZE;
|
||
pBuffer += EEPROM_PAGESIZE;
|
||
}
|
||
if(NumOfSingle != 0)
|
||
{
|
||
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 写一个字节到I2C EEPROM中
|
||
* @param
|
||
* @arg pBuffer:缓冲区指针
|
||
* @arg WriteAddr:写地址
|
||
* @retval 无
|
||
*/
|
||
uint32_t I2C_EE_ByteWrite(uint8_t* pBuffer, uint8_t WriteAddr)
|
||
{
|
||
HAL_StatusTypeDef status = HAL_OK;
|
||
|
||
status = HAL_I2C_Mem_Write(&I2C_Handle, EEPROM_ADDRESS, (uint16_t)WriteAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, 1, 100);
|
||
|
||
/* Check the communication status */
|
||
if(status != HAL_OK)
|
||
{
|
||
/* Execute user timeout callback */
|
||
//I2Cx_Error(Addr);
|
||
}
|
||
while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)
|
||
{
|
||
|
||
}
|
||
|
||
/* Check if the EEPROM is ready for a new operation */
|
||
while (HAL_I2C_IsDeviceReady(&I2C_Handle, EEPROM_ADDRESS, EEPROM_MAX_TRIALS, I2Cx_TIMEOUT_MAX) == HAL_TIMEOUT);
|
||
|
||
/* Wait for the end of the transfer */
|
||
while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)
|
||
{
|
||
|
||
}
|
||
return status;
|
||
}
|
||
|
||
/**
|
||
* @brief 在EEPROM的一个写循环中可以写多个字节,但一次写入的字节数
|
||
* 不能超过EEPROM页的大小,AT24C02每页有8个字节
|
||
* @param
|
||
* @arg pBuffer:缓冲区指针
|
||
* @arg WriteAddr:写地址
|
||
* @arg NumByteToWrite:写的字节数
|
||
* @retval 无
|
||
*/
|
||
uint32_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint8_t NumByteToWrite)
|
||
{
|
||
HAL_StatusTypeDef status = HAL_OK;
|
||
/* Write EEPROM_PAGESIZE */
|
||
status=HAL_I2C_Mem_Write(&I2C_Handle, EEPROM_ADDRESS,WriteAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t*)(pBuffer),NumByteToWrite, 100);
|
||
|
||
while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)
|
||
{
|
||
|
||
}
|
||
|
||
/* Check if the EEPROM is ready for a new operation */
|
||
while (HAL_I2C_IsDeviceReady(&I2C_Handle, EEPROM_ADDRESS, EEPROM_MAX_TRIALS, I2Cx_TIMEOUT_MAX) == HAL_TIMEOUT);
|
||
|
||
/* Wait for the end of the transfer */
|
||
while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)
|
||
{
|
||
|
||
}
|
||
return status;
|
||
}
|
||
|
||
/**
|
||
* @brief 从EEPROM里面读取一块数据
|
||
* @param
|
||
* @arg pBuffer:存放从EEPROM读取的数据的缓冲区指针
|
||
* @arg WriteAddr:接收数据的EEPROM的地址
|
||
* @arg NumByteToWrite:要从EEPROM读取的字节数
|
||
* @retval 无
|
||
*/
|
||
uint32_t I2C_EE_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead)
|
||
{
|
||
HAL_StatusTypeDef status = HAL_OK;
|
||
|
||
status=HAL_I2C_Mem_Read(&I2C_Handle,EEPROM_ADDRESS,ReadAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t *)pBuffer, NumByteToRead,1000);
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
/*********************************************END OF FILE**********************/
|