首页 > 其他分享 >STM32 HAL 使用串口IDLE中断+DMA实现收发

STM32 HAL 使用串口IDLE中断+DMA实现收发

时间:2023-11-13 23:55:05浏览次数:43  
标签:DMA HAL UART void myUART myUART1 串口 Data

STM32 HAL 使用串口IDLE中断+DMA实现收发

cubeMX配置

mx配置如下(省去系统时钟,烧录口,工程属性配置)

注意:这里关闭 Force DMA channels Interrupts

image

然后按下面配置即可(TX和RX的DMA都是normal模式)

image

image

代码部分

uart_com.h:

#ifndef __UART_COM_H__
#define __UART_COM_H__

#include "main.h"
#include "string.h"
#include "stdarg.h"
#include "stdio.h"

#define DATA_SIZE 255

typedef struct UART_Data_T 
{
	UART_HandleTypeDef * phuart;
	uint8_t pRxData[DATA_SIZE];
	uint8_t rxData[DATA_SIZE];
	uint16_t rxDataSize;
	uint8_t txBuffer[DATA_SIZE];
}UART_Data_T;

extern UART_Data_T myUART1;

void myUART_Init(UART_HandleTypeDef * huart, UART_Data_T * myUART);
void myUART_send_DMA(UART_Data_T * myUART, uint8_t * buffer, uint16_t size);
void myUART_debug_printf(UART_Data_T * myUART, const char * format, ...);
static inline void myUART_copyData(UART_Data_T * myUART, uint16_t size);
static inline void myUART_resumeReceive(UART_Data_T * myUART);

#endif

uart_com.h:

#include "uart_com.h"

UART_Data_T myUART1;

void myUART_Init(UART_HandleTypeDef * huart, UART_Data_T * myUART)
{
	myUART->phuart = huart;
	HAL_UARTEx_ReceiveToIdle_DMA(huart, myUART->pRxData, sizeof(myUART->pRxData));
}

static inline void myUART_copyData(UART_Data_T * myUART, uint16_t size)
{
	strcpy((char*)myUART->rxData, (char*)myUART->pRxData);
	myUART->rxDataSize = size;
}

static inline void myUART_resumeReceive(UART_Data_T * myUART)
{
	memset(myUART->pRxData, 0x00, sizeof(myUART->pRxData));
	HAL_UARTEx_ReceiveToIdle_DMA(myUART->phuart, myUART->pRxData, sizeof(myUART->pRxData));
}

void myUART_send_DMA(UART_Data_T * myUART, uint8_t * buffer, uint16_t size) 
{
	while(HAL_DMA_GetState(myUART->phuart->hdmatx) != HAL_DMA_STATE_READY);
	__HAL_DMA_DISABLE(myUART->phuart->hdmatx);
	HAL_UART_Transmit_DMA(myUART->phuart, buffer, size);
}

void myUART_debug_printf(UART_Data_T * myUART, const char * format, ...)
{
	uint16_t length = 0;
	va_list args;
	va_start(args, format);
	length = vsnprintf((char*)myUART->txBuffer, sizeof(myUART->txBuffer), (char*)format, args);
	myUART_send_DMA(myUART, myUART->txBuffer, length);
}

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart->Instance==myUART1.phuart->Instance)
	{
		/*Deal with the data*/
	  myUART_copyData(&myUART1, Size);
		//myUART_send_DMA(&myUART1, myUART1.rxData, myUART1.rxDataSize);	// This sentence is used for testing.
		//myUART_debug_printf(&myUART1, "%s", myUART1.rxData);	// This sentence is used for testing.
		
		/*Clear data and restart DMA receive*/
		myUART_resumeReceive(&myUART1);
	}
}

使用

以uart1为例,进行初始化:

myUART_Init(&huart1, &myUART1);
myUART_debug_printf(&myUART1, "Init OK!\n");

然后就可以在代码里调用发送函数了。

标签:DMA,HAL,UART,void,myUART,myUART1,串口,Data
From: https://www.cnblogs.com/Asaka-QianXiang/p/17830635.html

