stm32库函数void usart_senddata()的缺陷和解决方法
时间: 2023-09-02 07:04:07 浏览: 103
stm32库函数void usart_senddata()的缺陷主要有两点:首先,该函数仅能发送单个字节的数据;其次,该函数是阻塞调用的,发送完成前会一直占用CPU资源。
针对这些缺陷,我们可以通过以下方法进行改进:
首先,针对只能发送单个字节的问题,我们可以重新设计函数的接口,使其能够支持发送一串数据或者数组。例如,重新定义函数为void usart_senddata(uint8_t *data, uint32_t length),其中data为待发送数据的指针,length为数据长度。这样,我们就能够一次性发送多个字节的数据。
其次,为了解决阻塞调用的问题,我们可以借助中断来进行发送操作。首先,在函数中设置发送完成的中断标志位,并开启USART发送中断。然后,在主程序中,不断检查中断标志位是否被置位。当中断标志位被置位时,说明发送完成,可以进行下一步操作;否则,继续等待。
通过以上改进,我们可以实现一次发送多个字节的功能,并且利用中断机制解决了阻塞调用的问题,提高了程序的效率和可靠性。
相关问题
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) { /* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); assert_param(IS_USART_DATA(Data)); /* Transmit Data */ USARTx->DR = (Data & (uint16_t)0x01FF); 逐行解释这段代码
这段代码是 STM32 的库函数中的 USART 数据发送函数,下面逐行解释:
```
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) {
```
函数名为 USART_SendData,参数包括 USARTx 和 Data,其中 USARTx 为 USART_TypeDef 类型,表示待发送数据的 USART 外设;Data 为 uint16_t 类型,表示待发送的数据。
```
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_DATA(Data));
```
这两行代码是用来检查传入参数的合法性的,IS_USART_ALL_PERIPH 和 IS_USART_DATA 是宏定义,用于判断 USARTx 和 Data 是否符合 USART 外设和数据的规范。如果不符合规范,就会触发 assert_param 函数,并在调试模式下产生错误信息。
```
USARTx->DR = (Data & (uint16_t)0x01FF);
```
这行代码是将 Data 需要发送的数据写入到 USART 外设的 DR 寄存器中,DR 寄存器是 USART 数据寄存器,用于存储待发送的数据。由于 DR 寄存器只有低9位有效,因此使用了与运算符 & 0x01FF 将 Data 最高7位清零,确保只有低9位的数据被发送出去。同时也将 Data 强制转换为 uint16_t 类型,确保数据类型符合寄存器要求。
USART_SendData()这个函数是怎么写的
USART_SendData()函数是芯片厂商提供的库函数之一,用于向USART发送单个字节的数据。其函数定义通常包含两个参数:USARTx代表USART端口号,Data表示要发送的数据。
以下是STM32HAL库中USART_SendData()函数的代码:
```
void HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint16_t* tmp = (uint16_t*) pData;
uint32_t tickstart = HAL_GetTick();
huart->TxXferSize = Size;
huart->TxXferCount = Size;
/* Check the remain data to be sent */
while(huart->TxXferCount > 0U)
{
/* Wait until TXE flag is set to send data */
if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
/* Send data with format Data, par, stop */
if(huart->Init.WordLength == UART_WORDLENGTH_9B)
{
huart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
tmp++;
}
else
{
huart->Instance->TDR = (*pData++ & (uint8_t)0xFF);
}
huart->TxXferCount--;
}
/* Wait until TC flag is set to close transmission */
if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
/* Clear TXE flag */
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
```
在此函数中,首先通过tickstart变量记录当前时间,定义了TxXferSize和TxXferCount变量来表示要发送的数据的大小和剩余的数据量。然后在while循环中,判断TxXferCount是否大于0,即是否还有数据未发送。如果TXE标志位被设置,则可以发送数据。在发送数据之前,如果使用了9位字长,则从pData指向的地址中取出9个bit,然后再将其写入TDR寄存器。否则,直接将pData指向的8个bit写入TDR寄存器。最后,等待数据发送完毕,并清除TC标志位。
需要注意的是,USART_SendData()函数在发送数据之前必须调用USART_Init()函数初始化串口参数,确保参数设置正确。
阅读全文