今天来学习一下最常用的外设之一USART。

首先是硬件的连接,我们需要至少三根线,GND,TX,RX。参阅datasheet。默认的USART1_TX和USART1_RX的引脚如下图

关于HAL drivers的文档 尽量多查阅【UM1725】 User Manual Description of STM32F4xx HAL drivers和 STM32Cube_FW_F4_V1.5.0\Drivers\STM32F4xx_HAL_Driver\STM32F439xx_User_Manual.chm。

首先我们用最简单的查询方式来使用UART

1.定义好UART_HandleTypeDef结构体。因为Polling模式,只需指定UART的实例和配置参数即可。即UART_HandleTypeDef结构体前两个变量定义好。

2.配置IO口,在stm32f4xx_hal_msp.c中定义好HAL_UART_MspInit()回调函数后,在初始化外设时,系统会自动调用它,因此我们利用这个函数来配置我们的GPIO。

///////////////////Uart.c///////////////////////
UART_HandleTypeDef UartHandle;
void init_Uart(void)
{
UartHandle.Instance = USART1;
UartHandle.Init.BaudRate = 115200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
LCD_TEXT_STRINGLINE("error with USART Init");
} } ///////////////stm32f4xx_hal_msp.c///////////////////////
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_InitStruct; /******Enable peripherals and GPIO Clocks ***/
/* Enable GPIO TX/RX clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Enable USART1 clock */
__HAL_RCC_USART1_CLK_ENABLE(); /**** Configure peripheral GPIO *****/
/* UART TX GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* UART RX GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOA , &GPIO_InitStruct);
}

然后调用HAL_UART_Init(&UartHandle) 成功返回HAL_OK,我们的UART1就可以用了

对于查询方式,UART的发送接受数据我们仅使用两个函数 HAL_UART_Transmit()、 HAL_UART_Receive() 来实现就可以了

一个例子:HAL_UART_Transmit(&UartHandle, txbuf, size, 5000);这里的参数:UartHandle就是我们刚刚定义的uart实例,txbuf为字符串,size为字符串长度。5000为等待超时时间。

OK使用就这么简单。对于大部分的应用来说,都可以满足了。

使用DMA来完成传输

如果使用DMA来传输的话,我们需要做一下修改了,首先是要配置一下DMA模块,我们使用同一个DMA通道的两个流来分别做为TX、RX的传输路径。

HAL_UART_MspInit()函数中添加如下代码

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
static DMA_HandleTypeDef hdma_tx;
static DMA_HandleTypeDef hdma_rx;
GPIO_InitTypeDef GPIO_InitStruct; /******Enable peripherals and GPIO Clocks ***/
/* Enable GPIO TX/RX clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Enable USART1 clock */
__HAL_RCC_USART1_CLK_ENABLE();
/* Enable DMA2 Clock*/
__HAL_RCC_DMA2_CLK_ENABLE();
/**** Configure peripheral GPIO *****/
/* UART TX GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* UART RX GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOA , &GPIO_InitStruct); ////////////////////////configure the DMA///////////////
hdma_tx.Instance = DMA2_Stream7; hdma_tx.Init.Channel = DMA_CHANNEL_4;
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_NORMAL;
hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_tx.Init.MemBurst = DMA_MBURST_INC4;
hdma_tx.Init.PeriphBurst = DMA_PBURST_INC4; HAL_DMA_Init(&hdma_tx); /* Associate the initialized DMA handle to the the UART handle */
__HAL_LINKDMA(huart, hdmatx, hdma_tx); /* Configure the DMA handler for Transmission process */
hdma_rx.Instance = DMA2_Stream5; hdma_rx.Init.Channel = DMA_CHANNEL_4;
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode = DMA_NORMAL;
hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_rx.Init.MemBurst = DMA_MBURST_INC4;
hdma_rx.Init.PeriphBurst = DMA_PBURST_INC4; HAL_DMA_Init(&hdma_rx); /* Associate the initialized DMA handle to the the UART handle */
__HAL_LINKDMA(huart, hdmarx, hdma_rx); /*Configure the NVIC for DMA*/
/* NVIC configuration for DMA transfer complete interrupt (USARTx_TX) */
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn); /* NVIC configuration for DMA transfer complete interrupt (USARTx_RX) */
HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn); /* NVIC configuration for USART TC interrupt */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn); }

这段代码添加了 hdma_tx,hdama_rx的数据结构来初始化分别初始化发送、接收的dma初始化,启动了dma2的时钟,连接uart1与dma,并且启动了两个DMA流和USART1的中断。

中断服务函数的文件stm32f4xx_it.c中添加相关的ISR

void DMA2_Stream5_IRQHandler(void)
{
HAL_DMA_IRQHandler(UartHandle.hdmarx);
} void DMA2_Stream7_IRQHandler(void)
{
HAL_DMA_IRQHandler(UartHandle.hdmatx);
} void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&UartHandle);
}

这样我们就可以直接使用

HAL_UART_Transmit_DMA、HAL_UART_Recieve_DMA函数来完成uart数据传输了。

初步的尝试结果得出,HAL让我们不必关心太多底层的细节,比较适合快速的开发。但是要想熟练的使用,我们还是要学会使用固件库以及一些寄存器的配制方法,不可巧取。

