[STM32 HAL]一种可能不错的DMA处理串口数据方案
[STM32 HAL]一种可能不错的DMA处理数据方案
原文链接:https://blog.csdn.net/youmeichifan/article/details/51750435?spm=1001.2014.3001.5506
本文配置稍有不同,大体类似。
MX配置
开启USART1,使能USART1全局中断,打开RX,TX的DMA通道,均为normal模式,内存地址自增,使能TX对应DMA的中断,RX不需要。
代码部分
- 在main.c里将MX_DMA的初始化放在MX_UART的初始化之前
usart.h:
/* USER CODE BEGIN Prototypes */
#define RECEIVELEN 1024
#define USART_DMA_SENDING 1//发鿁未完成
#define USART_DMA_SENDOVER 0//发鿁完房
typedef struct
{
uint8_t receive_flag:1; // 空闲接收标记
uint8_t dmaSend_flag:1; // 发鿁完成标访
uint16_t rx_len; // 接收长度
uint8_t usartDMA_rxBuf[RECEIVELEN]; // DMA接收缓存
}USART_RECEIVETYPE;
extern USART_RECEIVETYPE usartType1;
void __USART_Receive_IDLE(UART_HandleTypeDef *huart);
void __USART_SendData_DMA(uint8_t *pdata, uint16_t Length);
/* USER CODE END Prototypes */
usart.c:
/* USER CODE BEGIN 0 */
#include "string.h"
#include "main.h"
USART_RECEIVETYPE usartType1;
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
void __USART_SendData_DMA(uint8_t *pdata, uint16_t Length)
{
while(usartType1.dmaSend_flag == USART_DMA_SENDING);
usartType1.dmaSend_flag = USART_DMA_SENDING;
HAL_UART_Transmit_DMA(&huart1, pdata, Length);
}
//DMA发鿁完成中断回调函敿
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, 1);
__HAL_DMA_DISABLE(huart->hdmatx);
usartType1.dmaSend_flag = USART_DMA_SENDOVER;
//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, 0);
}
//串口接收空闲中断
void __USART_Receive_IDLE(UART_HandleTypeDef *huart)
{
uint32_t temp;
if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_UART_DMAStop(huart);
temp = huart1.hdmarx->Instance->NDTR;
usartType1.rx_len = RECEIVELEN - temp;
usartType1.receive_flag=1;
HAL_UART_Receive_DMA(&huart1,usartType1.usartDMA_rxBuf,RECEIVELEN);
}
}
/* USER CODE END 1 */
stm32f4xxit.c:
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
__USART_Receive_IDLE(&huart1); // 这段代码是自己加进去的
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
main.c:
/* USER CODE BEGIN PV */
char rxStr[256];
char drawBuffer1[256];
char drawBuffer2[256];
char drawBuffer3[256];
/* USER CODE END PV */
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart1, usartType1.usartDMA_rxBuf, RECEIVELEN);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
/* USER CODE END 2 */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(usartType1.receive_flag)
{
usartType1.receive_flag = 0;
//printf("%s\r\n", (char*)usartType1.usartDMA_rxBuf);
strcpy(rxStr, (char*)usartType1.usartDMA_rxBuf);
// 处理数据
get_Data(rxStr, drawBuffer1, 'a', 'b');
get_Data(rxStr, drawBuffer2, 'b', 'c');
get_Data(rxStr, drawBuffer3, 'c', 'd');
memset(usartType1.usartDMA_rxBuf, 0x00, sizeof(usartType1.usartDMA_rxBuf));
}
//__USART_SendData_DMA((uint8_t*)sendBuffer1, sizeof(sendBuffer1));
u8g2_FirstPage(&u8g2);
do
{
u8g2_DrawStr(&u8g2, 0, 15, drawBuffer1);
u8g2_DrawStr(&u8g2, 0, 30, drawBuffer2);
u8g2_DrawStr(&u8g2, 0, 45, drawBuffer3);
}while(u8g2_NextPage(&u8g2));
}
/* USER CODE END 3 */
然后基本就可以了
但这个方案好像有点小问题,具体还没有搞清楚,大体是可以用的,至少可以接收电脑发送的数据并处理且显示,等有空再好好研究一下啦~
[STM32 HAL]一种可能不错的DMA处理串口数据方案的更多相关文章
- STM32使用DMA发送串口数据
1.概述 上一篇文章<STM32使用DMA接收串口数据>讲解了如何使用DMA接收数据,使用DMA外设和串口外设,使用的中断是串口空闲中断.本篇文章主要讲解使用DMA发送数据,不会讲解基础的 ...
- STM32—无需中断来实现使用DMA接收串口数据
本节目标: 通过DMA,无需中断,接收不定时长的串口数据 描述:当在串口多数据传输下,CPU会产生多次中断来接收串口数据,这样会大大地降低CPU效率,同时又需要CPU去做其它更重要的事情,我们应该如何 ...
- STM32 HAL库的定时器中断回调函数跟串口中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { //添加回调后的程序逻辑 if (htim->Instance == ...
- 利用DMA实现采样数据的直接搬运存储
尝试了下STM32的ADC采样,并利用DMA实现采样数据的直接搬运存储,这样就不用CPU去参与操作了. 找了不少例子参考,ADC和DMA的设置了解了个大概,并直接利用开发板来做一些实验来验证相关的操作 ...
- DMA实现采样数据的直接搬运存储
尝试了下STM32的ADC采样,并利用DMA实现采样数据的直接搬运存储,这样就不用CPU去参与操作了. 找了不少例子参考,ADC和DMA的设置了解了个大概,并直接利用开发板来做一些实验来验证相关的操作 ...
- STM32 HAL 库实现乒乓缓存加空闲中断的串口 DMA 收发机制,轻松跑上 2M 波特率
前言 直接储存器访问(Direct Memory Access,DMA),允许一些设备独立地访问数据,而不需要经过 CPU 介入处理.因此在访问大量数据时,使用 DMA 可以节约可观的 CPU 处理时 ...
- STM32 HAL库利用DMA实现串口不定长度接收方法
参考:https://blog.csdn.net/u014470361/article/details/79206352 我这里使用的芯片是 F1 系列的,主要是利用 DMA 数据传输方式实现的,在配 ...
- STM32 HAL库之串口详细篇
一.基础认识 (一) 并行通信 原理:数据的各个位同时传输 优点:速度快 缺点:占用引脚资源多,通常工作时有多条数据线进行数据传输 8bit数据传输典型连接图: 传输的数据是二进制:11101010, ...
- 【有趣的全彩LED | 编程】用STM32 HAL库让WS2812B为你所动
一.效果展示 观看演示效果:https://www.bilibili.com/video/BV1dv411Y7x3 使用STM32 HAL库编程 PWM+DMA控制输出,CubeMX生成初始工程 实现 ...
- STM32 UART DMA实现未知数据长度接收
串口通信是经常使用到的功能,在STM32中UART具有DMA功能,并且收发都可以使用DMA,使用DMA发送基本上大家不会遇到什么问题,因为发送的时候会告知DMA发送的数据长度,DMA按照发送的长度直接 ...
随机推荐
- 关于OJ中的输入格式的问题
输入:1 2 3 4 5 6 7 8 9 10 如上的输入,并未告诉我们终止条件,这种无上限输入的格式可以用以下格式读入 int main() { int S[100]; int i = 0; whi ...
- UUID算法:独一无二的标识符解决方案
引言 在分布式系统和大数据环境下,唯一标识符的生成和管理是一项关键任务.UUID(Universally Unique Identifier)算法应运而生,成为了解决重复数据和标识符冲突的有效工具.本 ...
- SSD 接口简介——M.2/U.2
一,M.2 - the Next Generation Form Factor (NGFF) 从名字上可以看出M.2在最初主要关于新一代尺寸的规格,它定义了以下几种尺寸,类似于内存条的样子. M.2 ...
- java 从零开始手写 redis(七)LRU 缓存淘汰策略详解
前言 java从零手写实现redis(一)如何实现固定大小的缓存? java从零手写实现redis(三)redis expire 过期原理 java从零手写实现redis(三)内存数据如何重启不丢失? ...
- 未配置Datasource时, 启动 SpringBoot 程序报错的问题
SpringBoot will show error if there is no datasource configuration in application.yml/application.pr ...
- spring boot+sqlite+mybatis实现增删改查例子
主要是更换了下sqlite的数据源而已,其他代码不变. 我都贴一下吧,这个算是比较通用的基础增删改查代码. 1.创建test.db 可以使用Idea自带的Database插件配置,也可以命令行创建,具 ...
- 24个javascript最佳实践
1. 使用 === 代替 == JavaScript utilizes two different kinds of equality operators: === | !== and == | != ...
- Google C++ 风格指南记录
最近在看谷歌的 C++ 风格指南发现了一些有意思的知识点,遂记录下 1. 第六章第二小节介绍了右值引用 只在定义移动构造函数与移动赋值操作时使用右值引用. 不要使用 std::forward. 定义: ...
- websocket 监听端口问题
有用户反馈使用我们的软件时会出现 ERR_CONNECTION_CLOSED 问题 我们根据反馈排查问题发现是软件的 websocket 监听端口被另一款软件占用了,暂时的解决方法是将占用的软件关闭 ...
- (微服务)服务治理:熔断器介绍以及hystrix-go的使用
一.什么是熔断器 要理解熔断器,可以先看看电路中使用的保险丝. 保险丝(fuse)也被称为电流保险丝,IEC127 标准将它定义为"熔断体(fuse-link)".保险丝是一种保证 ...