gpt4 book ai didi

c - HAL_UART_Transmit_IT 如何在 STM32F091VB 上管理串行发送数据

转载 作者:行者123 更新时间:2023-12-05 03:25:20 25 4
gpt4 key购买 nike

我试图了解 STM32F091VB 如何使用函数 HAL_UART_Transmit_IT() 管理通过串行协议(protocol)发送的数据

目前,我在 main() 中调用了一个函数,它创建数据包并通过串行发送;它是这样的:

tx1[0] = STX;    
tx1[1] = 0xFF;
tx1[2] = 0x80;
tx1[3] = 0x80;

DE_TAST_HIGH;
HAL_UART_Transmit_IT(&huart3, tx1, 8);

现在,我发送的数据非常小,所以代码运行得非常快,我试图了解如果我尝试通过串行协议(protocol)发送一个巨大的数据包会发生什么。

例如,如果我的 tx1[] 是 100 字节,则 HAL_UART_Transmit_IT() 函数会阻止 CPU 在将完整数据包发送到串行端口时等待,否则它会工作更多就像一个单独的过程,我告诉 micro 发送那个数据包,并且在发送它的同时它还处理我的代码/主要功能的剩余部分?

我试图搜索微型数据表,看看是否有关于这个过程的东西,但我没有运气。我已经阅读了 stm32f0xx_hal_uart.c,它确认它是以非阻塞模式通过中断发送的,但我想要一些关于它的更深入的文档

最佳答案

首先,您需要了解如何使用 HAL_UART_Transmit_IT。我们可以从STM FAQ得到一些帮助.

interrupt mode.

该函数是“非阻塞”的,因为当您调用它时,它会对中断进行一些配置,然后返回。在调用您的函数期间不会传输缓冲区,而是将繁重的工作推迟到稍后阶段。

我们可以进一步查看源代码,从我所说的中得到一个证明(注意我只保留了有趣的部分)。

阻塞

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
}

非阻塞

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 函数仅激活一个中断,同样基于数据表:

enter image description here

enter image description here

这意味着只要 TX 缓冲区空闲,我们就会收到一个中断。 那么实际上是谁在发送数据?

借助 FAQ 和阅读源代码,我们发现 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代码导航器查看我的代码片段并进一步调查。

关于c - HAL_UART_Transmit_IT 如何在 STM32F091VB 上管理串行发送数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72041049/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com