日韩一区二区三区精品,欧美疯狂xxxxbbbb牲交,热99re久久免费视精品频,人妻互换 综合,欧美激情肉欲高潮视频

歷史上的今天

今天是:2025年04月09日(星期三)

正在發(fā)生

2019年04月09日 | STM32使用HAL庫(kù)實(shí)現(xiàn)串口通訊——理論原理詳細(xì)講解

發(fā)布者:RoboPilot 來(lái)源: eefocus關(guān)鍵字:STM32  HAL庫(kù)  串口通訊 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

一、中斷模式


1.中斷接收。

1.1先看中斷接收的流程(以 USART2 為例)

在啟動(dòng)文件中找到中斷向量



USART2_IRQHandler

找到USART2_IRQHandler的函數(shù)定義


 

可以看到這里又轉(zhuǎn)到另一個(gè)函數(shù)里去了,再找下去:



該函數(shù)的源碼:


/**

  * @brief  This function handles UART interrupt request.

  * @param  huart: pointer to a UART_HandleTypeDef structure that contains

  *                the configuration information for the specified UART module.

  * @retval None

  */

void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)

{

   uint32_t isrflags   = READ_REG(huart->Instance->SR);

   uint32_t cr1its     = READ_REG(huart->Instance->CR1);

   uint32_t cr3its     = READ_REG(huart->Instance->CR3);

   uint32_t errorflags = 0x00U;

   uint32_t dmarequest = 0x00U;


  /* If no error occurs */

  errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));

  if(errorflags == RESET)

  {

    /* UART in mode Receiver -------------------------------------------------*/

    if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))

    {

      UART_Receive_IT(huart);

      return;

    }

  }  


  /* If some errors occur */

  if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))

  {

    /* UART parity error interrupt occurred ----------------------------------*/

    if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))

    {

      huart->ErrorCode |= HAL_UART_ERROR_PE;

    }

    

    /* UART noise error interrupt occurred -----------------------------------*/

    if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))

    {

      huart->ErrorCode |= HAL_UART_ERROR_NE;

    }

    

    /* UART frame error interrupt occurred -----------------------------------*/

    if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))

    {

      huart->ErrorCode |= HAL_UART_ERROR_FE;

    }

    

    /* UART Over-Run interrupt occurred --------------------------------------*/

    if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))

    { 

      huart->ErrorCode |= HAL_UART_ERROR_ORE;

    }


    /* Call UART Error Call back function if need be --------------------------*/    

    if(huart->ErrorCode != HAL_UART_ERROR_NONE)

    {

      /* UART in mode Receiver -----------------------------------------------*/

      if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))

      {

        UART_Receive_IT(huart);

      }


      /* If Overrun error occurs, or if any error occurs in DMA mode reception,

         consider error as blocking */

      dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);

      if(((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)

      {

        /* Blocking error : transfer is aborted

           Set the UART state ready to be able to start again the process,

           Disable Rx Interrupts, and disable Rx DMA request, if ongoing */

        UART_EndRxTransfer(huart);

        

        /* Disable the UART DMA Rx request if enabled */

        if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))

        {

          CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);

          

          /* Abort the UART DMA Rx channel */

          if(huart->hdmarx != NULL)

          {

            /* Set the UART DMA Abort callback : 

               will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */

            huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;

            if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)

            {

              /* Call Directly XferAbortCallback function in case of error */

              huart->hdmarx->XferAbortCallback(huart->hdmarx);

            }

          }

          else

          {

            /* Call user error callback */

            HAL_UART_ErrorCallback(huart);

          }

        }

        else

        {

          /* Call user error callback */

          HAL_UART_ErrorCallback(huart);

        }

      }

      else

      {

        /* Non Blocking error : transfer could go on. 

           Error is notified to user through user error callback */

        HAL_UART_ErrorCallback(huart);

        huart->ErrorCode = HAL_UART_ERROR_NONE;

      }

    }

    return;

  } /* End if some error occurs */


  /* UART in mode Transmitter ------------------------------------------------*/

  if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))

  {

    UART_Transmit_IT(huart);

    return;

  }

  

  /* UART in mode Transmitter end --------------------------------------------*/

  if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))

  {

    UART_EndTransmit_IT(huart);

    return;

  }

}

