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;
}
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);
}
}
}
}
lw
評論
查看更多