通过STM32CUBEMX的底层函数在中断模式下两个stm32板之间的I2C通信
I2C communication between two stm32 board in interrupt mode by low layer functions of STM32CUBEMX
我正在做一个需要在两个 stm32 (stm32f103rb and stm32f429zg)
之间进行数据通信的项目。
我使用 stm32f103rb-nucleo examples_ll (I2C _OneBoard_Communication_IT)
但它只工作一个字节,之后就停止工作。我希望它重复工作。
代码结构与示例在 stm32cubemx
存储库相关文件夹中的编写方式完全相同。
我不知道如何让它循环工作,通过按下按钮,每次按下主按钮和从按钮时都会完成通信。
我把主完成回调函数放在这里:
void Master_Complete_Callback(void)
{
if(ubNbDataToReceive == 3)
{
/* Prepare the generation of a Non ACKnowledge condition after next received bytes */
LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_NACK);
/* Read character in Receive Data register.
RXNE flag is cleared by reading data in RXDR register */
aReceiveBuffer[ubReceiveIndex++] = LL_I2C_ReceiveData8(I2C1);
ubNbDataToReceive--;
/* Disable Buffer Interrupts */
LL_I2C_DisableIT_BUF(I2C1);
}
else if(ubNbDataToReceive == 2)
{
/* Generate Stop condition */
LL_I2C_GenerateStopCondition(I2C1);
/* Read character from Receive Data register.
RXNE flag is cleared by reading data in RXDR register */
aReceiveBuffer[ubReceiveIndex++] = LL_I2C_ReceiveData8(I2C1);
ubNbDataToReceive--;
/* Read character from shift register.
RXNE flag is cleared by reading data in RXDR register */
aReceiveBuffer[ubReceiveIndex++] = LL_I2C_ReceiveData8(I2C1);
ubNbDataToReceive--;
}
else
{
if(ubNbDataToReceive > 0)
{
/* Read character from shift register.
RXNE flag is cleared by reading data in RXDR register */
aReceiveBuffer[ubReceiveIndex++] = LL_I2C_ReceiveData8(I2C2);
/* Update ubNbDataToReceive variable */
ubNbDataToReceive--;
}
}
if(ubNbDataToReceive == 0)
{
/* (1) Disable I2C1 transfer event/error interrupts:
* - Disable Events Interrupt
* - Disable Error interrupts
*/
LL_I2C_DisableIT_EVT(I2C1);
LL_I2C_DisableIT_ERR(I2C1);
LL_I2C_EnableIT_EVT(I2C1);
LL_I2C_EnableIT_ERR(I2C1);
/* Read Received character.
RXNE flag is cleared by reading of RXDR register */
if(aReceiveBuffer[ubReceiveIndex-1] == SLAVE_BYTE_TO_SEND)
{
/* Turn LED2 On:
* - Expected byte has been received
* - Master Rx sequence completed successfully
*/
//LED_On();
HAL_UART_Transmit_IT(&huart2,(uint8_t*)"#Data transfer is OK!$",strlen("#Data transfer is OK!$"));
ubNbDataToTransmit = sizeof(SLAVE_BYTE_TO_SEND);
ubNbDataToReceive = sizeof(SLAVE_BYTE_TO_SEND);
}
else
{
/* Call Error function */
Error_Callback();
}
}
}
很容易理解,发送过程的结束是在我添加HAL_UART函数将发送完成发送到串口的时候。
但这次之后,它又工作了一次,然后就停止了。
我检查了示波器信号显示,第二次传输后 SCL 引脚变低。
谢谢
好久没用LL了,用LL_I2C_DisableIT_EVT(I2C1);
单次传输后I2C中断不是禁用了吗??请确保在下次传输之前再次启用它。
存在两个主设备无法通过I2C总线相互通信的情况。因为主设备没有DEVICE_ADDRESS
。主设备只能与从设备通信。
我正在做一个需要在两个 stm32 (stm32f103rb and stm32f429zg)
之间进行数据通信的项目。
我使用 stm32f103rb-nucleo examples_ll (I2C _OneBoard_Communication_IT)
但它只工作一个字节,之后就停止工作。我希望它重复工作。
代码结构与示例在 stm32cubemx
存储库相关文件夹中的编写方式完全相同。
我不知道如何让它循环工作,通过按下按钮,每次按下主按钮和从按钮时都会完成通信。
我把主完成回调函数放在这里:
void Master_Complete_Callback(void)
{
if(ubNbDataToReceive == 3)
{
/* Prepare the generation of a Non ACKnowledge condition after next received bytes */
LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_NACK);
/* Read character in Receive Data register.
RXNE flag is cleared by reading data in RXDR register */
aReceiveBuffer[ubReceiveIndex++] = LL_I2C_ReceiveData8(I2C1);
ubNbDataToReceive--;
/* Disable Buffer Interrupts */
LL_I2C_DisableIT_BUF(I2C1);
}
else if(ubNbDataToReceive == 2)
{
/* Generate Stop condition */
LL_I2C_GenerateStopCondition(I2C1);
/* Read character from Receive Data register.
RXNE flag is cleared by reading data in RXDR register */
aReceiveBuffer[ubReceiveIndex++] = LL_I2C_ReceiveData8(I2C1);
ubNbDataToReceive--;
/* Read character from shift register.
RXNE flag is cleared by reading data in RXDR register */
aReceiveBuffer[ubReceiveIndex++] = LL_I2C_ReceiveData8(I2C1);
ubNbDataToReceive--;
}
else
{
if(ubNbDataToReceive > 0)
{
/* Read character from shift register.
RXNE flag is cleared by reading data in RXDR register */
aReceiveBuffer[ubReceiveIndex++] = LL_I2C_ReceiveData8(I2C2);
/* Update ubNbDataToReceive variable */
ubNbDataToReceive--;
}
}
if(ubNbDataToReceive == 0)
{
/* (1) Disable I2C1 transfer event/error interrupts:
* - Disable Events Interrupt
* - Disable Error interrupts
*/
LL_I2C_DisableIT_EVT(I2C1);
LL_I2C_DisableIT_ERR(I2C1);
LL_I2C_EnableIT_EVT(I2C1);
LL_I2C_EnableIT_ERR(I2C1);
/* Read Received character.
RXNE flag is cleared by reading of RXDR register */
if(aReceiveBuffer[ubReceiveIndex-1] == SLAVE_BYTE_TO_SEND)
{
/* Turn LED2 On:
* - Expected byte has been received
* - Master Rx sequence completed successfully
*/
//LED_On();
HAL_UART_Transmit_IT(&huart2,(uint8_t*)"#Data transfer is OK!$",strlen("#Data transfer is OK!$"));
ubNbDataToTransmit = sizeof(SLAVE_BYTE_TO_SEND);
ubNbDataToReceive = sizeof(SLAVE_BYTE_TO_SEND);
}
else
{
/* Call Error function */
Error_Callback();
}
}
}
很容易理解,发送过程的结束是在我添加HAL_UART函数将发送完成发送到串口的时候。
但这次之后,它又工作了一次,然后就停止了。 我检查了示波器信号显示,第二次传输后 SCL 引脚变低。 谢谢
好久没用LL了,用LL_I2C_DisableIT_EVT(I2C1);
单次传输后I2C中断不是禁用了吗??请确保在下次传输之前再次启用它。
存在两个主设备无法通过I2C总线相互通信的情况。因为主设备没有DEVICE_ADDRESS
。主设备只能与从设备通信。