[STM32F429-DISCO-HAL]4.Uart 的使用

今天来学习一下最常用的外设之一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让我们不必关心太多底层的细节,比较适合快速的开发。但是要想熟练的使用,我们还是要学会使用固件库以及一些寄存器的配制方法,不可巧取。

时间: 2024-10-13 11:53:46

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

STM32 HAL库 UART使用printf

// 添加这个函数 int fputc(int ch,FILE *f) { uint8_t temp[1]={ch}; HAL_UART_Transmit(&UartHandle,temp,1,2); } MDK设置:勾选Use Micro LIB 测试板子:STM32F746NG-DISCOVERY main.c文件 /* Includes ------------------------------------------------------------------*/ #include

STM32L0 HAL库 UART 串口读写功能

串口发送功能: uint8_t TxData[10]= "01234abcde"; HAL_UART_Transmit(&huart2,TxData,10,0xffff);//把TxData的内容通过uart2发送出去,长度是10,timeout的时间是最大值0xffff 串口接收功能1: uint8_t value='F'; HAL_UART_Receive(&huart2,(uint8_t *)&value,1,1000);//在这个语句停留1000ms内等

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

一.前言 1.简介 在上一篇UART详解中,已经有了关于UART的详细介绍了,也有关于如何使用STM32CubeMX来配置UART的操作了,而在该篇博客,主要会讲解一下如何实现UART串口的发送功能. 2.UART简介 嵌入式开发中,UART串口通信协议是我们常用的通信协议之一,全称叫做通用异步收发传输器(Universal Asynchronous Receiver/Transmitter). 3.准备工作 在UART详解中已经有了详细的说明,在这里就不说明了. 注: 建议每次编写好一个相关功

STM32F429i-DISCO FreeRTOS keil STM32CubeMX

目标: 在STM32F429 Disco开发板上用FreeRTOS双线程点亮双闪led. 准备: 0. STM32F429i-DISCO 1. keil ARMMDK 5.13 2. STM32CubeMX 4.8 步骤: 1. 建立工程 keil - project - new project 2. 保存在硬盘上, 给工程起名字 3. 保存工程 同时弹出了器件选择界面, 选STM32F429ZITx 4. 上面界面点OK后出来了运行环境配置界面 展开CMSIS:RTOS and enable

HAL UART DMA 数据收发

UART使用DMA进行数据收发,实现功能,串口2发送指令到上位机,上位机返回数据给串口2,串口2收到数据后由串口1进行转发,该功能为实验功能 1.UART与DMA通道进行绑定 1 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) 2 { 3 4 GPIO_InitTypeDef GPIO_InitStruct = {0}; 5 if(uartHandle->Instance==USART1) 6 { 7 /* USER CODE BEGI

基于STM32F429+HAL库编写的定时器主从门控模式级联输出固定个数PWM脉冲的程序

硬件设备   42步进电机,步进电机驱动器,正点原子F429开发板 开发软件    keil5,Cube 综述   一般要精准的控制电机,就要控制单片机的引脚输出指定个数的PWM波,有多种可实现的方法,其中最好用的方法是用定时器级联输出固定个数PWM脉冲,虽然多用了一个定时器,但大大减少了CPU的处理资源.STM32的每个定时器可以通过另外一个定时器的某一个条件被触发而启动.这里所谓某一个条件可以是定时到时.定时器超时.比较成功等许多条件.这种通过一个定时器触发另一个定时器的工作方式称为定时器的

一个基于STM32F429 HAL库的学习工程模板

让我们来看看这个模板里面都有些啥: 首先打开里面的STW_STM32F429.ioc文件,看到这个图形界面 在这个工程中,我们占用了一个FMC接口,用于向外拓展了32MB的SDRAM,占用了一个LTDC接口,用于连接一块RGB显示屏,两个定时器TIM6,TIM7,两个串口USART1,USART3(连接WIFI模块) 他们具体的配置以及时钟的配置就不详细说了,我在下面提供了一个链接,有兴趣可以下载后慢慢学习. 一般的模板工程无非就是完成一个跑马灯, 我提供的模板提供了一起其他功能,细节就不介绍了

转载:Pixhawk源码笔记三:串行接口UART和Console

转自:新浪@WalkAnt 第四部分 串行接口UART和Console 详细参考:http://dev.ardupilot.com/wiki/learning-ardupilot-uarts-and-the-console/ UART很重要,用于调试输出,数传.GPS模块等. 1.5个UART 目前共定义了5个UART,他们的用途分别是: uartA – 串行终端,通常是Micro USB接口,运行MAVLink协议. uartB – GPS1模块. uartC – 主数传接口,也就是Pixha

HAL层三类函数及其作用

HAL的函数主要由三种,初始化函数(Initialization Function Calls).服务访问函数(Service Access Function Calls ).以及回调函数(Callback Function Calls ).还是习惯看英文,觉得自己的中文翻译有的时候不伦不类,误导了亲们. 且看document定义: Initialization Function Calls : These function calls are used to initialize a serv