stm32 HAL庫學習筆記5——串口DMA空閑中斷,接收不定長數據包


TOC

開發環境

  • STM32CubeMX, Version6.1.0
  • Keil, uVision V5.23.0.0
  • STM32F103ZET6開發板

參考博客

Yonas-Luo

遇到的問題總結

不能仿真

Can not read register xx while CPU is running

原因是: cubemx生成的代碼中禁用了swd調試,需要手動注釋掉,如下面所示, 注釋掉__HAL_AFIO_REMAP_SWJ_DISABLE

void HAL_MspInit(void)
{
  /* USER CODE BEGIN MspInit 0 */

  /* USER CODE END MspInit 0 */

  __HAL_RCC_AFIO_CLK_ENABLE();
  __HAL_RCC_PWR_CLK_ENABLE();

  /* System interrupt init*/

  /** DISABLE: JTAG-DP Disabled and SW-DP Disabled
  */
  //__HAL_AFIO_REMAP_SWJ_DISABLE();

  /* USER CODE BEGIN MspInit 1 */

  /* USER CODE END MspInit 1 */
}

編譯優化等級

另外如有必要,調試時還需要將優化等級調整為level0

memset未聲明

使用memset需要添加頭文件 #include "string.h"

添加的源碼

main.c

__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);

usart.c

#include "usart.h"
#include "string.h"

//聲明外部變量
extern uint8_t receive_buff[255];
extern DMA_HandleTypeDef hdma_usart1_rx;

void USAR_UART_IDLECallback(UART_HandleTypeDef *huart);

void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)                                   //判斷是否是串口1(!此處應寫(huart->Instance == USART1)
    {
        if(RESET != __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))   //判斷是否是空閑中斷
        {
            __HAL_UART_CLEAR_IDLEFLAG(huart);                     //清楚空閑中斷標志(否則會一直不斷進入中斷)
            //printf("\r\nUART1 Idle IQR Detected\r\n");
            USAR_UART_IDLECallback(huart);                          //調用中斷處理函數
        }
    }
}


void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
{
    HAL_UART_DMAStop(huart);                                                     //停止本次DMA傳輸

    uint8_t data_length  = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);   //計算接收到的數據長度

    //printf("Receive Data(length = %d): ",data_length);
    HAL_UART_Transmit(huart,receive_buff,data_length,0x200);                     //測試函數:將接收到的數據打印出去
    //printf("\r\n");

    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_0);

    memset(receive_buff,0,data_length);                                            //清零接收緩沖區
    data_length = 0;
    HAL_UART_Receive_DMA(huart, (uint8_t*)receive_buff, 255);                    //重啟開始DMA傳輸 每次255字節數據
}

usart.h

#ifndef __USART_H
#define __USART_H
#include "main.h"
#define  BUFFER_SIZE  (255)
void USER_UART_IRQHandler(UART_HandleTypeDef *huart);

#endif

stm32f1xx_it.c

// 在串口1中斷回調函數中添加 USER_UART_IRQHandler(&huart1);
// 用於處理空閑中斷
#include "usart.h"
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  USER_UART_IRQHandler(&huart1);
  /* USER CODE END USART1_IRQn 1 */
}

stm32f1xx_hal_msp.c

注釋掉__HAL_AFIO_REMAP_SWJ_DISABLE();,用於在線調試

/**
  * Initializes the Global MSP.
  */
void HAL_MspInit(void)
{
  /* USER CODE BEGIN MspInit 0 */

  /* USER CODE END MspInit 0 */

  __HAL_RCC_AFIO_CLK_ENABLE();
  __HAL_RCC_PWR_CLK_ENABLE();

  /* System interrupt init*/

  /** DISABLE: JTAG-DP Disabled and SW-DP Disabled
  */
  //__HAL_AFIO_REMAP_SWJ_DISABLE();

  /* USER CODE BEGIN MspInit 1 */

  /* USER CODE END MspInit 1 */
}


免責聲明!

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



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