STM32F103 UART1 用DMA发送字符串要注意

因为是用STM32CubeMX生成初始化代码,凭直觉只在”DMA Settings”里增加了USART1_TX的一项:

STM32_UART1_DMA_1

结果在程序里调用HAL_UART_Transmit_DMA()时只能调用一次,第二次以后都没有输出,然后google,

原来还要在NVIC Settings里打开USART1 global interrupt:

STM32_USART1_global_interrupt

然后就可以多次发送HAL_UART_Transmit_DMA()了。

启用NVIC USART中断句柄(使用DMA非循环模式时,用来检测最后一个字节发送完毕)

然来在HAL_UART_Transmit_DMA()函数的定义文件stm32f1xx_hal_uart.c就有How to use this driver, 里面有讲:

==============================================================================
##### How to use this driver #####
==============================================================================
[..]
The UART HAL driver can be used as follows:

(#) Declare a UART_HandleTypeDef handle structure.

(#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
(##) Enable the USARTx interface clock.
(##) UART pins configuration:
(+++) Enable the clock for the UART GPIOs.
(+++) Configure the USART pins (TX as alternate function pull-up, RX as alternate function Input).
(##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
and HAL_UART_Receive_IT() APIs):
(+++) Configure the USARTx interrupt priority.
(+++) Enable the NVIC USART IRQ handle.
(##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
and HAL_UART_Receive_DMA() APIs):
(+++) Declare a DMA handle structure for the Tx/Rx channel.
(+++) Enable the DMAx interface clock.
(+++) Configure the declared DMA handle structure with the required
Tx/Rx parameters.
(+++) Configure the DMA Tx/Rx channel.
(+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
(+++) Configure the priority and enable the NVIC for the transfer complete
interrupt on the DMA Tx/Rx channel.
(+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
(used for last byte sending completion detection in DMA non circular mode)

————————分界线———————————

完成以上之后,是可以多次发送,但还是有一个问题, 两次发送之间的时间不能太小,如果上次还没有完成发送,第二次发送的内容就发不出去。

所以解决这个间隔时间问题,还要在发送完的的回调函数里增加状态设置:

同时,在调用HAL_UART_Transmit_DMA()之前,要等待状态成为HAL_UART_STATE_READY,如封装成一个函数:

这样就可以调用2次Console_Log()连续2次,中间不用加延时。

 

参考:http://blog.csdn.net/fengyu09/article/details/47147615