色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

STM32基礎知識:串口通信-中斷方式

CHANBAEK ? 來源:上下求索電子er ? 作者:上下求索電子er ? 2023-10-25 15:21 ? 次閱讀

串口通信-中斷方式

1 中斷方式的串口通信

串口中斷方式的特點:

  • 發送數據時,將一字節數據放入數據寄存器DR;接收數據時,將DR的內容存放到用戶存儲區;
  • 中斷方式不必等待數據的傳輸過程,只需要在每字節數據收發完成后,由中斷標志位觸發中斷,在中斷服務程序中放入新的一字節數據或者讀取接收到的一字節數據;
  • 在傳輸數據量較大,且通信波特率較高(大于38400)時,如果采用中斷方式,每收發一個字節的數據,CPU都會被打斷,造成CPU無法處理其他事務。因此在批量數據傳輸,通信波特率較高時,建議采用DMA方式。
  1. 串口中斷方式發送函數:HAL_UART_Transmit_IT

    函數原型HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_Handle TypeDef *huart, uint 8_t *pData, uint 16_t Size)
    功能描述在中斷方式下發送一定數量的數據
    入口參數1huart:串口句柄的地址
    入口參數pData:待發送數據的首地址
    入口參數3Size:待發送數據的個數
    入口參數4Timeout:超時等待時間, 以ms為單位, HAL MAX DELAY表示無限等待
    返回值HAL狀態值:HAL_OK表示發送成功;HAL_ERROR表示參數錯誤;HAL_BUSY表示串口被占用;
    注意事項1. 函數將使能串口發送中斷2. 函數將置位TXEIE和TCIE,使能發送數據寄存器空中斷和發送完成中斷。完成指定數量的數據發送后,將會關閉發送中斷,即清零TXEIE和TCIE。因此用戶采用中斷方式連續發送數據時,需要重復調用該函數,以便重新開啟發送中斷3. 當指定數量的數據發送完成后,將調用發送中斷回調函數HAL_UART_TxCpltCallback進行后續處理4. 該函數由用戶調用
  2. 串口中斷方式接收函數:HAL_UART_Receive_IT

    函數原型HAL_StatusTypeDef HAL_UART_Receive_IT(UART_Handle TypeDef *huart, uint 8_t *pData, uint 16_t Size, uint 32_t Timeout)
    功能描述在中斷方式下接收一定數量的數據
    入口參數1huart:串口句柄的地址
    入口參數2pData:存放數據的首地址
    入口參數3Size:待接收數據的個數
    入口參數4Timeout:超時等待時間, 以ms為單位, HAL MAX DELAY表示無限等待
    返回值HAL狀態值:HAL_OK表示發送成功;HAL_ERROR表示參數錯誤;HAL_BUSY表示串口被占用;
    注意事項1. 函數將使能串口接收中斷2. 函數將置位RXNEIE,使能接收數據寄存器非空中斷RXNE。完成指定數量的數據接收后,將會關閉接收中斷,即清零RXNEIE。因此用戶采用中斷方式連續接收數據時,要重復調用該函數,以重新開啟接收中斷3. 當指定數量的數據接收完成后,將調用接收中斷回調函數HAL_UART_RxCpltCallback進行后續處理4. 該函數由用戶調用
  3. 串口中斷通用處理函數:HAL_UART_IRQHandler

    函數原型void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
    功能描述作為所有串口中斷發生后的通用處理函數
    入口參數htim:定時器句柄的地址
    返回值
    注意事項1. 函數內部先判斷中斷類型,并清除對應的中斷標志,最后調用回調函數完成對應的中斷處理2. 該函數由CubeMX自動生成
  4. 串口發送中斷回調函數:HAL_UART_TxCpltCallback

    函數原型void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
    功能描述回調函數,用于處理所有串口的發送中斷,用戶在該函數內編寫實際的任務處理程序
    入口參數htim:定時器句柄的地址
    返回值
    注意事項1. 函數由串口中斷通用處理函數HAL_UART_IRQHandler調用,完成所有注意事項2.串口的發送中斷任務處理函數內部需要根據串口句柄的實例來判斷是哪一個串口產生的發送中斷3. 函數由用戶根據具體的處理任務編寫
  5. 串口接收中斷回調函數:HAL_UART_RxCpltCallback

    函數原型void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    功能描述回調函數,用于處理所有串口的接收中斷,用戶在該函數內編寫實際的任務處理程序
    入口參數htim:定時器句柄的地址
    返回值
    注意事項1. 函數由串口中斷通用處理函數HAL_UART_IRQHandler調用,完成所有注意事項2.串口的發送中斷任務處理函數內部需要根據串口句柄的實例來判斷是哪一個串口產生的接收中斷3. 函數由用戶根據具體的處理任務編寫
  6. 串口中斷使能函數:__HAL_UART_ENABLE_IT

    函數原型__HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__)
    功能描述使能對應的串口中斷類型
    入口參數__INTERRUPT __ :串口中斷類型,該參數幾個常用的取值如下UART_IT_TXE :發送數據寄存器空中斷UART_IT_TC :發送完成中斷UART_IT_RXNE:接收數據寄存器非空中斷UART_IT_IDLE :線路空閑中斷
    返回值
    注意事項1. 該函數是宏函數,進行宏替換,不發生函數調用2. 函數需要由用戶調用,用于使能對應的串口中斷類型
  7. 串口中斷標志查詢函數:__HAL_UART_GET_FLAG

    函數原型__HAL_UART_GET_FLAG (__HANDLE__, __INTERRUPT__)
    功能描述查詢對應的串口中斷類型
    入口參數__INTERRUPT __ :串口中斷類型,該參數幾個常用的取值如下UART_IT_TXE :發送數據寄存器空中斷UART_IT_TC :發送完成中斷UART_IT_RXNE:接收數據寄存器非空中斷UART_IT_IDLE :線路空閑中斷
    返回值中斷標志的狀態值:SET表示中斷標志置位;RESET表示中斷標志沒有置位
    注意事項1. 該函數是宏函數,進行宏替換,不發生函數調用2. 函數需要由用戶調用,用于查詢對應的串口中斷類型
  8. 空閑中斷標志清除函數:__HAL_UART_CLEAR_IDLEFLAG

    函數原型__HAL_UART_CLEAR_IDLEFLAG
    功能描述清除串口的空閑中斷標志
    入口參數HANDLE :串口句柄的地址
    返回值
    注意事項1. 該函數是宏函數,進行宏替換,不發生函數調用2. 函數需要由用戶調用,用于清除對應的串口空閑中斷標志