也就是說(shuō),當(dāng)串口中斷觸發(fā)以后,幾經(jīng)周轉(zhuǎn)到了這里,該函數(shù)功能是讀取寄存器的幾個(gè)狀態(tài),判斷無(wú)誤后再轉(zhuǎn)到另一個(gè)函數(shù),就是上圖小矩形框出來(lái)的UART_Receive_IT(huart);

然后我們?cè)偃タ碪ART_Receive_IT(huart)這個(gè)函數(shù)原型:

回調(diào)函數(shù)就在這個(gè)UART_Receive_IT(huart)函數(shù)里:

在回調(diào)函數(shù)上邊有兩行很重要的代碼

這兩行代碼的作用是關(guān)閉串口接收中斷,也就是說(shuō),在一次串口中斷接收過(guò)程的最后,即串口接收完一組數(shù)據(jù)之后會(huì)關(guān)閉串口接收中斷。(這個(gè)后面還會(huì)再講,先記?。?/p>

總結(jié)一下,串口中斷接收的流程:

USART2_IRQHandler(void)    ->    HAL_UART_IRQHandler(UART_HandleTypeDef *huart)    ->    UART_Receive_IT(UART_HandleTypeDef *huart)    ->    HAL_UART_RxCpltCallback(huart);

Callback函數(shù)就是用戶要重寫在main.c里的回調(diào)函數(shù)。

再說(shuō)明一下一個(gè)很重要的問(wèn)題:STM32的每個(gè)串口中斷有好幾個(gè)(發(fā)送接收等),但是只要是與串口相關(guān)的中斷發(fā)生系統(tǒng)都會(huì)先調(diào)用同一個(gè)函數(shù),也就是中斷向量表中的那個(gè),比如usart2的話就是USART2_IRQHandler(void),然后這個(gè)函數(shù)再調(diào)用HAL_UART_IRQHandler,在HAL_UART_IRQHandler中去讀取寄存器判斷究竟是那幾個(gè)位被置為1,確定好是哪個(gè)中斷之后(接收還是發(fā)送)再調(diào)用不同的回調(diào)函數(shù)。

1.2如何使用接收中斷。

在cube中配置完了之后并沒(méi)有使能串口中斷(有一個(gè)串口初始化函數(shù),但是在這個(gè)函數(shù)中并未使能串口中斷)需要用戶手動(dòng)使能。使能代碼如下:

HAL_UART_Receive_IT(&huart2, (uint8_t *)kRxBuffer, 10);

什么意思呢?

HAL庫(kù)的串口接收思路是這樣的:用戶你可以隨便定義一個(gè)緩存區(qū),大小隨意,然后通過(guò)上邊這個(gè)函數(shù)把這個(gè)緩存區(qū)對(duì)應(yīng)到串口的接收,上面函數(shù)的意思就是把kRxBuffer(這是一個(gè)數(shù)組)作為緩存區(qū),指定大小為10。然后usart2接收數(shù)據(jù)的時(shí)候就防到kRxBuffer這個(gè)數(shù)組中,只有當(dāng)接收到10個(gè)數(shù)據(jù)之后才調(diào)用一次callback函數(shù)(回調(diào)函數(shù))。當(dāng)然不要忘了該函數(shù)的使能串口接收中斷功能, 在:二、中斷模式 的1.1節(jié)中說(shuō)到了串口接收完數(shù)據(jù)后會(huì)關(guān)閉使能,所以,在回調(diào)函數(shù)中一定要再寫一次HAL_UART_Receive_IT(&huart2, (uint8_t *)kRxBuffer, 10),使能接收中斷。

小小的總結(jié)下串口中斷接收怎么用:

(1)指定一個(gè)緩存區(qū)(串口接收到的數(shù)據(jù)會(huì)全部堆到這個(gè)緩存區(qū))

(2)使能串口接收中斷,并把緩存區(qū)對(duì)應(yīng)到串口

(3)在回調(diào)函數(shù)中實(shí)現(xiàn)接收到數(shù)據(jù)之后的操作(比如處理數(shù)據(jù))并再次使能串口接收中斷。

所以更具體一下串口接收的流程就是這樣的:

(1)串口一個(gè)接一個(gè)的接收到數(shù)據(jù)填充到緩存區(qū)

(2)緩存區(qū)滿(大小是用戶定義的)程序幾經(jīng)輾轉(zhuǎn)最后會(huì)調(diào)用到回調(diào)函數(shù)。

(3)執(zhí)行用戶在回調(diào)函數(shù)中實(shí)現(xiàn)的功能。

2.中斷發(fā)送。

2.1發(fā)送中斷的觸發(fā)流程。

由于在STM32中usart2的入口中斷只有一個(gè):

就是上圖的中斷向量表中紅框標(biāo)出來(lái)的。其他的所有中斷其實(shí)都是從這里出發(fā)的,我們?cè)俸娃劢邮找粯愚垡槐榘l(fā)送。

