首先,你需要了解HAL_UART_Transmit_IT
的用途.我们可以从STM FAQ人那里得到一些帮助.
这个函数是"非阻塞"的,因为当你调用它时,它会对中断进行一些配置,然后返回.在调用函数的过程中,缓冲区不会被传输,相反,繁重的工作将被推迟到稍后的阶段.
我们可以进一步查看源代码,从我说的话中得到证据(注意,我只保留了有趣的部分).
stage调度
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint16_t* tmp;
uint32_t tickstart = 0U;
// [ ... ]
huart->TxXferSize = Size;
huart->TxXferCount = Size;
while(huart->TxXferCount > 0U)
{
// [ ... ]
// This is were the actual HW regs are accessed, starting the transfer
huart->Instance->DR = (*pData++ & (uint8_t)0xFF);
}
}
// [ ... ]
return HAL_OK
}
Non stage调度
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
/* Enable the UART Transmit data register empty Interrupt */
// This is the only part were HW regs are accessed. What is happening here??
SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
return HAL_OK;
}
IT功能仅激活一个中断,也基于数据表:
这意味着只要TX缓冲区空闲,我们就会收到一个中断.Who is actually sending the data then?
在常见问题解答和阅读源代码的帮助下,我们发现void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
的功能如下:
/* UART in mode Transmitter ------------------------------------------------*/
if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
{
UART_Transmit_IT(huart);
return;
}
这又称为UART_Transmit_IT
static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
{
uint16_t* tmp;
/* Check that a Tx process is ongoing */
if(huart->gState == HAL_UART_STATE_BUSY_TX)
{
huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF);
if(--huart->TxXferCount == 0U)
{
/* Disable the UART Transmit Complete Interrupt */
CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
/* Enable the UART Transmit Complete Interrupt */
SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
这个函数只传输一个字节!然后它递减传输的计数器(记住,所有信息都被设置到uart处理程序中),如果达到0,最后调用complete
中断.
打断
请注意,StmCube为您执行外围设备初始化和中断链接,但如果您从头开始编程,则需要记住写入和注册UART_IRQ_Handler
您可以在"代码导航器"中找到here条代码,以查看我的代码片段并进行进一步研究.