最近在使用F334的USART+DMA进行发送数据的时候,遇到了一个很奇怪的问题。 在调用HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)发送数据时,实际发送的数据长度总比我设置的Size少两个。 比如配置成HAL_UART_Transmit_DMA(&huart3, pucData, 19), 然后在DMA的发送完成中断里观察寄存器,发现串口的发送长度和发送计数器两个值,都是19,应该是对的。DMA配置的是normal模式,通讯的参数是9600bps, 8个数据位, 无校验位 , 1个停止位。 但是,从串口实际发送出来的数据,其实只有17个数。 如果我需要发送19个Byte,我在调用DMA发送的时候,需要将发送数据长度配置为21,即HAL_UART_Transmit_DMA(&huart3, pucData, 21) 这个时候,串口发送出来的就是完整的19个Byte了。 我实际是用在485通讯上,所以有一个GPIO用于控制数据流。 这个GPIO,在DMA发送完成中断程序的最开始我打断点看过IO口的电平,依然是在发送状态,随后,我才将IO后电平反转至接收状态。 除此之外,发现DMA的中断函数里,normal模式下会使能串口的发送完成中断TCIE,我如果在串口的发送完成中断里反转485的流控制IO,就可以完整的发送我需要发送的数据长度,不用再加2个byte的长度。 感觉好奇怪啊,难道是DMA的传输完成中断时,数据只是从DMA移到了串口的发送的寄存器,但是实际还没发出去吗? 如果是这个逻辑,在DMA的传输完成中断里,将流控制的IO反转,确实会打断数据的发送。 各位兄弟姐妹,大佬大神,走过路过帮忙支支招,看大家有没有遇到类似的问题呢。 |
DMA中断时,只表示需要传送的所有数据字节全部传送到串口的发送数据寄存器中了。
此时串口实际上还有2个字节并未发送完成,数据寄存器和移位寄存器中的2个字节还需要发送,并不能关闭串口发送。
同理,如果是485切换方向,必须要等到发送完成,也就是移位寄存器发送完成-TC标志置位。