stm32的i2c默认就是slave模式,本文基于HAL库实现中断方式的接收和发送,首先是初始化gpio和i2c,代码如下:
I2C_HandleTypeDef I2cHandle; void HAL_I2C_MspInit(I2C_HandleTypeDef*
i2cHandle) { GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOA_CLK_ENABLE() ;
__HAL_RCC_GPIOC_CLK_ENABLE() ; /**I2C3 GPIO Configuration PA8 ------> I2C3_SCL
PC9 ------> I2C3_SDA */ GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode
= GPIO_MODE_AF_OD; //开漏输出(i2c需要这种模式) GPIO_InitStruct.Speed =
GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Speed =
GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* Peripheral clock enable */
__HAL_RCC_I2C3_CLK_ENABLE(); /* Peripheral interrupt init */
HAL_NVIC_SetPriority(I2C3_EV_IRQn, 0, 0); HAL_NVIC_EnableIRQ(I2C3_EV_IRQn);
HAL_NVIC_SetPriority(I2C3_ER_IRQn, 0, 0); HAL_NVIC_EnableIRQ(I2C3_ER_IRQn); }
void I2c_config() { I2cHandle.Instance = I2C3; //此处使用i2c3
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; //7位地址模式
I2cHandle.Init.ClockSpeed = 1000000; //时钟支持最高1M I2cHandle.Init.DualAddressMode
= I2C_DUALADDRESS_DISABLE; //关闭双地址模式 I2cHandle.Init.DutyCycle =
I2C_DUTYCYCLE_16_9; I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
I2cHandle.Init.OwnAddress1 = 0X34; //器件地址 I2cHandle.Init.OwnAddress2 = 0;
if(HAL_I2C_Init(&I2cHandle) != HAL_OK) //调用初始化函数 { /* Initialization Error */
Error_Handler(); }
HAL_I2C_Slave_Receive_IT(&I2cHandle,i2c_slave_recv,I2C_REC_BYTES); //开启从机中断接收 }
i2c3中断回调函数:
void I2C3_ER_IRQHandler() //异常回调 { HAL_I2C_ER_IRQHandler(&I2cHandle); } void
I2C3_EV_IRQHandler() //事件回调(接收或发送) { HAL_I2C_EV_IRQHandler(&I2cHandle); }
  两个中断对应的中断事件如下图所示:



发送完成、接收完成和错误回调函数:
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *I2cHandle) { //发送完成回调函数 {
//一些其他操作 } HAL_I2C_Slave_Receive_IT(&I2cHandle,i2c_slave_recv,I2C_REC_BYTES); {
//一些其他操作 } } void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle) {
//接收完成回调函数 { //一些其他操作 }
HAL_I2C_Slave_Transmit_IT(&I2cHandle,send_buffer,send_cnt); { //一些其他操作 } } void
HAL_I2C_ErrorCallback(I2C_HandleTypeDef *I2cHandle) { //错误异常回调函数 }
实际操作时可以在接收完成中断中处理数据然后开启从机发送中断,在发送完成中断中开启从机接收中断,可以实现收发。

目前用HAL库发送必须将send_cnt的字节全部发送完成才行,不然通信会出问题。这个问题需要进一步解决。

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信