/** ****************************************************************************** * @file bsp_i2c.c * @author fire * @version V1.0 * @date 2019-xx-xx * @brief I2C 配置文件 ****************************************************************************** * @attention * * 实验平台:野火 STM32 H750 开发板 * 论坛 :http://www.firebbs.cn * 淘宝 :http://firestm32.taobao.com * ****************************************************************************** */ #include "./i2c/bsp_i2c.h" I2C_HandleTypeDef I2C_Handle; /** * @brief I2C MSP Initialization * This function configures the hardware resources used in this example: * - Peripheral's clock enable * - Peripheral's GPIO Configuration * - DMA configuration for transmission request by peripheral * - NVIC configuration for DMA interrupt request enable * @param hi2c: I2C handle pointer * @retval None */ void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) { GPIO_InitTypeDef GPIO_InitStruct; /*##-1- Enable peripherals and GPIO Clocks #################################*/ /* Enable GPIO TX/RX clock */ I2Cx_SCL_GPIO_CLK_ENABLE(); I2Cx_SDA_GPIO_CLK_ENABLE(); /* Enable I2C1 clock */ I2Cx_CLK_ENABLE(); /*##-2- Configure peripheral GPIO ##########################################*/ /* I2C TX GPIO pin configuration */ GPIO_InitStruct.Pin = I2Cx_SCL_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = I2Cx_SCL_AF; HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct); /* I2C RX GPIO pin configuration */ GPIO_InitStruct.Pin = I2Cx_SDA_PIN; GPIO_InitStruct.Alternate = I2Cx_SDA_AF; HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct); /* Force the I2C peripheral clock reset */ I2Cx_FORCE_RESET() ; /* Release the I2C peripheral clock reset */ I2Cx_RELEASE_RESET(); } /** * @brief I2C 工作模式配置 * @param 无 * @retval 无 */ void I2C_Mode_Config(void) { I2Cx_CLK_ENABLE(); HAL_I2C_MspInit(&I2C_Handle); I2C_Handle.Instance = I2Cx; I2C_Handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; I2C_Handle.Init.Timing = 0x40604E73;//100KHz I2C_Handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; I2C_Handle.Init.OwnAddress2Masks = I2C_OA2_NOMASK; I2C_Handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; I2C_Handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; I2C_Handle.Init.OwnAddress1 = 0 ; I2C_Handle.Init.OwnAddress2 = 0; /* Init the I2C */ HAL_I2C_Init(&I2C_Handle); HAL_I2CEx_AnalogFilter_Config(&I2C_Handle, I2C_ANALOGFILTER_ENABLE); } /** * @brief Manages error callback by re-initializing I2C. * @param Addr: I2C Address * @retval None */ static void I2Cx_Error(uint8_t Addr) { /* 恢复I2C寄存器为默认值 */ HAL_I2C_DeInit(&I2C_Handle); /* 重新初始化I2C外设 */ I2C_Mode_Config(); } /** * @brief 写寄存器,这是提供给上层的接口 * @param slave_addr: 从机地址 * @param reg_addr:寄存器地址 * @param len:写入的长度 * @param data_ptr:指向要写入的数据 * @retval 正常为0,不正常为非0 */ int Sensors_I2C_WriteRegister(unsigned char slave_addr, unsigned char reg_addr, unsigned short len, unsigned char *data_ptr) { HAL_StatusTypeDef status = HAL_OK; status = HAL_I2C_Mem_Write(&I2C_Handle, slave_addr, reg_addr, I2C_MEMADD_SIZE_8BIT,data_ptr, len,I2Cx_FLAG_TIMEOUT); /* 检查通讯状态 */ if(status != HAL_OK) { /* 总线出错处理 */ I2Cx_Error(slave_addr); } while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY) { } /* 检查SENSOR是否就绪进行下一次读写操作 */ while (HAL_I2C_IsDeviceReady(&I2C_Handle, slave_addr, I2Cx_FLAG_TIMEOUT, I2Cx_FLAG_TIMEOUT) == HAL_TIMEOUT); /* 等待传输结束 */ while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY) { } return status; } /** * @brief 读寄存器,这是提供给上层的接口 * @param slave_addr: 从机地址 * @param reg_addr:寄存器地址 * @param len:要读取的长度 * @param data_ptr:指向要存储数据的指针 * @retval 正常为0,不正常为非0 */ int Sensors_I2C_ReadRegister(unsigned char slave_addr, unsigned char reg_addr, unsigned short len, unsigned char *data_ptr) { HAL_StatusTypeDef status = HAL_OK; status =HAL_I2C_Mem_Read(&I2C_Handle,slave_addr,reg_addr,I2C_MEMADD_SIZE_8BIT,data_ptr,len,I2Cx_FLAG_TIMEOUT); /* 检查通讯状态 */ if(status != HAL_OK) { /* 总线出错处理 */ I2Cx_Error(slave_addr); } while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY) { } /* 检查SENSOR是否就绪进行下一次读写操作 */ while (HAL_I2C_IsDeviceReady(&I2C_Handle, slave_addr, I2Cx_FLAG_TIMEOUT, I2Cx_FLAG_TIMEOUT) == HAL_TIMEOUT); /* 等待传输结束 */ while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY) { } return status; } /*********************************************END OF FILE**********************/