2 HAL庫串口中斷處理過程:

圖片

  • HAL_UART_Receive_IT:開啟中斷,在中斷方式下接收一定數量的數據。
  • USART2_IRQHandler:串口2的中斷服務程序,調用串口中斷通用處理函數HAL_UART_IRQHandler
  • HAL_UART_IRQHandler:在函數 HAL_UART_IRQHandler內部通過判斷中斷類型是否為接收完成中斷,確定是否調用UART_Receive_IT。

函數UART_Receive_IT的作用是把每次中斷接收到的字符保存在串口句柄的緩存指針pRxBuffPtr中,同時每次接收一個字符,其計數器 RxXferCount 減 1,直到接收完成 RxXferSize 個字符之后 RxXferCount設置為0,同時調用接收完成回調函數 HAL_UART_RxCpltCallback進行處理。

  • HAL_UART_RxCpltCallback:函數由串口中斷通用處理函數UART_Receive_IT調用,完成所有串口的接收中斷任務處理,函數內部需要根據串口句柄的實例來判斷是哪一個串口產生的接收中斷,函數由用戶根據具體的處理任務編寫。

3 任務實踐2

利用串口調試助手,從PC上發送10個字符到開發板,開發板收到后原樣發回到PC。

前后臺編程模式: 前臺程序為中斷服務程序,一旦數據接收完成,則設置一個標志位為1;后臺程序為while(1)的死循環,在循環中不斷檢測標志位是否為1。如果為1,表明數據接收完成,并存放在接收緩沖區中。然后進行后續處理:先清除標志位,再把接收的數據原樣發回。

  1. 串口外設配置
    圖片
    圖片

    1. 異步模式,無硬件流控
    2. 設置通信參數:波特率115200,8位數據位,無奇偶校驗,1位停止位,使能接收和發送,16倍過采樣(CubeMX默認配置)
    3. 使能串口中斷
  2. 編寫代碼
    printf和scanf重定向:略

    // -----------------------------------------------------------------------//
    /* USER CODE BEGIN PD */
    #define LENGTH 10         // 接收數據緩沖區大小
    /* USER CODE END PD */
    
    // -----------------------------------------------------------------------//
    /* USER CODE BEGIN PV */
    uint8_t RxBuffer[LENGTH]; // 接收緩沖區
    uint8_t RxFlag = 0;       // 接收完成標志,0未完成,1完成
    /* USER CODE END PV */
    
    // -----------------------------------------------------------------------//
      /* USER CODE BEGIN 2 */
      // 打印提示信息
      printf("UART Communication Using ITn");
      printf("Please enter 10 characters:n");
      HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuffer, LENGTH);  // 使能接收中斷
      /* USER CODE END 2 */
    
    // -----------------------------------------------------------------------//
      while (1)
      {
        /* USER CODE BEGIN 3 */
        if (RxFlag == 1)   // 判斷接收是否完成
        {
          RxFlag = 0;      // 接收完成,清除標志位
          printf("Receive Successfully!n");  // 打印提示信息
          HAL_UART_Transmit_IT(&huart1, (uint8_t*)RxBuffer, LENGTH);  // 將接收的字符原樣發回
        }
      }
      /* USER CODE END 3 */
    
    // -----------------------------------------------------------------------//
    /* USER CODE BEGIN 4 */
    int fputc(int ch, FILE *f)
    {
      HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
      return ch;
    }
    
    int fgetc(FILE *f)
    {
      uint8_t ch = 0;
      HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
      return ch;
    }
    
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
      if (huart- >Instance == USART1)  // 判斷發生接收中斷的串口
      {
        RxFlag = 1;  // 置位接收完成b標志
        HAL_UART_Receive_IT(&huart1, (uint8_t*)RxBuffer, LENGTH);  // 使能接收中斷
      }
    }
    /* USER CODE END 4 */
    // -----------------------------------------------------------------------//
    

    實驗現象

    圖片

