/** ****************************************************************************** * @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**********************/