stm32的HAL库i2c从机实现

2023-11-01 9浏览
百检网是一家专业的第三方检测平台,汇聚众多拥有权威资质的第三方检测机构为你提供一站式的检测服务,做检测就上百检网。百检网让检测从此检测,一份报告全国通用,专业值得信赖。

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的字节全部发送完成才行,不然通信会出问题。这个问题需要进一步解决。


百检网秉承“客户至上,服务为先,精诚合作,以人为本”的经营理念,始终站在用户的角度解决问题,为客户提供“一站购物式”的新奇检测体验,打开网站,像挑选商品一样简单,方便。打破行业信息壁垒,建构消费和检测机构之间高效的沟通平台