2019独角兽企业重金招聘Python工程师标准>>>
请勿转载。谢谢。
###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
- 使能发送