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 */
}
posted @ 2021-02-01 22:12  JerryZheng2020  阅读(1550)  评论(0编辑  收藏  举报