[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处理串口数据方案的更多相关文章

  1. STM32使用DMA发送串口数据

    1.概述 上一篇文章<STM32使用DMA接收串口数据>讲解了如何使用DMA接收数据,使用DMA外设和串口外设,使用的中断是串口空闲中断.本篇文章主要讲解使用DMA发送数据,不会讲解基础的 ...

  2. STM32—无需中断来实现使用DMA接收串口数据

    本节目标: 通过DMA,无需中断,接收不定时长的串口数据 描述:当在串口多数据传输下,CPU会产生多次中断来接收串口数据,这样会大大地降低CPU效率,同时又需要CPU去做其它更重要的事情,我们应该如何 ...

  3. STM32 HAL库的定时器中断回调函数跟串口中断回调函数

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { //添加回调后的程序逻辑 if (htim->Instance == ...

  4. 利用DMA实现采样数据的直接搬运存储

    尝试了下STM32的ADC采样,并利用DMA实现采样数据的直接搬运存储,这样就不用CPU去参与操作了. 找了不少例子参考,ADC和DMA的设置了解了个大概,并直接利用开发板来做一些实验来验证相关的操作 ...

  5. DMA实现采样数据的直接搬运存储

    尝试了下STM32的ADC采样,并利用DMA实现采样数据的直接搬运存储,这样就不用CPU去参与操作了. 找了不少例子参考,ADC和DMA的设置了解了个大概,并直接利用开发板来做一些实验来验证相关的操作 ...

  6. STM32 HAL 库实现乒乓缓存加空闲中断的串口 DMA 收发机制,轻松跑上 2M 波特率

    前言 直接储存器访问(Direct Memory Access,DMA),允许一些设备独立地访问数据,而不需要经过 CPU 介入处理.因此在访问大量数据时,使用 DMA 可以节约可观的 CPU 处理时 ...

  7. STM32 HAL库利用DMA实现串口不定长度接收方法

    参考:https://blog.csdn.net/u014470361/article/details/79206352 我这里使用的芯片是 F1 系列的,主要是利用 DMA 数据传输方式实现的,在配 ...

  8. STM32 HAL库之串口详细篇

    一.基础认识 (一) 并行通信 原理:数据的各个位同时传输 优点:速度快 缺点:占用引脚资源多,通常工作时有多条数据线进行数据传输 8bit数据传输典型连接图: 传输的数据是二进制:11101010, ...

  9. 【有趣的全彩LED | 编程】用STM32 HAL库让WS2812B为你所动

    一.效果展示 观看演示效果:https://www.bilibili.com/video/BV1dv411Y7x3 使用STM32 HAL库编程 PWM+DMA控制输出,CubeMX生成初始工程 实现 ...

  10. STM32 UART DMA实现未知数据长度接收

    串口通信是经常使用到的功能,在STM32中UART具有DMA功能,并且收发都可以使用DMA,使用DMA发送基本上大家不会遇到什么问题,因为发送的时候会告知DMA发送的数据长度,DMA按照发送的长度直接 ...

随机推荐

  1. 关于OJ中的输入格式的问题

    输入:1 2 3 4 5 6 7 8 9 10 如上的输入,并未告诉我们终止条件,这种无上限输入的格式可以用以下格式读入 int main() { int S[100]; int i = 0; whi ...

  2. UUID算法:独一无二的标识符解决方案

    引言 在分布式系统和大数据环境下,唯一标识符的生成和管理是一项关键任务.UUID(Universally Unique Identifier)算法应运而生,成为了解决重复数据和标识符冲突的有效工具.本 ...

  3. SSD 接口简介——M.2/U.2

    一,M.2 - the Next Generation Form Factor (NGFF) 从名字上可以看出M.2在最初主要关于新一代尺寸的规格,它定义了以下几种尺寸,类似于内存条的样子. M.2 ...

  4. java 从零开始手写 redis(七)LRU 缓存淘汰策略详解

    前言 java从零手写实现redis(一)如何实现固定大小的缓存? java从零手写实现redis(三)redis expire 过期原理 java从零手写实现redis(三)内存数据如何重启不丢失? ...

  5. 未配置Datasource时, 启动 SpringBoot 程序报错的问题

    SpringBoot will show error if there is no datasource configuration in application.yml/application.pr ...

  6. spring boot+sqlite+mybatis实现增删改查例子

    主要是更换了下sqlite的数据源而已,其他代码不变. 我都贴一下吧,这个算是比较通用的基础增删改查代码. 1.创建test.db 可以使用Idea自带的Database插件配置,也可以命令行创建,具 ...

  7. 24个javascript最佳实践

    1. 使用 === 代替 == JavaScript utilizes two different kinds of equality operators: === | !== and == | != ...

  8. Google C++ 风格指南记录

    最近在看谷歌的 C++ 风格指南发现了一些有意思的知识点,遂记录下 1. 第六章第二小节介绍了右值引用 只在定义移动构造函数与移动赋值操作时使用右值引用. 不要使用 std::forward. 定义: ...

  9. websocket 监听端口问题

    有用户反馈使用我们的软件时会出现 ERR_CONNECTION_CLOSED 问题 我们根据反馈排查问题发现是软件的 websocket 监听端口被另一款软件占用了,暂时的解决方法是将占用的软件关闭 ...

  10. (微服务)服务治理:熔断器介绍以及hystrix-go的使用

    一.什么是熔断器 要理解熔断器,可以先看看电路中使用的保险丝. 保险丝(fuse)也被称为电流保险丝,IEC127 标准将它定义为"熔断体(fuse-link)".保险丝是一种保证 ...