自己DIY一个模拟多按钮电路

普通按键电路原理

        一般使用的按键原理图如下图所示,由按键、上拉电阻R1和消抖滤波电容组成。按键断开时KeyIin1处电压被上拉到+5V,当按键闭合时把KeyIin1电压拉到0V,与按键并联的电容起到滤除按键按下与弹起时的高频信号。

电路 按键 原理

以上的电路缺点是一个按钮需要占用单片机的一个数字接口,如果在电路中需要使用多个按钮时,就需要占用多个接口。在单片机的管脚资源紧张的情况下可以使用以下的模拟按钮方案,仅仅需要占用一个模拟接口(ADC)

模拟多路共用按键原理图

      

电路 按键 原理

       

         使用以上电路,当某个按键按下时,按键对应的电阻与R36串联构成分压电路,C12作为滤波电容,滤除干扰信号,提高ADC检测的稳定性。ADC采集R36上的电压,可以使用查表或者计算的方式得到被按下按键的序号。

        这种方案优点是只需要一个模拟管脚即可识别多个按键的动作,还可以检测多个按键同时按下的动作,使用4个按钮有15种组合,理想状态下相当于15个按钮。对模拟的精度也没有很高的要求;缺点是不能提供中断触发信号。

        在分压电阻取值时应当注意不同按键按下时对应的电压差不能小于ADC的检测精度,否则无法识别到底是哪个按键按下。

Arduino UNO的内置ADC精度是十位,用二进制表达就是十个二进制位,总信息量就是2的10次方(2^10==1024),从0开始就是0~1023了。

        而我们需要电压值,所以做个运算把0~1023转换为0~5V。5÷1024=0.00488伏。也就是说uno板的精度可以检测到小数点后三位,这是一个精确度很高的精确度了。如果你使用的是esp32那么内置精确度是12位,也就是2^12=4098,5伏÷4098=0.00122伏,精确度就更高了。

        另外,模拟接口检测到的值并不是精确稳定的,而是会在某个电压范围内抖动,在编写程序时可以采用判断电压范围的方式来避免误判。

### 设计实现模拟灌溉系统的按键控制电路 #### 1. 系统需求分析 为了满足农业灌溉系统中的手动模式功能,需要设计一套可靠的按键控制系统来允许用户远程或本地操作风扇、LED灯和水泵的开关状态。该系统应具备响应迅速、稳定性高以及易于扩展的特点。 #### 2. 按键硬件选型与布局规划 对于按键的选择,通常会选用机械式轻触开关,因其成本低廉且性能稳定可靠。考虑到实际应用场景下的防水防尘要求,在户外使用的设备建议选择带有密封胶圈的产品型号。每个按键对应不同的控制命令,比如增加/减少阈值设置或是直接触发特定执行机构的动作。 #### 3. 连接到STM32单片机的方式 按键的一端接地(GND),另一端则连接至STM32单片机上的通用输入输出(GPIO)引脚。这种接法能够简化外部供电线路的设计,并利用内部上拉电阻特性提高抗干扰能力。具体来说: - 当按下某个按钮时,对应的GPIO引脚电平会被拉低; - 松开后由于存在内置的弱上拉机制使得信号恢复为高电平。 ```c // 初始化 GPIO 引脚配置函数 void GPIO_Init(void){ // 配置按键所连的 GPIO 口为输入模式并开启内建上拉电阻 GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); // 启用 PA 端口时钟 GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; // 假设使用PA0, PA1两个引脚作为按键接口 GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` #### 4. 软件逻辑处理 编写相应的中断服务程序(ISR)或者轮询方式读取各个按键的状态变化情况。一旦检测到有效按压事件,则依据预定义的功能映射表更新全局变量标志位,进而影响后续的任务调度决策过程。为了避免误判现象的发生,还需要加入去抖动算法以过滤掉瞬态噪声带来的虚假触发问题[^2]。 ```c uint8_t key_state[2]; // 存储两路按键当前状态 void CheckKeyStatus(){ static uint8_t last_key_status[2]; for(int i=0;i<2;++i){ if(HAL_GPIO_ReadPin(GPIOA, (GPIO_PinDef)(1<<i)) != last_key_status[i]){ delay_ms(20); // 添加适当延时等待消抖 if(HAL_GPIO_ReadPin(GPIOA, (GPIO_PinDef)(1<<i))){ // 处理上升沿事件... }else{ // 下降沿事件处理 } last_key_status[i]=HAL_GPIO_ReadPin(GPIOA,(GPIO_PinDef)(1<<i)); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值