Nic*_*ldo 3 c serial-port stm32 uart stm32f0
我试图了解 STM32F091VB 如何使用以下功能通过串行协议管理数据发送HAL_UART_Transmit_IT()
目前,我在 main() 中调用了一个函数,该函数创建数据包并通过串行发送;它是这样的:
tx1[0] = STX;
tx1[1] = 0xFF;
tx1[2] = 0x80;
tx1[3] = 0x80;
DE_TAST_HIGH;
HAL_UART_Transmit_IT(&huart3, tx1, 8);
Run Code Online (Sandbox Code Playgroud)
现在,我发送的数据非常小,因此代码运行得非常快,我试图了解如果我尝试通过串行协议发送一个大数据包会发生什么。
例如,如果我的数据包tx1[]是 100 字节,则该HAL_UART_Transmit_IT()功能会阻止 CPU 在将完整数据包发送到串行端口时等待,或者它的工作方式更像是一个单独的进程,我告诉微控制器发送该数据包,并且在发送数据包的同时,它还处理剩余的数据包。我的代码/主要功能的一部分?
我试图在微型数据表上搜索,看看是否有关于此过程的信息,但我没有运气。我已阅读stm32f0xx_hal_uart.c并确认它是通过中断以非阻塞模式发送的,但我想有一些关于它的更深入的文档
小智 5
首先,您需要了解如何HAL_UART_Transmit_IT使用它。我们可以从STM FAQ获得一些帮助。
该函数是“非阻塞”的,因为当您调用它时,它将对中断进行一些配置,然后返回。在调用函数期间不会传输缓冲区,而是将繁重的工作推迟到稍后阶段。
我们可以进一步查看源代码,从我所说的得到证据(注意我只保留了有趣的部分)。
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
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
_IT 函数仅激活一个中断,也基于数据表:
这意味着只要 TX 缓冲区空闲,我们就会收到中断。那么到底是谁在发送数据呢?
在常见问题解答和阅读源代码的帮助下,我们发现它的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;
}
Run Code Online (Sandbox Code Playgroud)
这又调用了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;
}
}
Run Code Online (Sandbox Code Playgroud)
该函数只传输一个字节!然后它会递减传输计数器(记住,所有信息都已设置到 uart 处理程序中),如果达到 0,则最后complete调用中断。
请注意,StmCube 会为您完成外设初始化和中断链接,但如果您从头开始编程,则需要记住写入和注册UART_IRQ_Handler
您可以在此处找到代码导航器来查看我的代码片段并进一步调查。