HAL库——UART的DMA发送(对比接收)

更新时间:2023-05-23 10:14:57 阅读: 评论:0

HAL库——UART的DMA发送(对⽐接收)
前⾯讲到的UART接收执⾏过程:
启动UART的DMA接收(这⾥⾯还定义了DMA回调函数):HAL_UART_Receive_DMA
接收完成后,请求DMA中断(判断中断的类型):HAL_DMA_IRQHandler
调⽤DMA接收完成回调函数(同时关闭了DMA接收):UART_DMAReceiveCplt
调⽤UART接收回调函数(处理数据,启动DMA接收):HAL_UART_RxCpltCallback
UART的DMA发送和接收的过程类似,部分细节不同,DMA的发送执⾏过程如下:
启动UART的DMA发送(其中定义了发送的回调函数):HAL_UART_Transmit_DMA
发送完成,请求DMA中断(判断中断的类型):HAL_DMA_IRQHandler
调⽤DMA发送完成回调函数:UART_DMATransmitCplt
到这⼀步还是⼀样的,执⾏到 UART_DMATransmitCplt⾥⾯时,开始不⼀样了。看⼀下UART_DMATransmitCplt说了啥:
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
/* DMA Normal mode*/                                //看这⾥1
if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
{
huart->TxXferCount = 0x00U;
/* Disable the DMA transfer for transmit request by tting the DMAT bit
in the UART CR3 register */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
cof是什么/* Enable the UART Transmit Complete Interrupt */
SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
}
/* DMA Circular mode */                            //看这⾥2
el
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Tx complete callback*/
huart->TxCpltCallback(huart);
#el
/*Call legacy weak Tx complete callback*/
HAL_UART_TxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
程序不长,看着好像和UART_DMAReceiveCplt没啥区别,不过还是不⼀样的,说明如下:
DMA发送的回调函数处理需要区分DMA传输的模式(即区分normal和circular)
看这⾥1:如果DMA配置为normal模式,那么就会置位UART_CR1_TCIE,查⽤户⼿册可以知道,这是使能了UART的传送完成中断,⽣成UART中断,便进⼊了UART的中断请求,后⾯再说具体内容
看这⾥2:如果DMA配置为circular模式,那么就和接收模式下的处理过程类似了,如果没有动态配置回调函数,就会直接调⽤HAL_UART_TxCpltCallback
那么DMA配置成normal模式,进了UART的中断请求,后⾯发⽣了什么那,说明如下:
⾸先进UART的中断请求:HAL_UART_IRQHandler
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
uint32_t isrflags  = READ_REG(huart->Instance->SR);
uint32_t cr1its    = READ_REG(huart->Instance->CR1);
uint32_t cr3its    = READ_REG(huart->Instance->CR3);
uint32_t errorflags = 0x00U;
英语短话剧uint32_t dmarequest = 0x00U;
/* If no error occurs */
errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
if (errorflags == RESET)
{
/* UART in mode Receiver -------------------------------------------------*/
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
{
UART_Receive_IT(huart);
return;
}
}
/* If some errors occur */
if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))  {
/* UART parity error interrupt occurred ----------------------------------*/
if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
{雅思初级
huart->ErrorCode |= HAL_UART_ERROR_PE;
}
/* UART noi error interrupt occurred -----------------------------------*/
if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_NE;
}秋天如何保养皮肤
/* UART frame error interrupt occurred -----------------------------------*/
if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_FE;
}
/* UART Over-Run interrupt occurred --------------------------------------*/
if (((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
/* Call UART Error Call back function if need be --------------------------*/
if (huart->ErrorCode != HAL_UART_ERROR_NONE)
{
/* UART in mode Receiver -----------------------------------------------*/
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
{
UART_Receive_IT(huart);
}
/* If Overrun error occurs, or if any error occurs in DMA mode reception,
consider error as blocking */
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)
{
/* Blocking error : transfer is aborted
Set the UART state ready to be able to start again the process,
Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
UART_EndRxTransfer(huart);
/* Disable the UART DMA Rx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* Abort the UART DMA Rx stream */
if (huart->hdmarx != NULL)
{
/* Set the UART DMA Abort callback :
will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
{
/* Call Directly XferAbortCallback function in ca of error */
huart->hdmarx->XferAbortCallback(huart->hdmarx);
}
}
el
{
/* Call ur error callback */roc
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#el
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
el
hex{
/* Call ur error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/
*Call registered error callback*/
huart->ErrorCallback(huart);
#el
/*Call legacy weak error callback*/
不错的英文HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
el
{
/* Non Blocking error : transfer could go on.
Error is notified to ur through ur error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#el
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
huart->ErrorCode = HAL_UART_ERROR_NONE;
}
出国前英语培训
奥斯卡奖杯}
return;
} /* End if some error occurs */
/* UART in mode Transmitter ------------------------------------------------*/
if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))  {
{
UART_Transmit_IT(huart);
return;
}
/* UART in mode Transmitter end --------------------------------------------*/
if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
{
UART_EndTransmit_IT(huart);                          //看这⾥
return;
entire是什么意思}
}
和DMA的中断请求⼀样的套路,根据状态寄存器的值判断中断的种类,不过和DMA中断请求不同的是,UART中断请求没有直接调⽤回调函数,⽽是先进对应的中断处理函数。本例发送完成中断便会调⽤程序最后的UART_EndTransmit_IT。
调⽤发送完成中断处理函数:UART_EndTransmit_IT
static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
{
/* Disable the UART Transmit Complete Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_TC);
/* Tx process is ended, restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Tx complete callback*/
huart->TxCpltCallback(huart);
#el
/*Call legacy weak Tx complete callback*/
HAL_UART_TxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
return HAL_OK;
}
这部分程序很简短,⾸先是失能了UART的发送完成中断,后⾯就是熟悉的套路了——UART的回调函数,之后便进⼊
HAL_UART_TxCpltCallback,和上⾯就类似了,不多说了。
总结:以上就是UART的DMA发送啦,主要对⽐了上篇的接收过程,好像把UART的普通中断模式发送也说了~~
另外就是,UART可以采⽤轮询、中断、DMA的⽅式,⽽且都有对应的API,看清再下⼿!

本文发布于:2023-05-23 10:14:57,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/119435.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:中断   发送   回调   函数   接收   完成   判断
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图