[英]STM32 I2C interrupt method requires a blocking while loop?
我有一個 Nucleo-F446RE,我正在嘗試讓 I2C 與我擁有的 IMU (LSM6DS33) 一起工作。 我正在使用 STM32CubeMX 並檢查了與 I2C 相關的我的板的所有示例代碼。 具體來說,我將討論他們的“I2C_TwoBoards_ComIT”示例,但他們所有使用中斷方法的示例都有同樣的怪癖。 這是他們從 main.c 中截取的代碼:
/* The board sends the message and expects to receive it back */
do
{
/*##-2- Start the transmission process #####################################*/
/* While the I2C in reception process, user can transmit data through
"aTxBuffer" buffer */
if(HAL_I2C_Master_Transmit_IT(&I2cHandle, (uint16_t)I2C_ADDRESS, (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
{
/* Error_Handler() function is called in case of error. */
Error_Handler();
}
/*##-3- Wait for the end of the transfer ###################################*/
/* Before starting a new communication transfer, you need to check the current
state of the peripheral; if it’s busy you need to wait for the end of current
transfer before starting a new one.
For simplicity reasons, this example is just waiting till the end of the
transfer, but application may perform other tasks while transfer operation
is ongoing. */
while (HAL_I2C_GetState(&I2cHandle) != HAL_I2C_STATE_READY)
{
}
/* When Acknowledge failure occurs (Slave don't acknowledge its address)
Master restarts communication */
}
while(HAL_I2C_GetError(&I2cHandle) == HAL_I2C_ERROR_AF);
在評論 ##-3- 他們解釋說,除非我們等待 I2C 狀態再次准備好,否則在發送命令后,下一個命令將覆蓋前一個命令,因此他們使用等待 I2C 狀態的 while 循環在繼續之前“准備好”。
這不是使用中斷的一種非常低效的方式,與使用標准輪詢方法沒有區別嗎? 兩者都阻塞了主代碼,那么中斷的目的是什么?
在我個人的示例中,我想以 IMU 能夠達到的 1.66 kHz 速率收集加速度計/陀螺儀數據。 我使用 2kHz 定時器發送 I2C 命令以讀取 acc/gyr 數據就緒寄存器,如果數據已為任一傳感器准備好,我讀取它們的 6 個字節以獲取 x/y/z 平面信息。 使用輪詢方法太慢了,因為以 2kHz 的速率阻塞代碼並不是低效的,但是中斷方法似乎並沒有更快,因為我仍然需要在上述 while 循環期間掛起系統以檢查 I2C 是否准備好接受另一個命令。 我在這里想念什么?
這(您提供的示例)是一種有效的做事方式嗎? 不,可以避免阻塞部分嗎? 是的。 這只是一個小例子,一個概念證明,所以那里有一些障礙。 您應該更深入地了解它存在的原因以及如何在不阻塞的情況下實現它的功能。
該阻塞部分的要點是在另一個 I2C 通信正在進行時不啟動 I2C 通信。 問題是,雖然您通過 I2C 發送內容的代碼行已經執行,但數據仍在物理上通過線路發送,只是因為您的 MCU 比 I2C 快得多。 您需要等到 I2C 線路空閑且可用於傳輸。
如何通過中斷而不浪費周期和處理時間來實現這一點? 在您的情況下,您可以輕松估計每次傳輸的數據量,沒有問題可以估計在您的 I2C 速度下每次傳輸將花費多少時間。 由於您巧妙且正確地使用計時器來安排定期傳輸,因此您應該能夠設置計時器,以便在下一個將發送數據的計時器中斷時,您之前的通信已經結束。
例如,如果您將定時器設置為 1Hz 開始傳輸,您顯然可以確定到下一次中斷時所有通信都已發生。 你根本不需要投票。
如果它以 1.6kHz 產生數據,我認為以 2kHz 的頻率對 IC 進行 I2C 輪詢沒有多大意義。 樣本之間的時間段會不均勻,一些數據會非常新鮮,而一些數據會延遲很少,另外還會有沒有准備好數據的通信。 最好以 1.5-1.6kHz 的頻率對其進行輪詢,並期望數據始終存在。 當然,鑒於通信適合 1.5kHz 周期,這需要一些餐巾數學。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.