想用STM32编一个动态判断外部电路是否接通的程序:如果接通就认为满足条件(标志位置1),可以执行下一步动作。在执行过程中外部电路状态可能发生改变,希望系统能一直监控并更新标志位。
用杜邦线连接3V3模拟外部电路导通,拔掉杜邦线模拟断开。
自己用中断方式试着实现了一下,断开电路(拔掉杜邦线)时响应过于频繁,连续有15个左右的中断,然后就不再响应了。怀疑是信号抖动,在中断响应程序里加了延时后中断干脆不响应了。
想请教一下有经验的人士指教一下,如何实现
动态判断外部电路是否接通
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
5条回答 默认 最新
关注 引自免费微信小程序:皆我百晓生
针对您的问题,您想在STM32上编写一个程序,动态检测外部电路的通断状态,并通过标志位控制后续操作。当拔插杜邦线时,中断过于频繁且可能存在信号抖动。下面我将提供一种基于GPIO输入和软件滤波的方式来解决这个问题:
首先,确保您已经正确配置了GPIO引脚作为外部输入,并启用相应的外部中断(比如上升沿和下降沿)。这里我们假设使用的是PA0引脚:
#include "stm32f10x.h" // 初始化GPIO及中断 void GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 开启GPIOA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PA0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 上拉输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); // 配置EXTI线 EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = EXTI_Line0; // 对应PA0 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling | EXTI_Trigger_Rising; // 双边沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; // EXTI0通道中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } volatile bool circuit_connected = false; // 中断服务程序中更新的全局标志位 // EXTI0中断服务程序 void EXTI0_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line0) != RESET) { EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志 static uint8_t debounce_counter = 0; static bool previous_state = !circuit_connected; // 记录前一次的状态 GPIO_PinState current_state = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0); // 软件去抖动:连续检测n次(例如n=5)状态稳定才认为状态改变有效 if(current_state != previous_state) { debounce_counter++; if(debounce_counter == DEBOUNCE_THRESHOLD) { debounce_counter = 0; circuit_connected = current_state; // 更新电路连接状态 } } else { debounce_counter = 0; } previous_state = current_state; } } int main(void) { // ... 其他初始化代码 ... GPIO_Init(); // 初始化GPIO和中断 while(1) { if(circuit_connected) { // 执行下一步动作 // ... } } }
请注意,在上述代码中,
DEBOUNCE_THRESHOLD
是一个自定义的常量,用于设置去抖动的次数阈值,您可以根据实际情况调整该值以适应不同的硬件环境和需求。此外,由于无法实际模拟图片,请确保您的硬件接线没有问题,同时适当增大电阻(如10K欧姆)以减小接触电阻导致的信号干扰和电平变化速率,从而降低抖动的可能性。如果仍然存在问题,请检查MCU的工作模式、电源管理以及其它可能影响到中断响应的因素。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥15 ESP32CAM使用报错
- ¥15 c#对datatable 所有列查询,符合条件的列替换数据
- ¥15 ise14.7烧写flash失败
- ¥100 ICEM3-4度尖角位置能不能将质量提升到0.2甚至更高
- ¥15 在网页上点击view PDF或者open PDF之类的选项加载很慢甚至加载不出来,换网或浏览器都不行
- ¥115 不能成功安装R语言pathview包
- ¥15 LEfSe在线分析Galaxy报错,如何解决?
- ¥15 GTEx数据库eqtl数据整理求教学
- ¥15 初学者,自己写的js俄罗斯代码,谁能帮我调试并找出问题所在!! 自己调试了好多遍!快乱了,崩溃了!
- ¥15 qt 编译webengine 支持 webgl