1+X 傳感網(wǎng)中級備考實例解析:異步串行通信的接收中斷(1)

RXNE中斷響應(yīng)過程方法(1)

在USART1串口控制流水燈的實驗中,http://www.reibang.com/p/48817b329231,串口助手發(fā)送“mode_1#”命令字后懦底,STM32的USART1 DR寄存器接收到1個字符之后,就會進入到中斷服務(wù)函數(shù);總結(jié)中斷執(zhí)行的過程:

(1)使能中斷標志位逝钥,CR1寄存器的標志位RXNEIE被置1隘弊; 此函數(shù)調(diào)用之后,會直接配置CR1寄存器的RXNEIE=1;

__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);

圖1:RXNE事件使能
圖2:STM32的USART支持的中斷事件

(2)響應(yīng)中斷的入口函數(shù)

在使能了中斷之后送悔,DR數(shù)據(jù)寄存器只要接收到1個字符慢显,例如,發(fā)送命令字“mode_1#”,DR寄存器先接收到一個字符“m”,就會產(chǎn)生中斷欠啤;USART1_IRQHandler()函數(shù)是USART1中斷服務(wù)的入口荚藻,其中&huart1是訪問串口句柄UART_HandleTypeDef,可以通過huart1.TxXferSize,調(diào)用結(jié)構(gòu)體定義的成員洁段,

void USART1_IRQHandler(void)//中斷響應(yīng)的入口
{
 
    USER_UART_IRQHandler(&huart1);

}

串口句柄的定義內(nèi)容应狱,包含了(發(fā)送或接收的)數(shù)據(jù)緩存、數(shù)據(jù)指針祠丝、串口 DMA 相關(guān)的變量疾呻、各種標志位等等要在整個項目流程中都要設(shè)置的各個成員除嘹。還有中斷服務(wù)程序中的回調(diào)函數(shù);這樣我們在整個程序中就可以方便調(diào)用岸蜗;

UART_HandleTypeDef huart1;

typedef struct __UART_HandleTypeDef
{
  USART_TypeDef                 *Instance;        /*!< UART registers base address        */

  UART_InitTypeDef              Init;             /*!< UART communication parameters      */

  uint8_t                       *pTxBuffPtr;      /*!< Pointer to UART Tx transfer Buffer */

  uint16_t                      TxXferSize;       /*!< UART Tx Transfer size              */

  __IO uint16_t                 TxXferCount;      /*!< UART Tx Transfer Counter           */

  uint8_t                       *pRxBuffPtr;      /*!< Pointer to UART Rx transfer Buffer */

  uint16_t                      RxXferSize;       /*!< UART Rx Transfer size              */

  __IO uint16_t                 RxXferCount;      /*!< UART Rx Transfer Counter           */

  DMA_HandleTypeDef             *hdmatx;          /*!< UART Tx DMA Handle parameters      */

  DMA_HandleTypeDef             *hdmarx;          /*!< UART Rx DMA Handle parameters      */

  HAL_LockTypeDef               Lock;             /*!< Locking object                     */

  __IO HAL_UART_StateTypeDef    gState;           /*!< UART state information related to global Handle management
                                                       and also related to Tx operations.
                                                       This parameter can be a value of @ref HAL_UART_StateTypeDef */

  __IO HAL_UART_StateTypeDef    RxState;          /*!< UART state information related to Rx operations.
                                                       This parameter can be a value of @ref HAL_UART_StateTypeDef */

  __IO uint32_t                 ErrorCode;        /*!< UART Error code                    */

#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
  void (* TxHalfCpltCallback)(struct __UART_HandleTypeDef *huart);        /*!< UART Tx Half Complete Callback        */
  void (* TxCpltCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Tx Complete Callback             */
  void (* RxHalfCpltCallback)(struct __UART_HandleTypeDef *huart);        /*!< UART Rx Half Complete Callback        */
  void (* RxCpltCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Rx Complete Callback             */
  void (* ErrorCallback)(struct __UART_HandleTypeDef *huart);             /*!< UART Error Callback                   */
  void (* AbortCpltCallback)(struct __UART_HandleTypeDef *huart);         /*!< UART Abort Complete Callback          */
  void (* MspInitCallback)(struct __UART_HandleTypeDef *huart);           /*!< UART Msp Init callback                */
  void (* MspDeInitCallback)(struct __UART_HandleTypeDef *huart);         /*!< UART Msp DeInit callback              */
#endif  /* USE_HAL_UART_REGISTER_CALLBACKS */

} UART_HandleTypeDef;

(3)用戶重寫中斷服務(wù)函數(shù)
此次項目中憾赁,我們注釋掉了HAL庫原本的HAL_UART_IRQHandler(&huart1);然后重新定義了USER_UART_IRQHandler(&huart1);在中斷入口響應(yīng)函數(shù) USART1_IRQHandler(void)執(zhí)行以后,我們就直接調(diào)用USER_UART_IRQHandler(&huart1)散吵;在main.c中對函數(shù)進行定義龙考;

void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
    
{
    if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE) != RESET))//接收一個字節(jié)就會產(chǎn)生中斷
    {
          __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
            uart1RxBuff[uart1RxCounter] = (uint8_t)(huart1.Instance->DR & (uint8_t)0x00ff);
           uart1RxCounter++;
       
          __HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE);

    }
    if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))//接收一組數(shù)據(jù)/一幀數(shù)據(jù)就會中斷
        
    {   
           __HAL_UART_DISABLE_IT(&huart1,UART_IT_IDLE);
             uart1RxState = 1;
    }

}

