stm32 HAL库学习笔记5——串口DMA空闲中断,接收不定长数据包
开发环境
- STM32CubeMX, Version6.1.0
- Keil, uVision V5.23.0.0
- STM32F103ZET6开发板
参考博客
遇到的问题总结
不能仿真
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 */
}