首先是USART2_IRQHandler,找到這個(gè)函數(shù)原型(這一步和接收完全一樣):

再找HAL_UART_IRQHandler(&huart2);原型:

到這里還是和接收完全一樣,注意是完全一樣,源碼也就是上面接收貼出來(lái)的一樣。這次我們主要注意該函數(shù)最后幾行(可以翻上去看源碼):

把中間代碼收起來(lái)以后看最后紅框,這就很明顯了,這里觸發(fā)了發(fā)送中斷(軟件觸發(fā))

接著去找這個(gè)UART_EndTransmit_IT(huart)的函數(shù)原型:

第一個(gè)紅框里清除了發(fā)送中斷使能(同接收一樣,在用完之后就關(guān)掉,但是不同于接收,發(fā)送完成就不用再在回調(diào)函數(shù)中使能了,因?yàn)樵谥袛喟l(fā)送的時(shí)候就會(huì)使能),第二個(gè)紅框調(diào)用回調(diào)函數(shù)。

2.2如何使用發(fā)送中斷。

中斷發(fā)送的意思,非常類似于中斷接收,但其中有一些不同,看下面這個(gè)函數(shù):

HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

一個(gè)非常類似于中斷接收使能的函數(shù)。接收中斷使能函數(shù)的作用是綁定接收緩存區(qū)并使能接收中斷,但是對(duì)于發(fā)送,該函數(shù)的作用是發(fā)送指定長(zhǎng)度的指定數(shù)據(jù)并使能發(fā)送中斷。

比如有一個(gè)unsigned char 數(shù)組a[10],HAL_UART_Transmit_IT(&huart2, a, 10),這一句的意思是用usart2(串口2)發(fā)送a數(shù)組中的10個(gè)數(shù)據(jù),然后使能發(fā)送中斷。

當(dāng)發(fā)送完成之后(或者發(fā)送一半,發(fā)送一半也有個(gè)中斷)就會(huì)執(zhí)行回調(diào)函數(shù)。

總結(jié)一下發(fā)送中斷:

使用HAL_UART_Transmit_IT函數(shù)發(fā)送指定長(zhǎng)度的數(shù)據(jù),并使能發(fā)送中斷,發(fā)送到一半和發(fā)送結(jié)束會(huì)觸發(fā)中斷(相關(guān)的回調(diào)函數(shù)是HAL_UART_TxHalfCpltCallback()和HAL_UART_TxCpltCallback())中斷觸發(fā)后發(fā)送中斷使能會(huì)被清除,然后調(diào)用回調(diào)函數(shù),回調(diào)函數(shù)執(zhí)行完成之后結(jié)束本次發(fā)送。