4 任務實踐3

實現簡單的幀格式通信:PC按照自定義的幀格式發送指令開啟或關閉開發板上的LED1。

幀格式的概念:

  1. 幀(Frame)是數據傳輸的一種單位。一幀數據由多個字符組合而成,不同字段的字符代表不同的含義,執行不同的功能;
  2. 在實際的工程應用中,數據的傳輸常常以幀為單位來進行,如工控領域中最常用的Modbus通信協議中的消息幀;
  3. 發送方按照規定的幀格式發送一幀數據,接收方接收下這一幀數據后,再按照幀格式進行解析,最后完成后續的處理。

Modbus消息幀格式:

起始符設備地址功能代碼數據校驗結束符
1個字符2個字符1個字符n個字符2個字符1個字符
  • 起始符:表示一幀數據的開始
  • 設備地址:用于指定需要進行信息傳遞的設備
  • 功能代碼:用于指定需要完成的操作
  • 數據:表示需要傳輸的數據
  • 校驗:用于通信中的錯誤校驗
  • 結束符:表示一幀數據的結束

自定義的幀格式設定:

幀頭設備碼功能碼幀尾
0xaa1個字符(8bit)1個字符(8bit)0x55
  • 幀頭 :0xaa表示一幀數據的開始
  • 設備碼:0x01表示指示燈
  • 功能碼:0x00表示關閉指示燈,0x01表示開啟指示燈
  • 幀尾 :0x55表示一幀數據的結束
  1. 串口配置同任務實踐1

  2. 配置PA1為GPIO_Output模式

  3. 編寫代碼

    // -----------------------------------------------------------------------//
    /* USER CODE BEGIN PV */
    uint8_t RxBuffer[4];  // 接收緩沖區
    uint8_t RxFlag = 0;   // 接收完成標志,0位完成,1完成
    uint8_t ErrFlag = 0;  // 指令錯誤標志,0正確,1錯誤
    /* USER CODE END PV */
    
    // -----------------------------------------------------------------------//
      /* USER CODE BEGIN 2 */
      // 打印提示信息
      printf("*****  Communication Frame  *****n");
      printf("Please enter instruction:n");
      printf("Head- >0xaa, Device- >0x01, Operation- >0x00/0x10, Tail- >0x55n");
      HAL_UART_Receive_IT(&huart1, (uint8_t*)RxBuffer, 4);  // 使能接收中斷
      /* USER CODE END 2 */
    
    // -----------------------------------------------------------------------//
      while(1)
      {
        /* USER CODE BEGIN 3 */
        // Determine if reception is complete
        if (RxFlag == 1)  // 判斷接收是否完成              
        {
          RxFlag = 0;     // 完成,清除標志位   
    
          // 幀格式解析
          printf("head = RxBuffer[0] = %xn", RxBuffer[0]);
          printf("tail = RxBuffer[3] = %xn", RxBuffer[3]);
          printf("device = RxBuffer[1] = %xn", RxBuffer[1]);
          printf("function = RxBuffer[2] = %xn", RxBuffer[2]);
    
          if (RxBuffer[0] == 0xaa && RxBuffer[3] == 0x55)  // 判斷幀頭幀尾
          {
            if (RxBuffer[1] == 0x01)          // 判斷設備碼
            {
              if (RxBuffer[2] == 0x00)        // 判斷功能碼
              {
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
                printf("LED1 is close!n");
              }
              else if (RxBuffer[2] == 0x01)   // 判斷功能碼
              {
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
                printf("LED1 is open!n");
              }
              else              // 功能碼錯誤
              {
                ErrFlag = 3;
              }
            }
            else                // 設備碼錯誤
            {
              ErrFlag = 2;      
            }
          }
          else                  // 幀頭幀尾錯誤
          {
            ErrFlag = 1;
          }
    
          // 發送錯誤提示信息
          switch (ErrFlag)
          {
            case 1: 
              printf("Head and tail error! Please send again!n");
              break;
            case 2: 
              printf("Device code error! Please send again!n");  
              break;
            case 3: 
              printf("Function code error! Please send again!n");  
              break;   
            default:
              break;
          }
    
          // 清除接收緩沖區和錯誤標志,準備下一次接收
          ErrFlag = 0;
          RxBuffer[0] = 0;
          RxBuffer[1] = 0;
          RxBuffer[2] = 0;
          RxBuffer[3] = 0;
        }
      }
      /* USER CODE END 3 */
    
    // -----------------------------------------------------------------------//
    /* USER CODE BEGIN 4 */
    int fputc (int ch, FILE *f)
    {
        HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
        return ch;
    }
    
    int fgetc(FILE *f)
    {
        uint8_t ch = 0;
        HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
        return ch;
    }
    
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
      if (huart- >Instance == USART1)  // 判斷發生接收中斷的串口
      {
        RxFlag = 1;  // 置位接收完成標志
        HAL_UART_Receive_IT(&huart1 , (uint8_t*)RxBuffer, 4);  // 使能串口中斷
      }
    }
    /* USER CODE END 4 */
    

    實驗現象

