stm32 HAL库 HAL_UART_Transmit_DMA 发送函数分析
时间: 2016-11-13来源:OSCHINA
前景提要
请勿转载。谢谢。
###1.函数主体内容 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_UART_Transmit_DMA 函数全部的代码。除去些初始化的代码,可以提炼到比较重要的代码如下
设置memory 到 periphery 的地址,并且开启中断 并使能DMA通道 HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);
清除串口 TC 中断 FLAG __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
使能发送 SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2.调用HAL_DMA_Start_IT
设置memory 到 periphery 的地址,并且开启中断 并使能DMA通道 函数内容如下 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) { HAL_StatusTypeDef status = HAL_OK; /* calculate DMA base and stream number */ DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress; /* Check the parameters */ assert_param(IS_DMA_BUFFER_SIZE(DataLength)); /* Process locked */ __HAL_LOCK(hdma); if(HAL_DMA_STATE_READY == hdma->State) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_BUSY; /* Initialize the error code */ hdma->ErrorCode = HAL_DMA_ERROR_NONE; /* Configure the source, destination address and the data length */ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); /* Clear all interrupt flags at correct offset within the register */ regs->IFCR = 0x3FU << hdma->StreamIndex; /* Enable Common interrupts*/ hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME; hdma->Instance->FCR |= DMA_IT_FE; if(hdma->XferHalfCpltCallback != NULL) { hdma->Instance->CR |= DMA_IT_HT; } /* Enable the Peripheral */ __HAL_DMA_ENABLE(hdma); } else { /* Process unlocked */ __HAL_UNLOCK(hdma); /* Return error status */ status = HAL_BUSY; } return status; }
设置memory 到 periphery 地址 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
打开中断 hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME; hdma->Instance->FCR |= DMA_IT_FE;
开启通道 __HAL_DMA_ENABLE(hdma);
关于开启通道的的这个marco 可以在这条语句中得到解答 #define __HAL_DMA_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= DMA_SxCR_EN)
###3.结尾 那么HAL_UART_Transmit_DMA 函数主要做的事情顺序如下 设置memory 到 periphery 的地址,并且开启中断 并使能DMA通道 清除串口 TC 中断 FLAG 使能发送

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

热门排行