[STM32F429-DISCO-HAL]4.Uart 的使用的更多相关文章

  1. STM32 HAL库 UART 串口读写功能笔记

    https://www.cnblogs.com/Mysterious/p/4804188.html STM32L0 HAL库 UART 串口读写功能 串口发送功能: uint8_t TxData[10 ...

  2. STM32 HAL库 UART使用printf

    // 添加这个函数 int fputc(int ch,FILE *f) { uint8_t temp[]={ch}; HAL_UART_Transmit(&UartHandle,temp,,) ...

  3. 基于STM32F429和HAL库的CAN收发例程

    1.CAN协议介绍 CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信协议.在当前的汽车产业中,出于对安全性.舒适性.方便性.低公 ...

  4. STM32L0 HAL库 UART 串口读写功能

    串口发送功能: uint8_t TxData[]= "01234abcde"; HAL_UART_Transmit(&huart2,TxData,,0xffff);//把T ...

  5. stm32 cubemx hal dma uart参考例程,发送和接收

    参考:https://blog.csdn.net/toopoo/article/details/80012317https://blog.csdn.net/morixinguan/article/de ...

  6. 基于STM32之UART串口通信协议(二)发送

    一.前言 1.简介 在上一篇UART详解中,已经有了关于UART的详细介绍了,也有关于如何使用STM32CubeMX来配置UART的操作了,而在该篇博客,主要会讲解一下如何实现UART串口的发送功能. ...

  7. 基于STM32之UART串口通信协议(三)接收

    一.前言 1.简介 回顾上一篇UART发送当中,已经讲解了如何实现UART的发送操作了,接下来这一篇将会继续讲解如何实现UART的接收操作. 2.UART简介 嵌入式开发中,UART串口通信协议是我们 ...

  8. STM32F429的新版用户手册更新记录, 改进、交流(2019-08-18发布V0.9版本)

    2019-06-16 发布首版V0.1 2019-06-23 发布V0.2版本 新增章节: 第3章 STM32F429 整体把控 第4章 STM32F429 工程模板建立(MDK5) 第5章 STM3 ...

  9. stm32 hal库串口通信资料汇集

    串口的发送接收函数:HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制.HAL_UART_Receive();串口轮询模式发送,使用超时管理机制.HAL_UART_Transm ...

  10. STM32F429i-DISCO FreeRTOS keil STM32CubeMX

    目标: 在STM32F429 Disco开发板上用FreeRTOS双线程点亮双闪led. 准备: 0. STM32F429i-DISCO 1. keil ARMMDK 5.13 2. STM32Cub ...

随机推荐

  1. Linux编程之epoll

    现在有这么一个场景:我是一个很忙的大老板,我有100个手机,手机来信息了,我的秘书就会告诉我"老板,你的手机来信息了."我很生气,我的秘书就是这样子,每次手机来信息就只告诉我来信息 ...

  2. js或者jq的tab切换

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  3. PHP接入阿里云市场 阿里短信服务DEMO

    阿里短信服务:支持三大运营商短信.智能管道等优质能力,产品特点:3秒可达.99%到达率.超低资费. 使用阿里短信服务步骤: 1.购买服务 到https://market.aliyun.com/prod ...

  4. MyBatis源码解析【1】准备工作

    终于迎来了这一天,我觉得现在的我在经历了长时间的学习和开发之后有了一定的经验,所以准备开始学习源码. 今天我将做好充足的准备,在接下来的一个月中,努力的爬过这座大山.(可能不用一个月,但是我觉得需要仔 ...

  5. [asp.net mvc 奇淫巧技] 05 - 扩展ScriptBundle,支持混淆加密javascript

    一.需求: 在web开发中,经常会处理javascript的一些问题,其中就包括js的压缩,合并,发布版本以及混淆加密等等问题.在asp.net 开发中我们使用ScriptBundle已经可以解决ja ...

  6. hihocoder 1050 树中的最长路(动态规划,dfs搜索)

    hihocoder 1050 树中的最长路(动态规划,dfs搜索) Description 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中,小Ho发现他不仅 ...

  7. Java虚拟机:GC算法深度解析

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 在前面的文章里介绍了可达性分析算法,它为我们解决了判定哪些对象可以回收的问题,接下来就该我们的垃圾收集算法出场了.不同的垃圾收集算法有各自 ...

  8. MySQL主从复制的实现过程

    一.什么是主从复制 将主数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到从数据库上,然后将这些日志重新执行(重做):从而使得从数据库的数据与主数据库保持一致. 二.主从复制的作用 1. ...

  9. mysql浅龟定

    一,尽量不字啊数据库做运算 1,尽量不再数据库做运算, 2,将复杂运算移动到cpu 3,尽可能简单应用mysql 二,控制表数据量 1,纯 int不超过1000w 2,含char不超过500w 3,建 ...

  10. LuaFramework内存资源管理器ResourceManger详解及切换场景资源清理

    1.成员变量 m_BaseDownloadingURL : 获取资源的地方,加载AssetBundle包的时候会用到 m_AssetBundleManifest : 包间依赖关系文件,从这个类中的信息 ...