目录
在使用蓝牙模块时,经常会产生数据错位,导致解码出问题,按照本文所展示的方法操作后,问题解决,效果丝滑
一、配置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里更新了
制作不易,感谢支持!