STM32 UART串口DMA驱动设计

本文介绍了一种STM32串口驱动设计,通过结合DMA解决串口通信资源占用问题。作者强调了驱动的通用性和效率,特别讨论了如何利用DMA的传输计数器在循环模式下实现无中断接收,降低系统资源消耗。
摘要由CSDN通过智能技术生成

前言

stm32串口通信是开发中比较常用的功能,基本大家都会需要它来向别的设备或者PC端传递一些信息。然而大多数人却不能很好地设计一个好的串口驱动。对于新手或者比较懒的人一般直接赋值粘贴的网上的代码,一般这些代码包含三个功能:初始化、发送数据、中断入口函数。然后稍微变更一下端口号波特率之类的配置就可以用了。若只是调试这样用也无可厚非,但若要加入到一个系统中则有些不太严谨,对于一个系统来说追求的是占用最少的资源来实现一些外设功能。直接赋值粘贴的代码存在如下问题:
1、通用性比较弱,如初始化函数需要在不同的地方直接更改设置,规范的写法应该将基本配置放在头文件并使用宏定义集中配置。
2、对于STM32来说比较占用资源,如发送函数一般是阻塞发送,而串口通讯速率又相对较低,势必会消耗占用系统时间
3、频繁进入中断来接收数据,一般串口中断会开启接收缓存区非空中断,即每次接收一个字节都要进入一次中断,这样中断资源势必吃紧
总之如果仅仅测试可以随意,但当开发中如果感觉资源不够可以参考本文串口驱动。使用这个驱动的好处是配置简单、后台发送和接收不占用资源、调用简单。驱动适用于STM32F4系列,使用标准外设库。其他系列也可以做参考,因为本文注重介绍的是思路。

串口通信简介

首先还是先简单介绍下串口通信,一般串口通信包含两个接线口:TX接口和RX接口。通讯不分主从直接连接,如设备1和设备2连接时需要交叉连接,即设备1的TX接设备2的RX,设备1的RX接设备2的TX。然后双方使用同一个串口配置即可成功通讯,一般串口设置包括波特率、数据位数、停止位数、校验位数。如果这些不太懂可以百度之,这里就不详细介绍了,其实都是和硬件时序有关。这里向大家普及下波特率,原来一直不太懂波特率,如波特率9600代表什么,其实波特率单位是bps,翻译一下即为bits per second,即比特/每秒。我们一般接收数据都是以字节接收到单片机的,所以有人可能会误认为9600波特率代表每秒9600个字节数据,其实是错的。如下图是使用逻辑分析仪抓取的一个以9600波特率通讯的字节波形串口波形
这里使用了标准的配置,数据位是8 bit,停止位 1bit,再加上1 bit起始位一共是10 bit。所以若满负载发送时(即两个字节之间没有空隙)其发送速率为9600/10=960 bytes/s。图上A1和A2之间为这个字节的起始位,测试发现A1-A2=104.16us,这个数大小约为1000000us/9600,这也印证了9600指的是比特而不是字节。

STM32 USART通讯

既然是基于STM32的设计所以这里还需要介绍USART通讯。这里着重介绍下几个寄存器和程序。
stm32关于串口的寄存器列表如下:

寄存器 描述
USART_SR 状态寄存器
USART_DR 数据寄存器
USART_BRR 波特率寄存器
USART_CR1 控制寄存器 1
USART_CR2 控制寄存器 2
USART_CR3 控制寄存器 3

对于一般我们复制的初始化程序一般如下

//GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); //使能GPIOC时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);//使能USART4时钟
 
	//串口4对应引脚复用映射
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_UART4); //GPIOA10复用为USART4
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_UART4); //GPIOA11复用为USART4
	
	//USART1端口配置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; //GPIOA10与GPIOA11
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化
   //USART1 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
  	USART_Init(UART4, &USART_InitStructure); //初始化串口4
	USART_ITConfig
  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值