说德道礼 2026-03-19 23:54 采纳率: 0%
浏览 7

STM32对射式红外传感器计次

对射式红外传感器计次问题:
将遮挡物放在传感器中间led灯熄灭,拿走led灯点亮,次数中断触发,显示屏上的读数应该加一,但是实际情况是显示屏读数未增加,中断似乎没有触发,得出这个结果的原因是我写了一个参数设他初始值为1,若触发中断则赋这个参数为0,后来显示屏上显示的是1.
以下为计次部分代码:

img

img

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-03-19 23:55
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    你描述的问题是关于 STM32 使用 对射式红外传感器 进行 计次 的问题。根据你的描述,显示屏上的读数没有增加,说明 中断未被正确触发中断处理逻辑有误


    一、问题分析

    你提到以下几点:

    1. 遮挡物在传感器中间时,LED灯熄灭;拿走后,LED灯点亮
    2. 计次应通过中断触发,但显示屏上的读数未增加
    3. 你设置了一个参数 flag 初始值为 1,若触发中断则将其设为 0,显示屏显示的是 1

    这表明:

    • 中断可能没有被触发(如中断配置错误);
    • 中断服务函数(ISR)中未执行计数操作
    • 标志位 flag 没有被正确更新或读取

    二、可能的原因(加粗重点)

    1. 中断未被正确使能或配置

      • 检查是否在代码中开启了外部中断(EXTI)和 NVIC 中断优先级。
      • 确认是否设置了正确的中断触发方式(如上升沿/下降沿)。
    2. 中断服务函数(ISR)未被调用

      • 如果中断服务函数没有被正确实现或绑定,那么即使触发了中断,也不会执行任何操作。
    3. 标志位 flag 的使用逻辑有误

      • 你将 flag 初始化为 1,并在中断中设为 0,但显示屏上仍显示 1,说明 中断未被触发flag 未被正确读取
    4. 中断触发条件不匹配

      • 对射式红外传感器的输出信号是否符合中断触发条件?例如:是否是低电平触发?是否是高电平触发?
    5. 传感器与 STM32 的连接问题

      • 确保传感器的信号线已正确连接到 STM32 的某个 GPIO 引脚,并且该引脚配置为输入模式。

    三、解决方案(有序列表)

    1. 检查 EXTI 配置

      • 确保在初始化代码中配置了 EXTI 和 NVIC。
      • 示例代码如下:
      // 配置 EXTI 中断
      void EXTI_Config(void) {
          EXTI_InitTypeDef EXTI_InitStruct;
          NVIC_InitTypeDef NVIC_InitStruct;
      
          // 使能 EXTI 时钟
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
      
          // 配置 PA0 为 EXTI0
          GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
      
          EXTI_InitStruct.EXTI_Line = EXTI_Line0;
          EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
          EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // 上升沿+下降沿
          EXTI_InitStruct.EXTI_LineCmd = ENABLE;
          EXTI_Init(&EXTI_InitStruct);
      
          // 配置 NVIC
          NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
          NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
          NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
          NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStruct);
      }
      
    2. 编写并测试中断服务函数(ISR)

      • 确保中断服务函数被正确实现,并在其中执行计数操作。
      void EXTI0_IRQHandler(void) {
          if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
              // 执行计数操作
              count++;
              EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志
          }
      }
      
    3. 检查标志位 flag 的使用逻辑

      • 你提到 flag = 1,中断中 flag = 0,但显示屏显示的是 1,说明:

        • 中断未被触发
        • 或者 flag 未被正确读取(比如在主循环中没有更新显示)。
      • 建议直接使用 count 变量来显示数值,而不是依赖 flag

    4. 调试中断是否被触发

      • 在中断服务函数中添加调试信息(如 LED 状态变化或串口打印),以确认是否进入 ISR。
      void EXTI0_IRQHandler(void) {
          if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
              // 打印调试信息
              printf("Interrupt triggered!\n");
              count++;
              EXTI_ClearITPendingBit(EXTI_Line0);
          }
      }
      
    5. 验证传感器与 STM32 的连接

      • 使用示波器或万用表检测传感器输出信号是否正常。
      • 确保传感器的信号线连接至 STM32 的正确 GPIO 引脚,并且该引脚配置为输入模式。

    四、修改后的代码示例(关键部分)

    // 全局变量
    volatile uint16_t count = 0;
    
    // 中断服务函数
    void EXTI0_IRQHandler(void) {
        if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
            count++;  // 计数加一
            EXTI_ClearITPendingBit(EXTI_Line0);  // 清除中断标志
        }
    }
    
    // 主循环中更新显示屏
    while (1) {
        // 显示 count 的值
        Display_Update(count);
    }
    

    五、总结

    重点问题:中断未被正确触发或未被正确处理。

    • 建议直接使用 count 变量进行计数,而非依赖 flag
    • 确保中断服务函数被正确实现并被调用。
    • 使用调试工具(如串口打印或 LED 指示)确认中断是否被触发。

    如有更多代码片段或硬件连接图,可进一步分析具体原因。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月19日