STM32 HAL库 I2C 学习

今日头条

1097人已加入

描述

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);

}

}

}

}
lw

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分