STM32-I2C_CheckEvent-標志位自動清除理解


STM32里I2C_CheckEvent函數我們應該是相當熟悉了,在每次發送數據后我們都需要檢驗相應的EVx(x = 0,1,2,,,)事件是否有發送。

函數定義如下:

 1 ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
 2 {
 3   uint32_t lastevent = 0;
 4   uint32_t flag1 = 0, flag2 = 0;
 5   ErrorStatus status = ERROR;
 6 
 7   /* Check the parameters */
 8   assert_param(IS_I2C_ALL_PERIPH(I2Cx));
 9   assert_param(IS_I2C_EVENT(I2C_EVENT));
10 
11   /* Read the I2Cx status register */
12   flag1 = I2Cx->SR1;
13   flag2 = I2Cx->SR2;
14   flag2 = flag2 << 16;
15 
16   /* Get the last event value from I2C status register */
17   lastevent = (flag1 | flag2) & FLAG_Mask;
18 
19   /* Check whether the last event contains the I2C_EVENT */
20   if ((lastevent & I2C_EVENT) == I2C_EVENT)
21   {
22     /* SUCCESS: last event is equal to I2C_EVENT */
23     status = SUCCESS;
24   }
25   else
26   {
27     /* ERROR: last event is different from I2C_EVENT */
28     status = ERROR;
29   }
30   /* Return status */
31   return status;
32 }

該函數第一個參數是輸入需要檢查的I2Cx(x = 1,2,3,4,5)外設,第二個參數是檢查的事件,如下所示:

I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED :       EV1
I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED :         EV1
I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED :     EV1
I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED :       EV1
I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED :         EV1
I2C_EVENT_SLAVE_BYTE_RECEIVED :                 EV2
(I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF) :       EV2
(I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL) :       EV2
I2C_EVENT_SLAVE_BYTE_TRANSMITTED :               EV3
(I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF) :     EV3
(I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) :      EV3
I2C_EVENT_SLAVE_ACK_FAILURE :                   EV3_2
I2C_EVENT_SLAVE_STOP_DETECTED :                 EV4
I2C_EVENT_MASTER_MODE_SELECT :                 EV5
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED :        EV6 
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED :        EV6
I2C_EVENT_MASTER_BYTE_RECEIVED :              EV7
I2C_EVENT_MASTER_BYTE_TRANSMITTING :            EV8
I2C_EVENT_MASTER_BYTE_TRANSMITTED :             EV8_2
I2C_EVENT_MASTER_MODE_ADDRESS10 :               EV9

本文就舉里面常用的一些事件為例,來分析該函數為什么能夠自動清除標志位。包含EV5,EV6,EV8以及EV7事件。

在使用I2C發送數據時我們會用到EV5,EV6,EV8事件,事件名稱及定義如下:

/*I2C_EVENT_MASTER_MODE_SELECT                          : EV5*/
#define  I2C_EVENT_MASTER_MODE_SELECT                      ((uint32_t)0x00030001)  /* BUSY, MSL and SB flag */

/*I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED            : EV6 */
#define  I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED        ((uint32_t)0x00070082)  /* BUSY, MSL, ADDR and TRA flags */
/*I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED               : EV6*/
#define  I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED           ((uint32_t)0x00030002)  /* BUSY, MSL and ADDR flags */


/*I2C_EVENT_MASTER_BYTE_TRANSMITTING                    : EV8*/
#define I2C_EVENT_MASTER_BYTE_TRANSMITTING                 ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */
/*I2C_EVENT_MASTER_BYTE_TRANSMITTED                     : EV8_2*/
#define  I2C_EVENT_MASTER_BYTE_TRANSMITTED                 ((uint32_t)0x00070084)  /* TRA, BUSY, MSL, TXE and BTF flags */
  • 根據I2C_CheckEvent函數的定義,事件的高16位為I2C外設的SR2寄存器,低16位為I2C外設的SR1寄存器。
  • 先來看看 I2C_EVENT_MASTER_MODE_SELECT,宏定義為,0x00030001,對應的SR1和SR2寄存器如下所示:

其中MSL為1表為主模式,BUSY為1表總線忙碌,

這兩位一般都是在產生STOP信號的時候置0,其他時候都為1。

看看SB位如何清零,

我們在Check_Event函數里面讀取了SR1寄存器,我們在發送了起始信號之后就需要發送設備地址進行訪問,在I2C_Send7bitAddress函數里面我們訪問了數據寄存器SD,於是在下一次檢測標志位之前SB被清除。

  • 再來看看兩個EV6事件 I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED 和 I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED,這兩者的區別就是一個用於發送模式,另一個用於接受模式,發送模式為0x00070082,

 

TRA數據單元一般產生STOP信號后清除,至於ADDR位,在I2C_CheckEvent函數里面,我們是順序地讀取了SR1和SR2寄存器,於是ADDR位被清除。對於TxE位,我們下一步能會進行數據發送操作,也就是使用I2C_SendData函數訪問DR數據寄存器,於是TxE也被清除。

  • 還有一個EV8事件 I2C_EVENT_MASTER_BYTE_TRANSMITTED, 定義為0x00070084,

 

此處只討論BTF位的清除,

也是訪問SR1寄存器和對數據寄存器的讀或寫可以清除該位,因此BTF位也被清除。

至於I2C_CheckEvent里面其他事件所設計的位清除,我就不一一舉例了,可以按照這個思路,參考STM32F10x-中文參考手冊自己一步步的查看。

I2C_ChencEvent比I2C_GetFlagStatus函數好的一點就是它檢測了與事件相關的所有寄存器位,而后者只檢測提供的標志位。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM