STM32_串口接收中断_实现定长数据接收_调试记录(1)

本文介绍了在STM32上使用中断接收上位机发送的定长数据的方法,着重强调了波特率匹配和硬件干扰问题。通过解决1对多连接导致的数据误码率问题,实现了串口通信的稳定性。关键代码在于`HAL_UART_Receive_IT()`函数的调用,用于启动中断接收。同时,详细解释了中断处理函数和回调函数的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

第一处:main.c

第二处:"AngelaDecode.c"


最近调串口接收是费了我很久的时间,软件没写过现学,硬件还出了问题【后面证明的】。

有一个点需要加深印象,当你串口能接收到数据,但是数据误码率很高的情况下。

首先,判断通信双方的波特率是否匹配、硬件是否支持这么高的波特率。

其次,大概率是硬件内部的干扰。 比如 我遇到的问题是,使用232通信,但硬件连接上出现了【1对多】的情况。

把【1对多】修改成【1对1】数据误码率瞬间就下降了。

下面总结使用 STM32 使用中断接收 上位机发送的定长数据,使用到的相关代码。

上位机一般下发的都是命令数据,时不时才发一回。因此暂时先不追求效率。

主要参考博客:STM32串口接收中断——基于HAL库 - 山无言 - 博客园 (cnblogs.com)

博客最后这段话是最受益的,我认为写在前面更合适。

【看完本文,大家可能对回调函数和中断处理函数的关系产生了疑问。其实是这样的,单片机每完成接收一个字符,就会进入一次中断处理函数,而在中断处理函数中,我们又调用了函数 void HAL_UART_IRQHandler ( UART_HandleTypeDef * huart ),该函数会间接调用回调函数,也就是说回调函数是由中断处理函数间接调用的。而函数 HAL_UART_Receive_IT ( UART_HandleTypeDef *huart, uint8_t * pData, uint16_t Size)决定了中断处理函数调用回调函数的频率,若Size为1,则每进入一次中断处理函数都会调用一次回调函数;若Size为10,则每第十次进入中断处理函数时,才会调用回调函数。方法2使用了标准库中断处理数据的思想。】

上面那段话好好Get一下啥意思,再往下看。

没学会的时候很懵逼,学会以后,其实简单得要死。 要实现<串口中断接收上位机发送的定长数据>这个功能,只需要修改两处代码。

第一处:main.c

/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_TIM3_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
	HAL_TIM_Base_Start_IT(&htim3);
	userinit();
	HAL_UART_Receive_IT(&huart1,&value,1);	// 【这一句最关键,就这一句!】
											// 也可以写到MX_USART1_UART_Init();这个函数里面去
											// 免得你看到烦
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		usermain();
  }
  /* USER CODE END 3 */

第二处:"AngelaDecode.c"

// 此文件专门用于接收并处理上位机数据, 你可自己定义串口接收源文件a.c b.c,随便你。 你写在main.c里面也可以。 好好看注释就行,我不必多说。

#include "usart.h"		// 这必须包含! 
#include "AngelaDecode.h"

unsigned char value;	// main.c要包含AngelaDecode.h,value的定义在这里,.h里面定义了extern
unsigned char AngelaRx[128]={0x00};
short AngelaRxCNT = 0;

// 这函数本来有定义,但它前面有个关键字【__weak】,意思是自己可以重新定义一个同名函数,并且会被优先调用
。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if(huart->Instance==USART1)	// 由于所有的串口中断都会调用这个回调函数,因此要判断是串口几调用的
  {				
		AngelaRx[AngelaRxCNT] = value;	// 这时候value里面已经保持的有数据了
		AngelaRxCNT++;
		HAL_UART_Receive_IT(&huart1, &value,1);		// 再次使能中断	
		if(AngelaRxCNT==128){	// 这128就是我定的“长”。集齐了128字节就召唤神龙!
			AngelaCmdDecode();	// 数据有128字节后,开始解析上位机发过来是什么命令。	
            AngelaRxCNT = 0;	// CNT重新置零。 以便接收下一个128字节的命令包
		}
  }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖上都叫我秋博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值