日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32 串口接收流程-串口接收中断

發布時間:2025/3/12 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32 串口接收流程-串口接收中断 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

串口接收

串口接收流程

  • 編程USARTx_CR1的M位來定義字長。
  • 編程USARTx_CR2的STOP位來定義停止位位數。
  • 編程USARTx_BRR寄存器確定波特率。
  • 使能USARTx_CR1的UE位使能USARTx。
  • 如果進行多緩沖通信,配置USARTx_CR3的DMA使能(DMAT)。
  • 使能USARTx_CR1的RE位為1使能接收器。
  • 如果要使能接收中斷(接收到數據后產生中斷),使能USARTx_CR1的RXNEIE位為1。
  • 當串口接收到數據時

  • USARTx_SR(ISR)的RXNE位置1。表明移位寄存器內容已經傳輸到RDR(DR)寄存器。已經接收到數據并且等待讀取。
  • 如果開啟了接收數據中斷(USARTx_CR1寄存器的RXNEIE位為1),則會產生中斷。(程序上會執行中斷服務函數)
  • 如果開啟了其他中斷(幀錯誤等),相應標志位會置1。
  • 讀取USARTx_RDR(DR)寄存器的值,該操作會自動將RXNE位清零,等待下次接收后置位。
  • 串口接收流程(HAL庫)

    配置過程:

    接收配置步驟①~⑥和發送流程一樣,調用HAL_UART_Init函數HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);

    步驟⑦開啟接收中斷:HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef*huart, uint8_t *pData, uint16_t Size);

    接收數據過程:

    步驟①獲取狀態標志位通過標識符實現:

    __HAL_UART_GET_FLAG //判斷狀態標志位__HAL_UART_GET_IT_SOURCE //判斷中斷標志位

    步驟②~③中斷服務函數:

    void USARTx_IRQHandler(void) ;//(x=1~3,6) void UARTx_IRQHandler(void) ;//(x=4,5,7,8)

    在啟動文件startup_stm32fxxx.s中查找。
    步驟④讀取接收數據:
    HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

    串口接收中斷程序配置過程(HAL庫)

  • 初始化串口相關參數,使能串口:HAL_UART_Init();
  • 串口相關IO口配置,復用配置:
    在HAL_UART_MspInit中調用HAL_GPIO_Init函數。
  • 串口接收中斷優先級配置和使能:
    HAL_NVIC_EnableIRQ();
    HAL_NVIC_SetPriority();
  • 使能串口接收中斷:HAL_UART_Receive_IT();
  • 編寫中斷服務函數:USARTx_IRQHandler
  • 經過上面步驟,我們就可以寫完整的串口接收實驗。我們就可以在中斷服務函數中編寫中斷處理過程。
    HAL庫提供了詳細的中斷處理函數HAL_UART_IRQHandler,我們在中斷服務函數中會調用此函數處理中斷。

    在void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)函數里可以找到:UART_Receive_IT(huart);然后找到他的定義static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart),里面可以找到HAL_UART_RxCpltCallback(huart);他是一個接收完成處理回調函數,void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart),用戶可以自己編寫。

    在USART_HandleTypeDef中有如下變量:RxXferSize是接收的數量,RxXferCount是剩余的數據個數,pRxBuffPtr指向數據存儲位置的地址。比如,一開始要接收10個數據,pRxBuffPtr指向一個起始位置,初始時RxXferSize=10,RxXferCount=10,每接收一次,RxXferCount的值就減去1,而且pRxBuffPtr指針往下移,直到RxXferCount減為0 。

    uint8_t *pRxBuffPtr; /*!< Pointer to USART Rx transfer Buffer */uint16_t RxXferSize; /*!< USART Rx Transfer size */uint16_t RxXferCount; /*!< USART Rx Transfer Counter */ static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) {uint16_t* tmp;uint16_t uhMask = huart->Mask;/* Check that a Rx process is ongoing */if(huart->RxState == HAL_UART_STATE_BUSY_RX){if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)){tmp = (uint16_t*) huart->pRxBuffPtr ;*tmp = (uint16_t)(huart->Instance->RDR & uhMask);huart->pRxBuffPtr +=2;}else{*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);}if(--huart->RxXferCount == 0){/* Disable the UART Parity Error Interrupt and RXNE interrupt*/CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);/* Rx process is completed, restore huart->RxState to Ready */huart->RxState = HAL_UART_STATE_READY;HAL_UART_RxCpltCallback(huart);return HAL_OK;}return HAL_OK;}else{/* Clear RXNE interrupt flag */__HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);return HAL_BUSY;} }

    串口接收中斷流程

    串口中斷服務函數執行流程

    串口中斷服務函數中調用HAL庫串口中斷通用處理函數:HAL_UART_IRQHandler(); 該函數會對中斷來源進行分析,調用相應函數。
    對于不同的中斷類型,我們只需要編寫最終的中斷處理函數:

    void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart); void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);

    串口接收實驗

    電腦通過串口助手往串口1發送字符,串口1通過中斷方式接受字符,每接受一個字符就同時通過串口1返回給電腦。

  • 初始化串口相關參數,使能串口:HAL_UART_Init();
  • 串口相關IO口配置,復用配置:
    在HAL_UART_MspInit中調用HAL_GPIO_Init函數。
  • 串口接收中斷優先級配置和使能:
    HAL_NVIC_EnableIRQ();
    HAL_NVIC_SetPriority();
  • 使能串口接收中斷:HAL_UART_Receive_IT();
  • 編寫中斷服務函數:USARTx_IRQHandler
  • 根據如上步驟,其中1、2步驟和串口發送設置差不多,第三步,HAL_NVIC_SetPriority(USART1_IRQn,3,3);搶占和響應優先級均設置為3.這是因為main中的HAL_Init();有一個設置是 HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);

    #include "sys.h" #include "delay.h" #include "usart.h" u8 rdata[1];//因為是每接收一個就發出去,所以設置為1 UART_HandleTypeDef usart1_handler; //初始化串口相關參數,使能串口 void uart1_init(void) {usart1_handler.Instance = USART1;usart1_handler.Init.BaudRate = 115200;usart1_handler.Init.WordLength = UART_WORDLENGTH_8B;usart1_handler.Init.StopBits = UART_STOPBITS_1;usart1_handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;usart1_handler.Init.Mode = UART_MODE_TX_RX;usart1_handler.Init.Parity = UART_PARITY_NONE;HAL_UART_Init(&usart1_handler); } //串口相關IO口配置,復用配置 void HAL_UART_MspInit(UART_HandleTypeDef *huart) {GPIO_InitTypeDef GPIO_Initure;if(huart->Instance==USART1){__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA時鐘__HAL_RCC_USART1_CLK_ENABLE(); //使能USART1時鐘GPIO_Initure.Pin=GPIO_PIN_9; //PA9GPIO_Initure.Mode=GPIO_MODE_AF_PP; //復用推挽輸出GPIO_Initure.Pull=GPIO_PULLUP; //上拉GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速GPIO_Initure.Alternate=GPIO_AF7_USART1; //復用為USART1HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA9GPIO_Initure.Pin=GPIO_PIN_10; //PA10HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10//串口接收中斷優先級配置和使能HAL_NVIC_SetPriority(USART1_IRQn,3,3);//設置中斷優先級HAL_NVIC_EnableIRQ(USART1_IRQn);//使能中斷通道} } //編寫中斷服務函數 void USART1_IRQHandler() {HAL_UART_IRQHandler(&usart1_handler);//由于調用一次中斷,進入中斷回調函數后,中斷就結束了,所以還要開啟中斷HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata));//使能接收中斷 } //編寫接收完成中斷回調函數 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {u8 rec;if(huart->Instance==USART1){//rec = *((huart->pRxBuffPtr)-1);rec = rdata[0];//保存接收到的數據HAL_UART_Transmit(&usart1_handler,&rec,1,1000);} } int main(void) {Cache_Enable(); //打開L1-CacheHAL_Init(); //初始化HAL庫Stm32_Clock_Init(432,25,2,9); //設置時鐘,216Mhz delay_init(216);uart1_init();HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata));//使能接收中斷while(1){}}

    總結

    以上是生活随笔為你收集整理的STM32 串口接收流程-串口接收中断的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。