stm32F4XX之UART&DMA HAL库

发布者:WiseSage123最新更新时间:2019-03-07 来源: eefocus关键字:stm32F4XX  UART  DMA  HAL库 手机看文章 扫描二维码
随时随地手机看文章

1:串口相关的初始化操作

我们都知道stm32相关外设的初始化都需要打开相应的时钟,配置相应的IO,除此之外我们还需要对串口库中的相关成员变量赋值,这里我们就直接看一下这些结构体成员有哪些。


HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);这个函数就是对串口的初始化操作,形参是一个结构体指针,该结构体主要包含哪些部分,下面会做相应的介绍


typedef struct

{

 USART_TypeDef *Instance; 

 UART_InitTypeDef Init; 

 uint8_t *pTxBuffPtr; 

 uint16_t TxXferSize; 

 uint16_t TxXferCount; 

 uint8_t *pRxBuffPtr; 

 uint16_t RxXferSize; 

 uint16_t RxXferCount; 

 DMA_HandleTypeDef *hdmatx; 

 DMA_HandleTypeDef *hdmarx; 

 HAL_LockTypeDef Lock; 

 __IO HAL_UART_StateTypeDef State; 

 __IO uint32_t ErrorCode; 

}UART_HandleTypeDef;


在该成员中我们只需要对 USART_TypeDef *Instance;  UART_InitTypeDef Init; 这两个成员赋值就行了,首先我先来介绍一下 USART_TypeDef *Instance,这个成员表示的是具体串口号,它是执行寄存器基地址,实际上这个基地址 HAL 库已经定义好了,如果是串口 1,取值为 USART1 即可。


 UART_InitTypeDef Init这个变量主要包含如下的成员,它是用来设置串口的各个参数,包括波特率,停止位等


typedef struct

{

 uint32_t BaudRate; //波特率

 uint32_t WordLength; //字长

 uint32_t StopBits; //停止位

 uint32_t Parity; //奇偶校验

 uint32_t Mode; //收/发模式设置

 uint32_t HwFlowCtl; //硬件流设置

 uint32_t OverSampling; //过采样设置

}UART_InitTypeDef


pTxBuffPtr,TxXferSize 和 TxXferCount 三个变量分别用来设置串口发送的数据缓存指针,发送的数据量和还剩余的要发送的数据量。而接下来的三个变量 pRxBuffPtr,RxXferSize 和RxXferCount 则是用来设置接收的数据缓存指针,接收的最大数据量以及还剩余的要接收的数据量。这六个变量是 HAL 库处理中间变量。hdmatx 和 hdmarx 是串口 DMA 相关的变量,指向 DMA 句柄

函数 HAL_UART_Init 使用的一般格式为:

 


UART_HandleTypeDef UART1_Handler; //UART 句柄

UART1_Handler.Instance=USART1; //USART1

UART1_Handler.Init.BaudRate=115200; //波特率

UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为 8 位格式

UART1_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位

UART1_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位

UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控

UART1_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式

HAL_UART_Init(&UART1_Handler); //HAL_UART_Init()会使能 UART1

 

这里我们需要说明的是,函数 HAL_UART_Init 内部会调用串口使能函数使能相应串口,所以调用了该函数之后我们就不需要重复使能串口了。当然,HAL 库也提供了具体的串口使能和关闭方法,具体使用方法如下:

__HAL_UART_ENABLE(handler); //使能句柄 handler 指定的串口

__HAL_UART_DISABLE(handler); //关闭句柄 handler 指定的串口


这里还需要提醒大家,串口作为一个重要外设,在调用的初始化函数 HAL_UART_Init 内部,会先调用 MSP 初始化回调函数进行 MCU 相关的初始化,函数为:void HAL_UART_MspInit(UART_HandleTypeDef *huart);我们在程序中,只需要重写该函数即可。一般情况下,该函数内部用来编写 IO 口初始化,时钟使能以及 NVIC 配置


void HAL_UART_MspInit(UART_HandleTypeDef *huart)

{

    //GPIO端口设置

GPIO_InitTypeDef GPIO_Initure;


if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化

{

__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟

__HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟


GPIO_Initure.Pin=GPIO_PIN_9; //PA9

GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出

GPIO_Initure.Pull=GPIO_PULLUP; //上拉

GPIO_Initure.Speed=GPIO_SPEED_FAST; //高速

GPIO_Initure.Alternate=GPIO_AF7_USART1; //复用为USART1

HAL_GPIO_Init(GPIOA,&GPIO_Initure);     //初始化PA9

 

GPIO_Initure.Pin=GPIO_PIN_10; //PA10

HAL_GPIO_Init(GPIOA,&GPIO_Initure);     //初始化PA10


#if EN_USART1_RX

HAL_NVIC_EnableIRQ(USART1_IRQn); //使能USART1中断通道

HAL_NVIC_SetPriority(USART1_IRQn,3,3); //抢占优先级3,子优先级3

#endif

}

 

}


