STM32CubeMX系列(2)--串口传输方式

1、阻塞式传输

HAL_UART_Transmit();//发送
HAL_UART_Receive();//接收

2、中断传输

HAL_UART_Transmit_IT();//中断发送
HAL_UART_Receive_IT();//中断接收
/*
每发送
*/

3、DMA传输

HAL_UART_Transmit_DMA();
HAL_UART_Receive_DMA();
/*
结合空闲中断,实现不定长数据传输
*/

以DMA传输为例使用STM32CubeMX创建工程
具体过程见:
STM32CubeMX系列(1)–串口工程创建
在上一节的基础上增添一些DMA相关配置即可:
在这里插入图片描述
在这里插入图片描述
生成工程即可。
代码修改:

//在uart.c中添加变量
#include "stdio.h"
#include "gpio.h"
#include "string.h"
#include "stdbool.h"
unsigned char RxDMABuf[BUFSIZE] = {0};
unsigned char TxDMABuf[BUFSIZE] = {0};
uint8_t FIFOUART1[MAXNUM] = {0};
int DMA_RevNum = 0;//DMA实际接收的数据长度
int TX_FLAG = 0; //接收完成,可以发送的标志
struct Queue queue;
/*******************************uart.h************************************/
#define BUFSIZE 100
#define MAXNUM 200
extern unsigned char RxDMABuf[BUFSIZE];
extern unsigned char TxDMABuf[BUFSIZE];
extern uint8_t FIFOUART1[MAXNUM];
extern int DMA_RevNum;//DMA实际接收的数据长度
extern int TX_FLAG;
extern struct Queue queue;
/*消息队列结构体*/
struct Queue{
	uint8_t front;
	uint8_t rear;
	uint8_t* buf;
	uint8_t size;
};

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
//在上面函数中手动开启串口空闲中断和DMA接收


//在下面串口全局中断函数中添加中断服务函数
/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)

在这里插入图片描述
具体实现

void UART_IDLE_Callback(UART_HandleTypeDef *huart)
{
	if(__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET)/*产生空闲中断*/
	{
	     /*指示灯翻转*/
		LED0_Toggle;
		LED1_Toggle;
		__HAL_UART_CLEAR_IDLEFLAG(huart);//清除空闲中断标志位

        HAL_UART_DMAStop(huart); //停止DMA传输
		
		if(huart->Instance == USART1)
		{
			/*实际接收数据个数*/
			DMA_RevNum = BUFSIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx);
			if(DMA_RevNum >= 1)
			{
				QueueWrite(&queue,RxDMABuf,DMA_RevNum);//将收到的数据写进FIFO
			}
			TX_FLAG = 1;/*发送标志位置1*/
			memset(RxDMABuf, 0 , sizeof(RxDMABuf));//清空接收数组
		}
		HAL_UART_Receive_DMA(huart,RxDMABuf,BUFSIZE);//重启DMA接收
	}
}

//main.c
int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_USART1_UART_Init();
	QueneInit(&queue,FIFOUART1);//初始化FIFO
    while (1)
    {
		if(TX_FLAG == 1)
		{
			/*将数据从FIFO中读取出来并发送到串口*/
			QueueRead(&queue,TxDMABuf,DMA_RevNum);
			HAL_UART_Transmit_DMA(&huart1, TxDMABuf, DMA_RevNum);
			TX_FLAG = 0;
		}
    }
}

//FIFO实现
/*
@队列初始化
@
*/
void QueneInit(struct Queue* obj, uint8_t* buf)
{
	obj->buf = buf;
	obj->front = obj->rear = obj->size = 0;
}
/*
@判断队列是否满
*/
bool QueueIsFull(struct Queue* obj)
{
	if((obj->rear + 1) % MAXNUM == obj->front)
		return true;
	return false;
}
/*
@判断队列是否空
*/
bool QueueIsEmpty(struct Queue* obj)
{
	if(obj->rear == obj->front)
		return true;
	return false;
}
/*
@队列写
*/
void QueueWrite(struct Queue* obj, uint8_t* data, uint8_t len)
{
	if(QueueIsFull(obj))
		return;
	if(obj->rear == MAXNUM)
		obj->rear = 0;/*从头开始*/
	for(uint8_t i = 0; i < len; i ++)
	{
		if(QueueIsFull(obj))
			return;
		if(obj->rear == MAXNUM)
			obj->rear = 0;/*从头开始*/
		obj->buf[obj->rear++] = *data;
		data ++;
		obj->size ++;
	}
}
/*
@队列读
*/
void QueueRead(struct Queue* obj, uint8_t* data, uint8_t num)
{
	if(QueueIsEmpty(obj))
		return;
	if(obj->front == MAXNUM)
		obj->front = 0;
	for(uint8_t i = 0; i < num; i ++)
	{
		if(QueueIsEmpty(obj))
			return;
		if(obj->front == MAXNUM)
			obj->front = 0;
		data[i] = obj->buf[obj->front++];
		obj->size --;
	}
}

推荐文章:一个严谨的STM32串口DMA发送&接收(1.5Mbps波特率)机制
若侵权,告知立删!

版权声明:本文为CSDN博主「sjxpf922」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sjxpf922/article/details/122439830

生成海报
点赞 0

sjxpf922

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

Lin总线通信在STM32作为主机代码以及从机程序

距离上次做资料准备已经过去六天了。最近在学车,上周末就没有开电脑。这周开始进行了Lin通信的代码整理,目前是可以正常通信的了,采用的是增强型校验方式。后期再进一步跟进研究。。。更新一博,留

STM32串口接收数据处理方法

STM32串口接收数据处理方法 STM32串口接收定长数据处理方法 STM32串口接收定长数据的处理方法非常简单,我目前做项目都是用的这个,也可用做处理MODBUS协议,直接上代码。 void U

趣聊51之串口通信(概念篇)

对于刚刚接触单片机的同学们来说,串口通信似乎是一个神秘感十足的东西,笔者在刚刚开始学习51单片机时,读的是郭天祥先生的那本著名的《新概念51单片机教程》,贼厚的一本书,但是等