hal库dma中断发送接收过程(真心没有标准库好用)

hal库dma中断发送接收过程(真⼼没有标准库好⽤)
dma中断定长发送本来很简单的⼀个问题让hal搞的头⼤,调来调去的,说好的彻底封装呢,确实很彻底啊,不废话了,实测之后说说的理解吧,不对的话请⼤佬指正。
hal_uart_transmit_dma如果配置好了dam,开启了通道,直接⽤这个函数。那么这个函数⾥⾯是个啥样的。
函数主体:
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;
/* Check that a Tx process is not already ongoing */
if(huart->gState == HAL_UART_STATE_READY)
{
if((pData == NULL ) || (Size == 0U))
莆田学院网络教育
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(huart);
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;
/* Set the UART DMA transfer complete callback */吕冠成
huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
/* Set the UART DMA Half transfer complete callback */
huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
/* Set the DMA error callback */
韩国四季歌huart->hdmatx->XferErrorCallback = UART_DMAError;
/* Set the DMA abort callback */
huart->hdmatx->XferAbortCallback = NULL;
/* Enable the UART transmit DMA Stream */
tmp = (uint32_t*)&pData;
HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);
/* Clear the TC flag in the SR register by writing 0 to it */
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
/* Process Unlocked */
__HAL_UNLOCK(huart);
/* Enable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
除了相关的初始化外,只要的就是HAL_DMA_Start_IT,很熟悉吧,对了就是势能⼀次dma,然后__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);清除⼀下串⼝接收完成标志(不知道如果开启了串⼝中断的话是个什么⿁情况,按道理应该是优先级的问题)再然后最后⼀步就是启动⼀次dma传输SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);据说hal库⾥⾯没有相关函数所有得⽤寄存器了。 当然在hal_dma_start_it⾥⾯是势能了所有接收/发送的相关句柄的中断情况的。
那么调⽤了hal_uart_transmit_dma,他的回调函数在哪⾥呢,我是真的让这个东西看哭了,看⼿册发现这个回调函数还是串⼝发送的回调函数 HAL_UART_Receive_DMA(&huart1,(uint8_t *)aRxMessage,10);
实测代码:
//stm32f1xx_it.c中的DMA中断句柄课程标准是什么
void DMA1_Channel5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
/* USER CODE END DMA1_Channel5_IRQn 0 */
刘爱勤printf(“here DMA1_Channel5_IRQHandler”);
HAL_DMA_IRQHandler(&hdma_usart1_rx);//串⼝接收DMA通道
/* USER CODE BEGIN DMA1_Channel5_IRQn 1 */
/* USER CODE END DMA1_Channel5_IRQn 1 */
}
//在main.c中通过重载来处理DMA接收的数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
//printf("%c",aRxBuffer[ss]);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback can be implemented in the user file
*/
for (i=0;i<100;i++){
printf("%c",aRxMessage[i]);
}
HAL_UART_Receive_DMA(&huart1,(uint8_t *)aRxMessage,10);
故宫博物院教学设计/
/HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, 10,0xFFFF);
}
/* USER CODE END 4 */
使⽤串⼝DMA接收数据,即使不使⽤“接收⼀半数据中断”,在接收⼀半数据后,也会触发相应的DMA通道中断句柄,全部数据接收完成后,⼜触发相应的DMA通道中断句柄,通过DMA通道中断句柄,⽽DMA中断句柄最终还是会调⽤串⼝接收中断回调函数,所以最终接收的数据可以通过重载串⼝接收中断回调函数来处理
在stm32f1xx_it.c中的与串⼝接收相关的DMA通道中断句柄函数,注意这个中断句柄与接收或发送相对应,也就是说发送和接收是2个不同DMA通道中断句柄。⽐如使⽤ HAL_UART_Receive_DMA(&huart1,(uint8_t *)aRxMessage,6) 在下⾯的代码中,我接收到3个数据就会触发printf(“here DMA1_Channel5_IRQHandler”) 接收到6个数据,⼜触发printf(“here DMA1_Channel5_IRQHandler”),同时这接收到的6个数据,通过重载串⼝接收中断回调函数来处理。(其实这整个流程就是调⽤HAL_UART_Receive_DMA函数后还是会回到标准库中到DMA1_Channel5_IRQHandler相关流通道的中断函数,然后进⼊HAL_DMA_IRQHandler,这个是hal库中给的统⼀的dma中断处理函数,然后在⾥⾯判断是哪⼀种中断标志,然后调⽤相关的串⼝回调处
理函数处理数据),hal库的好处就是我们省去了中间调来调去的过程,⽤户直接⽤串⼝回调函数就好了,对了记得最后如果还要继续调⽤⼀次HAL_UART_Receive_DMA继续接收,反正我是没有清除中断标志位的,不知道是不是清除串⼝中断就可以了,明天测试下发送。有问题的话可以在讨论下,反正我觉得没有标准库好⽤,可是stmcube好⽤啊!

本文发布于:2024-09-22 01:05:12,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/118830.html

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

标签:中断   接收   函数   句柄   通道   发送   数据
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议