圖片

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5363

    瀏覽量

    120933
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10901

    瀏覽量

    212664
  • STM32
    +關注

    關注

    2270

    文章

    10923

    瀏覽量

    357076
  • 中斷
    +關注

    關注

    5

    文章

    900

    瀏覽量

    41648
  • 串口通信
    +關注

    關注

    34

    文章

    1627

    瀏覽量

    55656
收藏 人收藏

    評論

    相關推薦

    USART串口基礎知識

    第29章 STM32H7的USART串口基礎知識和HAL庫API本章節為大家講解USART(Universal synchronous asynchronous receiver transmitter,通用同步異步收發器)的
    發表于 08-20 08:05

    STM32中斷基礎知識及配置過程,絕對實用

    STM32中斷基礎知識及配置過程,絕對實用
    發表于 11-17 07:10

    STM32串口通信基礎知識點匯總,不看肯定后悔

    STM32串口通信基礎知識點匯總,不看肯定后悔
    發表于 12-03 08:03

    串口基礎知識點匯總

    串行口一串口基礎知識串口概念串行接口(Serial port)"同步/異步串行接收/發送器。"又稱“串口”USART,也稱串行通信接口(通常
    發表于 02-23 07:27

    STM32 | 串口空閑中斷接收不定長數據(DMA方式

    在使用STM32串口接收數據的時候,我們常常會使用接收中斷方式來接收數據,常用的是RXNE。這里分享另一種接收數據的方式——IDLE
    發表于 11-20 12:51 ?17次下載
    <b class='flag-5'>STM32</b> | <b class='flag-5'>串口</b>空閑<b class='flag-5'>中斷</b>接收不定長數據(DMA<b class='flag-5'>方式</b>)

    stm32CubeMX中斷模式編程點燈并實現串口點燈(中斷方式

    文章目錄一、中斷介紹1.基礎知識2.中斷向量表3.中斷過程二、CubeMX中斷方式點燈1.題目要
    發表于 11-21 18:21 ?4次下載
    <b class='flag-5'>stm32</b>CubeMX<b class='flag-5'>中斷</b>模式編程點燈并實現<b class='flag-5'>串口</b>點燈(<b class='flag-5'>中斷</b><b class='flag-5'>方式</b>)

    DMA通信編程與STM32串口中斷方式

    目錄DMA通信原理DMA的基本介紹DMA工作原理STM32的DMA結構DMA的主要特性DMA寄存器列表DMA進行數據傳輸的必要條件中斷實驗練習STM32用HAL庫點亮LED燈任務要求實
    發表于 11-26 19:21 ?13次下載
    DMA<b class='flag-5'>通信</b>編程與<b class='flag-5'>STM32</b><b class='flag-5'>串口中斷</b><b class='flag-5'>方式</b>

    STM32中斷串口DMA通信

    一管腳接一個LED,GPIOB端口一引腳接一個開關(用杜邦線模擬代替)。采用中斷模式編程,當開關接高電平時,LED亮燈;接低電平時,LED滅燈。2. 采用串口中斷方式重做上篇博客中的串口
    發表于 12-06 20:36 ?11次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>中斷</b>與<b class='flag-5'>串口</b>DMA<b class='flag-5'>通信</b>

    STM32串口通訊——中斷方式

    一、簡介在上一次我們學習了如何使用查詢的方式進行串口通訊——發送數據,以及中斷方式,在本次我們使用中斷來進行
    發表于 12-07 09:51 ?27次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b>通訊——<b class='flag-5'>中斷</b><b class='flag-5'>方式</b>

    STM32CubeMX使用串口中斷方式實現串口通信

    中斷方式),要求:1)設置波特率為115200,1位停止位,無校驗位;2)STM32系統給上位機(win10)連續發送“hello windows!”。win10采用“串口助手”工具接
    發表于 12-07 10:36 ?10次下載
    <b class='flag-5'>STM32</b>CubeMX使用<b class='flag-5'>串口中斷</b><b class='flag-5'>方式</b>實現<b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    串口通信基礎知識詳解

    目錄通信基礎知識STM32串口通信基礎(UART)串口通信
    發表于 12-20 19:20 ?14次下載
    <b class='flag-5'>串口</b><b class='flag-5'>通信</b><b class='flag-5'>基礎知識</b>詳解

    STM32中的串口通信基礎知識

    目錄串口通信基本原理并行通信與串行通信串行通信中單工,半雙工和全雙工的區別按通信
    發表于 12-24 18:37 ?4次下載
    <b class='flag-5'>STM32</b>中的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>的<b class='flag-5'>基礎知識</b>

    STM32串口中斷之DMA通信

    一.DMA介紹DMA詳細介紹請轉博客:嵌入式:初次了解STM32的USART串口通訊(中斷方式)_LaiYiFei25的博客-CSDN博客DMA框圖二.
    發表于 12-24 19:08 ?12次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>串口中斷</b>之DMA<b class='flag-5'>通信</b>

    STM32CubeMX實現串口通信中斷方式

    這里寫目錄標題一、STM32CubeMX工程創建1、題目要求2、配置STM32CubeMX工程一、STM32CubeMX工程創建1、題目要求完成一個STM32的USART
    發表于 12-24 19:18 ?11次下載
    <b class='flag-5'>STM32</b>CubeMX實現<b class='flag-5'>串口</b><b class='flag-5'>通信</b>(<b class='flag-5'>中斷</b><b class='flag-5'>方式</b>)

    STM32串口通信簡明知識

    STM32串口通信簡明知識
    的頭像 發表于 10-25 15:48 ?1370次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b><b class='flag-5'>通信簡明知識</b>
    主站蜘蛛池模板: 野花韩国免费高清电影 | 久9青青cao精品视频在线 | 第一次破女初国产美女 | 久久高清免费视频 | 男女高潮又爽又黄又无遮挡 | 国产自产第一区c国产 | 国产成人片视频一区二区青青 | 88.7在线收听 | 亚洲综合小说久久另类区 | www黄色大片 | 欧美在线亚洲综合国产人 | 美女张开腿让男生桶动态图 | 蜜芽丅v新网站在线观看 | 国产精品青青草原app大全 | 国产亚洲精品99一区二区 | 久久精品伊人 | 亚洲精品沙发午睡系列 | 男人扒开添女人下部口述 | 国产香蕉视频在线播放 | 国产白丝JK被疯狂输出视频 | 欧美乱妇狂野欧美在线视频 | 日本国产成人精品无码区在线网站 | 亚洲黄色片免费看 | 国产全部视频列表支持手机 | 狠很橹快播 | 中文字幕不卡免费高清视频 | 天天综合亚洲综合网站 | 伦理79电影网在线观看 | 国产在线精品亚洲视频在线 | 男男gaygay拳头 | 中文字幕精品视频在线 | 男女生爽爽爽视频免费观看 | 亚洲高清一区二区三区电影 | 色播播电影 | 香蕉免费高清完整 | 国产免费久久爱久久啪 | 日本不卡一二三 | 好男人好资源在线观看 | 一区视频免费观看 | 亚州AV中文无码乱人伦在线 | 国产午夜精品视频在线播放 |