首页 > 其他分享 >[STM32 HAL]一种可能不错的DMA处理串口数据方案

[STM32 HAL]一种可能不错的DMA处理串口数据方案

时间:2023-07-09 20:45:22浏览次数:45  
标签:DMA CODE HAL UART USER 串口 usartType1

[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 */

然后基本就可以了

但这个方案好像有点小问题,具体还没有搞清楚,大体是可以用的,至少可以接收电脑发送的数据并处理且显示,等有空再好好研究一下啦~

标签:DMA,CODE,HAL,UART,USER,串口,usartType1
From: https://www.cnblogs.com/Asaka-QianXiang/p/17539327.html

相关文章

  • [STM32]STM32双机蓝牙串口通信
    [STM32]STM32双机蓝牙串口通信期末考完力,虽然GPA--,但也终于有空搓一搓32了蓝牙模块配置我们先配置蓝牙模块,需要主从兼容,配置过程可以参考这个博客:https://blog.csdn.net/m0_59113542/article/details/122028037?spm=1001.2014.3001.5506cubeMX配置然后就是MX里的配置。PS:两......
  • [Raspberry Pi]树莓派多线程下串口收发数据
    [RaspberryPi]树莓派多线程下串口收发数据鼠鼠用的是python开发树莓派,因为python是最优美的语言!少废话,直接上代码:importthreadingimportserialimportcv2ser=serial.Serial("/dev/ttyAMA0",115200)ser.timeout=5ifnotser.isOpen:ser.open()#打开串口......
  • CF1817E Half-sum
    greedy把数分成两个集合\(A,B\),且\(A<B\)。令每个集合的数的个数分别是\(a,b\)。令\(A_1\dotsA_a,B_1\dotsB_b\)分别有序。定理\(1\)\(A\)集合合并的顺序一定是从大往小的,\(B\)集合是从小往大的。应该很好猜到,但是证明需要一点推导。大概可以局部到\(x,y,z,w\)......
  • 使用STM32的usb虚拟串口CDC_Transmit_FS打印freertos的任务列表vTaskList
    创建一个任务,打印信息后,把自己删除/*USERCODEENDHeader_func_showSysInfo*/voidfunc_showSysInfo(voidconst*argument){/*USERCODEBEGINfunc_showSysInfo*//*Infiniteloop*/for(;;){osDelay(1000);chartaskList[200];......
  • AE插件中文汉化丨创意半调圆点填充效果 Halftone V1.1.2 Win
    Halftone是一个AfterEffects中文汉化插件,可帮助你使用点阵效果填充gradients和形状。 主要特点•使用不同尺寸的点来生成渐变效果。•自定义点的形状、颜色、大小、随机性、旋转等参数。•易于使用的界面,简单设置即可。•支持AECC2015及更高版本。•此版本v1.1......
  • RV1126调试-修改默认调试串口
    背景RK系列的SDK给的默认的调试串口都是uart2/1500000波特率,本次调试设备已经把console调试口改为了uart0,所以需要修改下uboot和内核,然后把波特率设为常用的115200。注:本次调试的SDK版本为原厂的V2.2版本1.uboot修改1)修改rv1126-evb.dts和rv1126-u-boot.dtsi把uart2改成uart......
  • IDEA:MAVEN:Result Maps collection does not contain value for com.itheima.mapper.
    尝试过很多方法:我的代码与视频的一致仍然不可行。可以发现是mapper文件的错误后发现自己的资源文件下的包创建方式不对,尽管打的target包里仍然存在代码,仍是错误的。之后更改resource文件下包的命名方式用“/”来命名即可。   ......
  • DMA数据发送模块实现
    DMA数据发送模块实现发送模块的数据接口发送模块使用AXIStream接口与DMA控制器通信,AXIStream是一种简单的点对点数据流协议,主要包含以下三个信号:valid:表示发送方是否有有效的数据。ready:表示接收方是否准备好接收数据。data:表示数据本身,可以是任意位宽。另外,AXIStrea......
  • QT 记串口的用法
    QSerialPort用法一、在.pro文件添加serialportQT+=coreguiserialport二、头文件#include<QSerialPort>#include<QSerialPortInfo>三、开启串口1voidWidget::on_pushButton_clicked()//自己写的按钮为例2{3QSerialPortInfoinfo;4QLis......
  • 坚固型3DMAG™A31315LOLATR-XZ-S-AR-10、A31315LOLATR-XY-S-SE-10霍尔效应 线性,旋转位
    A313153D磁性位置传感器IC是完全集成的坚固型3DMAG™霍尔效应磁性位置传感器IC,主要用于支持汽车、工业和消费类应用中的各种非接触式旋转和线性位置测量。此传感器IC符合AEC-Q1000级的要求,并根据ISO26262进行开发。这些标准使A31315成为了要求严格的汽车安全系统的理想选择,适......