2:中断相关配置

 开启串口相关中断,配置串口中断优先级HAL 库中定义了一个使能串口中断的标识符__HAL_UART_ENABLE_IT,大家可以把它当一个函数来使用,具体定义请参考 HAL 库文件 stm32f4xx_hal_uart.h 中该标识符定义。例如我们要使能接收完成中断,方法如下:

__HAL_UART_ENABLE_IT(huart,UART_IT_RXNE); //开启接收完成中断第一个参数为串口句柄,类型为UART_HandleTypeDef 结构体类型。第二个参数为我们要开启的中断类型值,可选值在头文件 stm32f4xx_hal_uart.h 中有宏定义。


关闭串口中断,操作方法为:

__HAL_UART_DISABLE_IT(huart,UART_IT_RXNE); //关闭接收完成中断对于中断优先级配置,方法就非常简单


对于中断优先级配置,方法就非常简单

HAL_NVIC_EnableIRQ(USART1_IRQn); //使能 USART1 中断通道

HAL_NVIC_SetPriority(USART1_IRQn,3,3); //抢占优先级 3,子优先级 3


3:编写中断服务函数

我们在初始化串口之后,开启相应中断,在中断产生的时候我们要有相应的中断处理函数来相应此次的中断


//串口1中断服务程序

void USART1_IRQHandler(void)               

u32 timeout=0;

u32 maxDelay=0x1FFFF;


HAL_UART_IRQHandler(&UART1_Handler); //调用HAL库中断处理公用函数


timeout=0;

    while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)//等待就绪

{

timeout++;////超时处理

     if(timeout>maxDelay) break;

}

     

timeout=0;

