cjtdz 发表于 2025-3-13 15:53:55

求一个按键计数代码


有三个按键,增加键UP,减小键DOWN,清除键CLER。点动按下增加键UP,计数值count加1,按下增加键UP不松手,计数值count循环加1,速度不能过快,能及时停止。点动按下减小键DOWN,计数值count减1,按下减小键DOWN不松手,计数值count循环减1,速度也不能过快。按下清除键,计数值count清零。求一个参考代码。

haiyang201 发表于 2025-3-13 17:22:11

论坛里有长短按按键的例程,修改下就可以实现功能

angmall 发表于 2025-3-13 19:27:04

人工智能辅助生成
以下是基于51单片机的按键控制计数器的参考代码,包含短按、长按和清除功能:

```c
#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

// 定义按键引脚
sbit KEY_UP = P3^5;    // 增加键
sbit KEY_DOWN = P3^6;// 减小键
sbit KEY_CLR = P3^7;   // 清除键

// 全局变量
int count = 0;         // 计数值
bit key_flag = 0;      // 按键处理标志位

// 定时器0初始化
void Timer0Init()
{
    TMOD &= 0xF0;      // 设置定时器模式
    TMOD |= 0x01;      // T0 16位定时器模式
    TH0 = 0xFC;      // 1ms定时初值
    TL0 = 0x66;
    ET0 = 1;         // 使能定时器中断
    EA = 1;            // 开总中断
    TR0 = 1;         // 启动定时器
}

// 按键检测函数
void KeyScan()
{
    static uchar key_up = 1;      // 按键松开标志
    static uint press_time_up = 0;// UP键按下时间
    static uint press_time_down = 0;// DOWN键按下时间

    // UP键处理
    if(KEY_UP == 0)
    {
      if(key_up)
      {
            key_up = 0;
            count++;               // 短按立即加1
            press_time_up = 0;   // 开始计时
      }
      else
      {
            press_time_up++;
            if(press_time_up > 500) // 长按500ms后进入连续加
            {
                if((press_time_up % 200) == 0) // 200ms间隔
                {
                  count++;
                }
            }
      }
    }
    else if(KEY_UP == 1)
    {
      key_up = 1;
      press_time_up = 0;
    }

    // DOWN键处理(逻辑与UP键相似)
    if(KEY_DOWN == 0)
    {
      if(key_up)
      {
            key_up = 0;
            count--;
            press_time_down = 0;
      }
      else
      {
            press_time_down++;
            if(press_time_down > 500)
            {
                if((press_time_down % 200) == 0)
                {
                  count--;
                }
            }
      }
    }
    else if(KEY_DOWN == 1)
    {
      key_up = 1;
      press_time_down = 0;
    }

    // 清除键处理
    if(KEY_CLR == 0)
    {
      _nop_();_nop_();          // 简单消抖
      if(KEY_CLR == 0)
      {
            count = 0;            // 清零计数器
            while(!KEY_CLR);      // 等待按键释放
      }
    }
}

// 定时器中断服务程序
void Timer0_ISR() interrupt 1
{
    TH0 = 0xFC;      // 重装初值
    TL0 = 0x66;
    KeyScan();         // 每隔1ms调用按键扫描
}

void main()
{
    Timer0Init();      // 初始化定时器
    while(1)
    {
      // 主循环可添加显示或其他功能
      // 例如通过数码管或串口显示count值
    }
}
```

**代码说明:**

1. **按键响应机制:**
   - **短按**:立即执行加1/减1操作
   - **长按**:按住超过500ms后,每隔200ms自动连续加/减
   - **清除键**:按下立即清零

2. **参数调整建议:**
   ```c
   if(press_time_up > 500)      // 长按触发时间(500ms)
   if((press_time_up % 200) == 0) // 连续加减间隔(200ms)
   ```
   可根据需求调整这两个参数来改变长按响应速度

3. **功能扩展建议:**
   - 添加数码管显示驱动代码显示计数值
   - 增加数值范围限制(如0-999)
   - 添加EEPROM存储功能保存当前计数值
   - 增加蜂鸣器提示音反馈

4. **优化方向:**
   - 可增加更精确的按键消抖处理(软件滤波)
   - 使用状态机实现更复杂的按键处理逻辑
   - 添加按键释放时的回调处理
   - 通过PWM控制LED亮度反馈当前计数值

实际应用中需要根据具体硬件电路调整IO口定义,并可通过示波器观察按键波形来优化延时参数。
页: [1]
查看完整版本: 求一个按键计数代码