這種方式與我們之前學(xué)習(xí)的標準庫方法比較相似,在中斷服務(wù)入口函數(shù)里矾睦,判斷標志位晦款,然后做讀/寫操作,最后清除標志位枚冗;沒有使用調(diào)用HAL庫的回調(diào)函數(shù)缓溅,程序代碼思路比較簡潔;
(4)判斷標志位赁温,將數(shù)據(jù)寄存器DR中接收的低8位字符讀取到自己定義的數(shù)組中坛怪;同時,完成清除標志位RXNE股囊;代碼中uart1RxBuff是我們在C語言代碼中定義好的數(shù)組袜匿,準備將DR寄存器的數(shù)值讀入到數(shù)組中;通過在線調(diào)試稚疹,我們可以看到變化居灯;
從DR寄存器讀取數(shù)據(jù)之后,RXNE會自動被清零内狗;

if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE) != RESET))
uart1RxBuff[uart1RxCounter] = (uint8_t)(huart1.Instance->DR & (uint8_t)0x0i0ff);
           uart1RxCounter++;

圖3:單步運行查看數(shù)組是否接收到字符

圖4:RXNE置1和清零的條件

當RDR移位寄存器中的數(shù)據(jù)被轉(zhuǎn)移到USART_DR寄存器中怪嫌,該位被硬件置位。如果USART_CR1寄存器中的RXNEIE為1柳沙,則產(chǎn)生中斷岩灭。對USART_DR的讀操作可以將該位清零。

(5)使能IDLE中斷赂鲤,本次項目在RXNE中斷響應(yīng)函數(shù)中噪径,開啟了IDLE中斷,IDLE是空閑線路檢測標志位蛤袒,當一幀數(shù)據(jù)發(fā)送完熄云,下一幀數(shù)據(jù)還沒有發(fā)送之前膨更,會有空閑狀態(tài)妙真;IDLE標志位用于檢測一幀數(shù)據(jù)是否發(fā)送完成;在本例中荚守,IDLE使能的代碼是:

 __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);

在中斷服務(wù)函數(shù)中又使能了一個新的中斷珍德,可能對于初學(xué)者有很多疑問练般;這里注意不屬于中斷嵌套,IDLE標志位也只有在接收數(shù)據(jù)的狀態(tài)下锈候,才可能發(fā)生薄料,因為RXNE接收一個字符就會發(fā)生中斷,而IDLE是接收一幀數(shù)據(jù)才會發(fā)生中斷泵琳,這里兩個狀態(tài)是可以在一次接收數(shù)據(jù)的過程中按代碼順序先后發(fā)生摄职;所以不存在中斷嵌套問題;如果初學(xué)者對這里覺得難以理解获列,也可以將IDLE的使能谷市,在main.c全局變量中進行使能;

(6)產(chǎn)生IDLE中斷
當檢測到總線空閑時击孩,IDLE位被硬件置位,因為已經(jīng)開啟了USART_CR1中的IDLEIE為’1’迫悠,則產(chǎn)生中斷;條件判斷成立巩梢,接收數(shù)據(jù)狀態(tài)字置uart1RxState=1创泄;

if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))//接收一組數(shù)據(jù)/一幀數(shù)據(jù)就會中斷
        
    {       
           __HAL_UART_DISABLE_IT(&huart1,UART_IT_IDLE);
             uart1RxState = 1;
    }

IDLE的狀態(tài)位受到RXNE狀態(tài)位的影響,先有RXNE狀態(tài)位置1括蝠,檢測到IDLE狀態(tài)情況下鞠抑,才會進入IDLE的中斷響應(yīng);表示一幀數(shù)據(jù)已經(jīng)接收完成忌警;

(7)禁用IDLE中斷碍拆;__HAL_UART_DISABLE_IT(&huart1,UART_IT_IDLE);

總結(jié):通過此篇分析,是幫助同學(xué)們理解串口接收中斷函數(shù)的執(zhí)行流程慨蓝;使能函數(shù)__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE) 與用戶自定義的中斷服務(wù)函數(shù) USER_UART_IRQHandler(UART_HandleTypeDef *huart)感混,配合使用。完成數(shù)據(jù)接收礼烈;此篇沒有用到接收中斷的回調(diào)函數(shù)弧满。我們在下篇方法二中進行介紹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末此熬,一起剝皮案震驚了整個濱河市庭呜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌犀忱,老刑警劉巖募谎,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異阴汇,居然都是意外死亡数冬,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門搀庶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拐纱,“玉大人铜异,你說我怎么就攤上這事〗占埽” “怎么了揍庄?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長东抹。 經(jīng)常有香客問我蚂子,道長,這世上最難降的妖魔是什么缭黔? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任缆镣,我火速辦了婚禮,結(jié)果婚禮上试浙,老公的妹妹穿的比我還像新娘董瞻。我一直安慰自己,他們只是感情好田巴,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布钠糊。 她就那樣靜靜地躺著,像睡著了一般壹哺。 火紅的嫁衣襯著肌膚如雪抄伍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天管宵,我揣著相機與錄音截珍,去河邊找鬼。 笑死箩朴,一個胖子當著我的面吹牛岗喉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炸庞,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼钱床,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了埠居?” 一聲冷哼從身側(cè)響起查牌,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滥壕,沒想到半個月后纸颜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡绎橘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年胁孙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡浊洞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出胡岔,到底是詐尸還是另有隱情法希,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布靶瘸,位于F島的核電站苫亦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏怨咪。R本人自食惡果不足惜屋剑,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诗眨。 院中可真熱鬧唉匾,春花似錦、人聲如沸匠楚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芋簿。三九已至峡懈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間与斤,已是汗流浹背肪康。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留撩穿,地道東北人磷支。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像食寡,于是被迫代替她去往敵國和親齐唆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348