STM32 Cube使用uart DMA空闲中断接收数据包

目录

一、配置Cube

二、配置keil 

UART_DMA.c

UART_DMA.h

 添加UART_DMA.c

添加UART_DMA.h 

 引用相关函数


在使用蓝牙模块时,经常会产生数据错位,导致解码出问题,按照本文所展示的方法操作后,问题解决,效果丝滑

一、配置Cube

时钟:

 Debug:

时钟树: 

UART参数配置: 

DMA配置: 

 使能中断: 

 工程信息:

这个配置可以让工程更小: 

二、配置keil 

生成代码后添加两个文件UART_DMA.c 和UART_DMA.h,代码如下

UART_DMA.c

/* Includes ------------------------------------------------------------------*/
#include "UART_DMA.h"
uint8_t rxbuff[100];//数据接收缓冲区	
RemoteData rxdata;//接收数据的结构体

/* Functions ----------------------------------------------------------*/
/**
  * @brief UartDma初始化
  * @param huart Uart句柄; size 接收数据的长度
  */
void Uart_InitUartDMA(UART_HandleTypeDef* huart, uint8_t rxbuff[], uint32_t size) { 
    /* open uart idle it */
    __HAL_UART_CLEAR_IDLEFLAG(huart);
    __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);
		
		rxdata.x = 0;
		rxdata.y = 0;

    uint32_t tmp1 = 0;
    tmp1 = huart->RxState;
    if (tmp1 == HAL_UART_STATE_READY) {
        if ((rxbuff == NULL) || (size == 0)) {
            return;
        }
        huart->pRxBuffPtr = rxbuff;
        huart->RxXferSize = size;
        huart->ErrorCode  = HAL_UART_ERROR_NONE;
        /* Enable the DMA Stream */
        HAL_DMA_Start(huart->hdmarx, (uint32_t)&huart->Instance->DR, (uint32_t)rxbuff, size);
        /* 
         * Enable the DMA transfer for the receiver request by setting the DMAR bit
         * in the UART CR3 register 
         */
        SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
    }
}
/**
  * @brief 解码函数(自定义)这里所写的是一个遥控器两个摇杆的解码
  */
void Decode(RemoteData *rxdata,uint8_t *rxbuff)
{
		if(rxbuff[0] == 0xA5&&rxbuff[10] == 0x5A){
			*((uint8_t*)& rxdata->x) = rxbuff[1];
			*((uint8_t*)& rxdata->x+1) = rxbuff[2];
			*((uint8_t*)& rxdata->x+2) = rxbuff[3];
			*((uint8_t*)& rxdata->x+3) = rxbuff[4];
			
			*((uint8_t*)& rxdata->y) = rxbuff[5];
			*((uint8_t*)& rxdata->y+1) = rxbuff[6];
			*((uint8_t*)& rxdata->y+2) = rxbuff[7];
			*((uint8_t*)& rxdata->y+3) = rxbuff[8];
			rxdata->x += 0.5f;
			rxdata->y += 0.5f;
		}
}
/**
  * @brief 数据接收回调
  */
void Uart_ReceiveHandler(UART_HandleTypeDef *huart) {
	// clear idle it flag after uart receive a frame data
	if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) && __HAL_UART_GET_IT_SOURCE(huart, UART_IT_IDLE)) {
		/* clear idle it flag avoid idle interrupt all the time */
		__HAL_UART_CLEAR_IDLEFLAG(huart);
		/* handle received data in idle interrupt */
		__HAL_DMA_DISABLE(huart->hdmarx);
		Decode(&rxdata, rxbuff);
	__HAL_DMA_SET_COUNTER(huart->hdmarx, RXSIZE);
	__HAL_DMA_ENABLE(huart->hdmarx);
	}
}
/***************************本人不帅**END OF FILE*****************************/

UART_DMA.h

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"
	
#define __HAL_DMA_SET_COUNTER(__HANDLE__, __COUNTER__) ((__HANDLE__)->Instance->CNDTR = (uint16_t)(__COUNTER__))

#define RXSIZE 11    //接收数据的长度
	
typedef struct    //接收数据结构体,可自定义
{
	float x;
	float y;
}RemoteData;

extern RemoteData rxdata;
extern uint8_t rxbuff[];
 

void Uart_InitUartDMA(UART_HandleTypeDef* huart, uint8_t rxbuff[], uint32_t size);
void Uart_ReceiveHandler(UART_HandleTypeDef *huart);
#ifdef __cplusplus
}
#endif
/************************ 本人不帅 *****END OF FILE****/

一下展示一种添加方法,如果觉得太麻烦,可以直接将对应代码粘贴到main.c里 

 添加UART_DMA.c

右键单击Application/User/Core

如图操作 

将UART_DMA.c的代码粘贴进去 

添加UART_DMA.h 

操作类似

粘贴UART_DMA.h的代码 

 引用相关函数

在main.c里添加头文件

引用初始化函数 

在stm32f1xx.c里添加头文件 

引用中断处理函数 

此时如果进行编译应该会有两个error,因为新添加的文件没有添加编译路径

下面进行添加 

后退一级 

 再次编译,就没有报错了,此时烧录、运行代码,uart的数据就会在rxdata里更新了

 制作不易,感谢支持!

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

本人不帅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值