相关文章

  • 串口案例
    111204  #ifndefMAINWINDOW_H#defineMAINWINDOW_H#include<QMainWindow>#include<QSerialPort>namespaceUi{classMainWindow;}classMainWindow:publicQMainWindow{Q_OBJECTpublic:explicitMainWindow(QWidget*parent=......
  • Modbus串口 未完成
    111205   #ifndefMAINWINDOW_H#defineMAINWINDOW_H#include<QMainWindow>#include<QModbusRtuSerialMaster>#include<QSerialPort>namespaceUi{classMainWindow;}classMainWindow:publicQMainWindow{Q_OBJECTpublic:......
  • UART串口介绍和演示
    UART(通用异步收发器)是一种广泛用于串口通信的协议,它在嵌入式系统中起着重要的作用。本文将介绍UART串口的基本原理,并通过代码演示如何在嵌入式系统中使用UART进行通信。UART串口概述UART串口是一种异步通信协议,它使用两个引脚进行数据传输:一个用于发送(TX-Transmit)和一个用于接收(R......
  • 格式转换:相机帧void* pBuffer,QImage,cv::Mat,Halconcpp::HObject
    【说明】1、若传递的是指针,则内存共享,其一改变,另一个也被改变。为了避免输入被更改,做了些处理。如QImage2Mat中使用了两个变量mat,out。2、有的存在宽度方向4字节对齐情况,所以做了些处理。如QImage2HObject中让宽度变为4的整数倍。 【相机帧void*pBuffer赋给其他格式】 ......
  • Arduino UNO使用DHT11温湿度传感器通过串口向PC发送温湿度信息​
    ArduinoUNO使用DHT11温湿度传感器通过串口向PC发送温湿度信息硬件介绍笔者使用的开发板为ArduinoUNO国产兼容板,淘宝上大约卖20rmb左右。如下图DHT11传感器为四脚封装样式,从正面看引脚从左往右依次为1、2、3、4引脚,其中1引脚为VCC3~5V,2引脚为通信引脚要与单片机引脚相连,3引脚是个......
  • podman 容器管理 docker替代,进阶版本?
    简介Docker的一个缺点是它有一个中央守护进程,它以root用户的身份运行,这对安全有影响。但这正是Podman的用武之地。padman完全兼容docker命令和镜像。Podman是一个无守护进程容器引擎,用于开发、管理和在你的Linux系统上以root或无root模式运行OCI容器。安装安......
  • Electron学习3 使用serialport操作串口
    Electron学习3使用serialport操作串口一、准备工作二、SerialPort介绍1.核心软件包(1)serialport(2)@serialport/stream(3)@serialport/bindings-cpp(4)@serialport/binding-mock(5)@serialport/bindings-interface2.解析器包3.命令行工具三、创建一个demo程序1.创建......
  • 最详细STM32,cubeMX串口发送,接收数据
    这篇文章将详细介绍串口发送数据,接受数据。@TOC前言实验开发板:STM32F103C8T6。所需软件:keil5,cubeMX。实验目的:了解串口的基础知识,掌握串口如何发送,接收数据。实验:串口发送数据点亮led。一、串口的基础知识如果想了解串口的基础知识可以参考我之前的文章:STM32Cube串口USART......
  • 1Panel 升级 Halo报错
    1Panel升级Halo报错通过1panel升级2.10.0->2.10.1后启动失败,出现Novaluefoundforprotocol错误,1Panel-halo-rzxY|Causedby:io.r2dbc.spi.NoSuchOptionException:Novaluefoundforprotocol1Panel-halo-rzxY| atio.r2dbc.spi.ConnectionFactoryOptio......
  • USB转串口CH343驱动
    背景在网上用9.9淘的一块ESP32-C3(RISC-V)的小开发板上,用的CH343的USB转串口。最近打算学习用Rust开发ESP32-C3,在Ubuntu上搭建开发环境的时候发现,Ubuntu20.04上默认使用的是CDC-ACM驱动,即生成的节点为/dev/ttyACM0,但是用Rust开发ESP32-C3,需要使用VCP驱动,于是在网上找到了官方(......