static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1; 设置I2C实体
hi2c1.Init.ClockSpeed = 100000; 设置clk速率,从而设置TRISE,CCR,DUTY等寄存器
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; 设置占空比T low /T high = 2 (CCR寄存器14位)
hi2c1.Init.OwnAddress1 = 100; 设置地址A0,8位地址
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; 设置为7位地址模式
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; 禁止双地址
hi2c1.Init.OwnAddress2 = 0; 第2地址
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; 禁止广播
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; 禁止时钟拉伸
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
}
MX_I2C1_Init调用库函数HAL_I2C_Init()(在stm32f1xx_hal_i2c.c中定义)来初始化I2C接口,需要初始化的数据已经在MX_I2C1_Init中定义了
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
{
uint32_t freqrange = 0;
uint32_t pclk1 = 0;
/* Check the I2C handle allocation */
if(hi2c == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
assert_param(IS_I2C_CLOCK_SPEED(hi2c->Init.ClockSpeed));
assert_param(IS_I2C_DUTY_CYCLE(hi2c->Init.DutyCycle));
assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1));
assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode));
assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode));
assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2));
assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode));
assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode));
if(hi2c->State == HAL_I2C_STATE_RESET)
{
/* Allocate lock resource and initialize it */
hi2c->Lock = HAL_UNLOCKED;
/*配置相关硬件: GPIO, CLOCK, NVIC */
HAL_I2C_MspInit(hi2c);
}
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Get PCLK1 frequency */
pclk1 = HAL_RCC_GetPCLK1Freq();
/* Calculate frequency range */
freqrange = I2C_FREQ_RANGE(pclk1);
/*---------------------------- I2Cx CR2 Configuration I2C模块时钟频率 ----------------------*/
/* Configure I2Cx: Frequency range */
hi2c->Instance->CR2 = freqrange;
/*---------------------------- I2Cx TRISE Configuration --------------------*/
/* Configure I2Cx: Rise Time */
hi2c->Instance->TRISE = I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed);
/*---------------------------- I2Cx CCR Configuration ----------------------*/
/* Configure I2Cx: Speed */
hi2c->Instance->CCR = I2C_Configure_Speed(hi2c, pclk1);
/*---------------------------- I2Cx CR1 Configuration ----------------------*/
/* Configure I2Cx: Generalcall and NoStretch mode */
hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode);
/*---------------------------- I2Cx OAR1 Configuration ---------------------*/
/* Configure I2Cx: Own Address1 and addressing mode */
hi2c->Instance->OAR1 = (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1);
/*---------------------------- I2Cx OAR2 Configuration ---------------------*/
/* Configure I2Cx: Dual mode and Own Address2 */
hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2);
/* Enable the selected I2C peripheral */
__HAL_I2C_ENABLE(hi2c);
/* 设置句柄相关状态位*/
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;
return HAL_OK;
}
库函数HAL_I2C_Init()检查句柄的参数是否有效,然后再调用HAL_I2C_MspInit()(在stm32f1xx_hal_msp.c中定义)进行相关GPIO,时钟,中断方面的设置,然后才根据句柄所带的参数对I2C模块的寄存器进行配置。
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)
{
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* Peripheral interrupt init 此处设置了开启I2C事件中断*/
HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
到此I2C的模块已经初始化已经完成,如果有中断发生就会调用中断处理函数I2C1_EV_IRQHandler(void) (在stm32f1xx_it.c中定义),然而调用真正的中断服务函数HAL_I2C_EV_IRQHandler(&hi2c1)(stm32f1xx_hal_i2c.c中定义)
void I2C1_EV_IRQHandler(void)
{
/* USER CODE BEGIN I2C1_EV_IRQn 0 */
/* USER CODE END I2C1_EV_IRQn 0 */
HAL_I2C_EV_IRQHandler(&hi2c1);
/* USER CODE BEGIN I2C1_EV_IRQn 1 */
/* USER CODE END I2C1_EV_IRQn 1 */
}
void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
{
uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
/* Master or Memory mode selected */
if((hi2c->Mode == HAL_I2C_MODE_MASTER) ||
(hi2c->Mode == HAL_I2C_MODE_MEM))
{
/* I2C in mode Transmitter -----------------------------------------------*/
if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA) == SET)
{
tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE);
tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_BUF);
tmp3 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF);
tmp4 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_EVT);
/* TXE set and BTF reset -----------------------------------------------*/
if((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET))
{
I2C_MasterTransmit_TXE(hi2c);
}
/* BTF set -------------------------------------------------------------*/
else if((tmp3 == SET) && (tmp4 == SET))
{
I2C_MasterTransmit_BTF(hi2c);
}
}
/* I2C in mode Receiver --------------------------------------------------*/
else
{
tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE);
tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_BUF);
tmp3 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF);
tmp4 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_EVT);
/* RXNE set and BTF reset -----------------------------------------------*/
if((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET))
{
I2C_MasterReceive_RXNE(hi2c);
}
/* BTF set -------------------------------------------------------------*/
else if((tmp3 == SET) && (tmp4 == SET))
{
I2C_MasterReceive_BTF(hi2c);
}
}
}
/* Slave mode selected */
else
{
tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, (I2C_IT_EVT));
tmp3 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF);
tmp4 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA);
/* ADDR set --------------------------------------------------------------*/
if((tmp1 == SET) && (tmp2 == SET))
{
I2C_Slave_ADDR(hi2c);
}
/* STOPF set --------------------------------------------------------------*/
else if((tmp3 == SET) && (tmp2 == SET))
{
I2C_Slave_STOPF(hi2c);
}
/* I2C in mode Transmitter -----------------------------------------------*/
else if(tmp4 == SET)
{
tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE);
tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_BUF);
tmp3 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF);
tmp4 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_EVT);
/* TXE set and BTF reset -----------------------------------------------*/
if((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET))
{
I2C_SlaveTransmit_TXE(hi2c);
}
/* BTF set -------------------------------------------------------------*/
else if((tmp3 == SET) && (tmp4 == SET))
{
I2C_SlaveTransmit_BTF(hi2c);
}
}
/* I2C in mode Receiver --------------------------------------------------*/
else
{
tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE);
tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_BUF);
tmp3 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF);
tmp4 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_EVT);
/* RXNE set and BTF reset ----------------------------------------------*/
if((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET))
{
I2C_SlaveReceive_RXNE(hi2c);
}
/* BTF set -------------------------------------------------------------*/
else if((tmp3 == SET) && (tmp4 == SET))
{
I2C_SlaveReceive_BTF(hi2c);
}
}
}
}