You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

中断模式下软UART数据损坏,仅读取条形码首字符求助

中断模式软UART仅接收第一个字符的问题排查与修复

1. 接收完成判断逻辑过早终止定时器

你在定时器中断回调里,一检测到SUart[0].RxTimingFlag == 0且SUart[0].RxBitCounter == 0就立刻停定时器、关软UART接收。但条码扫描器输出的是连续字符流(完整条码数据+回车),第一个字符接收完后,下一个字符的起始位(下降沿)会紧接着到来,此时定时器已经停了、软UART也禁用了,后续字符自然抓不到。

修复方案:
删掉定时器回调里直接停定时器的逻辑,改成只有收到条码结束符(比如\r)时再停止定时器、处理数据。示例:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
  if (htim == &htim3) {
    SoftUartHandler();
    // 仅当接收到回车符时,才停止定时器并处理数据
    uint8_t temp = SUart[0].RxBuf; // 假设库中RxBuf存当前接收的字符
    if (temp == '\r') {
      HAL_TIM_Base_Stop_IT(htim);
      SoftUartDisableRx(0);
      printData();
    }
  }
}

2. printData()仅读取单个字符

你的printData()每次只调用getChar(0)一次,但软UART缓冲区里可能已经存了整个条码的多个字符,这就导致只输出第一个,剩下的字符留在缓冲区里,下次触发时可能被覆盖或无法读取。

修复方案:
循环读取缓冲区里的所有字符,直到空为止:

void printData(void) {
  uint8_t ch;
  uint8_t buffer[100];
  uint8_t bufferIndex = 0;

  // 循环读取所有已接收的字符
  while (SoftUartRxAvailable(0)) { // 假设库有判断缓冲区是否有数据的函数
    ch = getChar(0);
    HAL_UART_Transmit(&huart2, &ch, 1, HAL_MAX_DELAY);
    
    if (ch == '\r') {
      buffer[bufferIndex++] = '\r';
      buffer[bufferIndex++] = '\n';
      HAL_UART_Transmit(&huart2, buffer, bufferIndex, HAL_MAX_DELAY);
      bufferIndex = 0;
    } else {
      buffer[bufferIndex++] = ch;
      if (bufferIndex >= sizeof(buffer)) {
        HAL_UART_Transmit(&huart2, buffer, bufferIndex, HAL_MAX_DELAY);
        bufferIndex = 0;
      }
    }
  }
}

如果库没有SoftUartRxAvailable(),可以查SUart结构体里的字段(比如RxCount)判断缓冲区剩余字符数。

3. EXTI与定时器中断优先级冲突

如果EXTI(PIN13对应的中断线)优先级比Timer3低,后续字符的起始位下降沿可能无法及时触发EXTI,导致软UART没法启动接收后续字符。

修复方案:
在CubeMX里调中断优先级,让EXTI15_10_IRQn(对应PIN13)的抢占优先级高于TIM3_IRQn。比如EXTI设为2,Timer3设为3。

4. 软UART接收状态未正确重置

第一个字符接收完后,软UART的内部状态(比如RxTimingFlag、RxBitCounter)可能没重置,导致后续字符无法被正确捕获。

修复方案:
在调用SoftUartEnableRx(0)前手动重置状态(确认库逻辑允许的前提下):

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
  if (GPIO_Pin == GPIO_PIN_13) {
    // 重置接收状态
    SUart[0].RxTimingFlag = 0;
    SUart[0].RxBitCounter = 0;
    SUart[0].RxByte = 0;
    // 启用接收并启动定时器
    SoftUartEnableRx(0);
    HAL_TIM_Base_Start_IT(&htim3);
  }
}

内容的提问来源于stack exchange,提问作者Marek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:22:45