關(guān)鍵字:STM32  HAL庫(kù)  串口通訊 引用地址:STM32使用HAL庫(kù)實(shí)現(xiàn)串口通訊——理論原理詳細(xì)講解

上一篇:STM32串口環(huán)形緩沖區(qū)
下一篇:STM32F429 DMA串口數(shù)據(jù)發(fā)送

推薦閱讀

  我國(guó)作為世界上最大的電力能源生產(chǎn)國(guó)和消費(fèi)國(guó),近年來(lái)在可再生能源領(lǐng)域取得了舉世矚目的成就,不僅是全球最大的能效改善國(guó),也將逐步成為最大的清潔能源貢獻(xiàn)國(guó)。預(yù)計(jì)“十三五”中后期,國(guó)內(nèi)可再生能源將保持中高速增長(zhǎng)態(tài)勢(shì),產(chǎn)業(yè)發(fā)展將再上新臺(tái)階——下面就隨嵌入式小編一起來(lái)了解一下相關(guān)內(nèi)容吧?! 〗眨?ldquo;推廣清潔能源應(yīng)用,助力低碳經(jīng)濟(jì)發(fā)展”...
無(wú)論是傳統(tǒng)的工業(yè)機(jī)器人系統(tǒng),還是當(dāng)今最先進(jìn)的協(xié)作機(jī)器人(Cobot),它們都要依靠可生成大量高度可變數(shù)據(jù)的。這些數(shù)據(jù)有助于構(gòu)建更佳的(ML)和人工智能()模型。而機(jī)器人依靠這些模型變得“自主”,可在動(dòng)態(tài)的現(xiàn)實(shí)環(huán)境中做出實(shí)時(shí)決策和導(dǎo)航。 工業(yè)機(jī)器人通常位于“封閉”環(huán)境中,出于安全原因,如果該環(huán)境中有人類進(jìn)入,機(jī)器人會(huì)停止移動(dòng)。但是限制...
據(jù)外媒報(bào)道,邊緣計(jì)算公司MobiledgeX與硅谷汽車技術(shù)與V2X通信技術(shù)公司Savari宣布建立戰(zhàn)略合作伙伴關(guān)系,共同為汽車OEM廠商、車隊(duì)管理部門及移動(dòng)出行服務(wù)合作伙伴提供增強(qiáng)的C-V2X用例。(圖片來(lái)源:Savari官網(wǎng))MobiledgeX由德國(guó)電信(Deutsche Telekom)創(chuàng)建,旨在幫助全球電信運(yùn)營(yíng)商提供跨運(yùn)營(yíng)商的邊緣計(jì)算服務(wù)和能力。得益于MobiledgeX Edge-Cloud(邊...
2020年,疫情席卷全球,“宅經(jīng)濟(jì)”強(qiáng)化人們對(duì)于萬(wàn)物互聯(lián)的需求,給半導(dǎo)體產(chǎn)業(yè)鏈帶來(lái)難逢的市場(chǎng)機(jī)遇。盡管受疫情影響,各公司上半年?duì)I收有所調(diào)整,但整體表現(xiàn)不錯(cuò);下半年受各種因素影響,產(chǎn)能爆滿。根據(jù)芯思想研究院發(fā)布的數(shù)據(jù)顯示,2020年的榜單較2019年榜單加了三家公司,分別是紹興中芯、粵芯半導(dǎo)體、寧波中芯。2020年中國(guó)大陸本土晶圓代工公司總體營(yíng)收...

史海拾趣

小廣播
設(shè)計(jì)資源 培訓(xùn) 開(kāi)發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開(kāi)發(fā)圈

 
機(jī)器人開(kāi)發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved