Learn about one of the most commonly used peripherals today usart.
The first is the hardware connection, we need at least three wires, gnd,tx,rx. See datasheet. The default Usart1_tx and Usart1_rx pins are
Refer to Hal Drivers documentation as much as possible "UM1725" User Manual Description of stm32f4xx HAL Drivers and Stm32cube_fw_f4_v1.5.0\drivers\ Stm32f4xx_hal_driver\stm32f439xx_user_manual.chm.
First we use the UART in the simplest query mode.
1. Define the UART_HANDLETYPEDEF structure. Because of the polling mode, you only need to specify the UART instance and configuration parameters. That is, the first two variables of the UART_HANDLETYPEDEF structure are well defined.
2. Configure the IO port, after defining the Hal_uart_mspinit () callback function in Stm32f4xx_hal_msp.c, the system will call it automatically when initializing the peripheral, so we use this function to configure our Gpio.
///////////////////uart.c///////////////////////uart_handletypedef Uarthandle;voidInit_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///////////////////////voidHal_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);}
Then call Hal_uart_init (&uarthandle) to successfully return to HAL_OK, and our UART1 can use the
For the query mode, the UART send accept data we only use two functions Hal_uart_transmit (), hal_uart_receive () to achieve it can be
An example: Hal_uart_transmit (&uarthandle, txbuf, size, 5000); Here's the argument: Uarthandle is the UART instance we just defined, Txbuf is a string, and size is a string length. 5000 is the wait time-out period.
OK, it's so easy to use. For most applications, it can be fulfilled.
Using DMA to complete the transfer
If we use DMA to transfer, we need to make a change, first of all to configure the DMA module, we use the same DMA channel two streams to be used as TX, RX transmission path.
Add the following code to the Hal_uart_mspinit () function
voidHal_uart_mspinit (UART_HANDLETYPEDEF *Huart) { StaticDma_handletypedef Hdma_tx; StaticDma_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); }
This code adds the HDMA_TX,HDAMA_RX data structure to initialize the DMA initialization that was sent, received separately, initiates the DMA2 clock, connects Uart1 with DMA, and initiates interrupts for two DMA streams and USART1.
Add related ISR in file stm32f4xx_it.c of interrupt service function
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);}
So we can use it directly.
HAL_UART_TRANSMIT_DMA, HAL_UART_RECIEVE_DMA function to complete the UART data transmission.
The preliminary experiment results show that HAL lets us not care too much about the underlying details, which is more suitable for rapid development. But in order to use skillfully, we still have to learn to use the firmware library and some registers of the method of preparation, not to be skillfully taken.
[Stm32f429-disco-hal] Use of 4.Uart