while(HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1

{

timeout++; //超时处理

if(timeout>maxDelay) break;

}

 

HAL_UART_IRQHandler(&UART1_Handler);    该函数会清楚相应的中断标志位,然后调用HAL_UART_GetState等待uart恢复初始状态,处理完之后重新打开接受中断


4:串口的发送和接收


         STM32F4 的发送与接收是通过数据寄存器 USART_DR 来实现的,这是一个双寄存器,包含了 TDR 和 RDR。当向该寄存器写数据的时候,串口就会自动发送,当收到数据的时候,也是存在该寄存器内。HAL 库操作 USART_DR 寄存器发送数据的函数是:

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

通过该函数向串口寄存器 USART_DR 写入一个数据。

HAL 库操作 USART_DR 寄存器读取串口接收到的数据的函数是:

HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

通过该函数可以读取串口接受到的数据。


关键字:stm32F4XX  UART  DMA  HAL库 引用地址:stm32F4XX之UART&DMA HAL库

上一篇:stm32F4XX之窗口看门狗 HAL库
下一篇:stm32F4XX之AD采样 HAL库

推荐阅读最新更新时间:2024-03-16 16:24

STM32F0单片机快速入门六 用库操作串口(UART)原来如此简单
1.从 GPIO 到 UART 前面几节我们讲了MCU如何启动,如何用翻转IO引脚,以及用按键去触发中断。接下来我们介绍的也是最常用的一个模块,串口(UART)。 串口可以说是最古老,而且生命力最强的一种通信接口了。RS485总线更是久经考验。虽然串口早已经从大多数PC的标配中去掉了,但是嵌入式系统跟上位PC机通信用的最多的应该还是通过串口转USB吧。 我们用 Keil 打开下面这个工程: STM32Cube_FW_F0_V1.11.0ProjectsSTM32F030R8-NucleoExamplesUARTUART_TwoBoards_ComPollingMDK-ARMProject.uvprojx 这个代码配置串口为 96
[单片机]
STM32 UART的使用过程
1、使用UART前必须启动相应的外设时钟,其主要用到固件库的RCC_APBnPeriphClockCmd函数。 使能UART1:使用RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE) 使能UART2:使用RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE) 2、使用中断进行UART操作的需要配置NVIC,设置中断优先级。如: /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGr
[单片机]
基于PCI Core的链式DMA控制器设计
摘要:介绍一种基于PCI总线的高效链式DMA控制器的设计与实现,用于高速宽带的计算机外设接口。利用Altera公司的PCI核——PCI_MT32搭建基于此控制器的数据采集平台,并成功应用在DVB数据接收卡中。 关键词:PCI 链式 DMA控制器 1991年PCISIG(外围部件互连专业组)成立,提出了PCI的概念。Altera公司提供的软件包:PCI Compiler可以参数化地生成 用于PCI接口的IP核——Megacore。该IP核包含了PCI控制电路的所有功能,完成总线协议的转换,并将复杂的、 电气和时序要求高的PCI转换为易于操作的本地接口逻辑。用户可以基于其生成的IP核模块,设计自己的外部设备接口逻辑。用户可以基
[传感技术]
STM8L 在USART中使用DMA来发送与接收数据
以USART为例子来使用DMA 分两部分,第一为,DMA这个外设自身的配置;第二为,USART的DMA部分配置, DMA与USART的DMA配置 void SYS_DMA_Init(void) { CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, ENABLE); /span //打开时钟,很重要 /* Deinitialize DMA channels */ DMA_GlobalDeInit(); DMA_DeInit(DMA1_Channel1); DMA_DeInit(DMA1_Channel2); /* DMA channel Rx of USART Co
[单片机]
MSP430F169(二)——UART波特率
串口通信 1. 什么叫串口 串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口 (Serial Interface)是指数据一位一位地顺序传送。 与并行接口相比,其优点也非常明显: 成本低,最少需要一根线就可以完成传输; 没有数据的相互干扰,误码率相对较低; 缺点:传输速率相对较低。 2. 串口如何建立通信 对单片机有所了解的人都应该知道,串口通信是通过调配单片机内部的寄存器来控制速率。而MSP430F169内部最重要的几个配置无非是波特率的设置和多机通信。 2.1什么是波特率 在讲波特率之前我们要区分两个概念:波特率和比特率。 比特率: 比特率是指每秒传送
[单片机]
MSP430F169(二)——<font color='red'>UART</font>波特率
STM8 UART 发送器
STM8 UART 发送器 发送器根据M位的状态发送8位或9位的数据字。当M位置1,字长为9位,并且第九位(MSB)应该写入寄存器UART_CR1的T8位。 当发送使能位(TE)被设置时,发送移位寄存器中的数据在TX脚上输出,相应的时钟脉冲在SCLK脚上输出。 字符发送 在UART发送期间,在TX引脚上首先移出数据的最低有效位。在此模式里,UART_DR寄存器有一个缓冲器(TDR),位于内部总线和发送移位寄存器之间。 每个字符之前都有一个低电平的起始位;之后跟着数目可配置的停止位。UART支持以下停止位。 注意: 1.在数据传输期间不能复位TE位,否则将破坏TX脚上的数据,因为波特率计数器停止计数。正在传输的当前数据将丢
[单片机]
STM8 <font color='red'>UART</font> 发送器
stm32F103——ADC与DMA(按键与光敏电阻)
ADC的基本介绍 ADC的基本定义 Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。 典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。 我们先来看ADC的工作原理: 通道选择:1个ADC模块具有多个通道,不同的通道在不同的引脚上。所以,我们要采集哪个引脚上面的模拟量,需要我们去选择对应ADC通道。 采保电容:采样保持电容。当开关闭合的时候,给采保电容进行充电,然后在规定的时间内断开开关,然后将采保电容上面的模拟量电压进行转换为数字量。这个就是ADC的采集原理。 采样时间:当开关闭合的时候,给采
[单片机]
stm32F103——ADC与<font color='red'>DMA</font>(按键与光敏电阻)
【菜鸟入门】stm32 之 DMA
DMA是个好东西,他可以帮助CPU分担好多工作,减轻CPU的工作压力,我们可以一边传输数据,一边干别的事情,很不错! 今天可谓是配置的好艰辛啊,看电视把我看蒙了,好多注意事项都木有看见,浪费了我好多时间。 好吧,开始进入主题! 时钟配置我就不用罗嗦了!大家自己去RCC里面的AHBENR找: RCC- AHBENR |= 1 0;//DAM1 Clock Enable 主要来看看DMAx的控制寄存器CCR 这个寄存器看着很容易理解,今天对控制寄存器有了新的认识,一般的寄存器可能要在控制寄存器的某一位关闭或者打开才能修改,而控制寄存器基本上可以在任意时刻进行修改,所以,在配置控制寄存器的时候我们没必要考
[单片机]
【菜鸟入门】stm32 之 <font color='red'>DMA</font>
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved