STM32使用串口发送数据 复位后第一次发送的数据中第一个数据丢失之原因

问题描述:

使用STM32F103芯片,通过串口USART1发送数据,复位之后,第一次发送数据时,所发送的数据中第一个数据丢失,之后发送的数据正常。代码是从正点原子STM32F1例程中扒出来的,接收和发送同时使用时,是正常的,只有单独使用发送时,存在上述现象。

相应代码:

u8 TEST0_BUF[] = {0XC0,0XF9,0XA4,0xB0,0X99,0X92,0X82,0XF8,0X80,0X90};

if(key==KEY0_PRES)
{	
    delay_ms(10);
    if(key==KEY0_PRES)
    {					   
        le=10;
        for(t=0;t<le;t++)
        {
        	USART_SendData(USART1, TEST0_BUF[t]);
	        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
        }
    }	
}

复位后,第一次按下按键KEY0,发送的数据为:

F9 A4 B0 99 92 82 F8 80 90 

第二次按下按键KEY0,发送的数据为:

F9 A4 B0 99 92 82 F8 80 90 C0 F9 A4 B0 99 92 82 F8 80 90 

由此可见,第一次发送的数据中少了C0,之后发送的数据正常。

添加发送和接收代码进行测试:

u8 TEST0_BUF[] = {0XC0,0XF9,0XA4,0xB0,0X99,0X92,0X82,0XF8,0X80,0X90};

if(key==WKUP_PRES)
{	
    delay_ms(10);			
    if(USART_RX_STA&0x8000 && key==WKUP_PRES)
    {					   
        len = USART_RX_STA&0x3fff;
        for(t=0;t<len;t++)
        {
            USART_SendData(USART1, USART_RX_BUF[t]);
            while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
        }
        USART_RX_STA=0;
    }				
}

if(key==KEY0_PRES)
{	
	delay_ms(10);
	if(key==KEY0_PRES)
	{					   
		le=10;
		for(t=0;t<le;t++)
		{
			USART_SendData(USART1, TEST0_BUF[t]);
			while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
		}
	}	
}

此时,复位后使用串口调试助手发送数据,按下WKUP键,再将数据发回到串口调试助手,数据正常,未出现发送的数据第一位缺少情况;继续按下KEY0也是C0~90数据,正常。若复位后直接按KEY0,第一次发送的数据仍然缺少C0,之后正常。

解决办法:
在发送数据的语句前加上:

USART_ClearFlag(USART1,USART_FLAG_TC);

清除 发送完成标志位 USART_FLAG_TC

测试代码如下:

u8 TEST0_BUF[] = {0XC0,0XF9,0XA4,0xB0,0X99,0X92,0X82,0XF8,0X80,0X90};

while(1)
{
  key=KEY_Scan(0);
	
	if(key==WKUP_PRES)
	{	
		delay_ms(10);			
		if(USART_RX_STA&0x8000 && key==WKUP_PRES)
		{					   
			len = USART_RX_STA&0x3fff;
			for(t=0;t<len;t++)
			{
				USART_SendData(USART1, USART_RX_BUF[t]);
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
			}
			USART_RX_STA=0;
		}				
	}
	if(key==KEY1_PRES)
	{	
		delay_ms(10);
		if(key==KEY1_PRES)
		{					   
			le=10;
			for(t=0;t<le;t++)
			{
				USART_ClearFlag(USART1,USART_FLAG_TC);
				USART_SendData(USART1, TEST0_BUF[t]);
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
			}
		}	
	}
	if(key==KEY0_PRES)
	{	
		delay_ms(10);
		if(key==KEY0_PRES)
		{					   
			le=10;
			for(t=0;t<le;t++)
			{
				USART_SendData(USART1, TEST0_BUF[t]);
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
			}
		}	
	}
}

对比复位后,先按下KEY0和先按下KEY1,即可发现 ,添加清除 发送完成标志位语句后,正常。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!以下是使用HAL库在STM32上编写串口发送数据的函数示例: ```c #include "stm32f4xx_hal.h" void UART_SendData(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t size) { HAL_UART_Transmit(huart, pData, size, HAL_MAX_DELAY); } ``` 在这个例子,我们使用了HAL库提供的`HAL_UART_Transmit`函数来发送数据。该函数的参数包括UART句柄(`huart`)、要发送数据缓冲区指针(`pData`)以及数据大小(`size`)。`HAL_MAX_DELAY`表示在发送过程不设置超时。 要使用该函数,你需要先实例化一个UART_HandleTypeDef结构体,并配置相应的UART外设。例如,你可以在主函数添加以下代码: ```c int main(void) { // 初始化HAL库 HAL_Init(); // 配置GPIO和UART外设 __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_USART2_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); UART_HandleTypeDef huart2; huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; HAL_UART_Init(&huart2); // 发送数据 uint8_t data[] = "Hello, STM32!"; UART_SendData(&huart2, data, sizeof(data) - 1); while (1) { // 主循环 } } ``` 在上面的示例,我们使用了USART2作为UART外设,并将PA2和PA3引脚配置为复用功能以与UART通信。然后,通过调用`UART_SendData`函数发送了一条字符串数据。 请注意,以上代码仅为示例,具体的配置和使用方法可能因所使用STM32型号和开发环境而有所不同。因此,在实际应用,你可能需要根据自己的需求进行适当修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值