使用Arduino制作按键计时系统的方法

目录

一. 所需硬件 

二. 连接示意图

三. 程序

1. 引脚与常量定义

2. 全局变量声明

3. 段码输出函数  deal() 

4. 按键处理函数  handleKeyPress() 

5. 初始化函数  setup() 

6. 主循环函数  loop() 

四.功能

1. 数码管动态扫描:

2. 按键消抖:

3. 计数逻辑:


一. 所需硬件 

 Arduino Uno控制器 
1个四位共阴数码管
1个10k 欧姆电阻
1个按键
1个面包版
条线若干

二. 连接示意图

 

三. 程序

// 数码管a,b,c,d,e,f,g,dp对应引脚
#define SEG_A 7
#define SEG_B 8
#define SEG_C 9
#define SEG_D 10
#define SEG_E 11
#define SEG_F 12
#define SEG_G 13
#define SEG_H A0

#define COM1 2
#define COM2 3
#define COM3 5
#define COM4 6

#define KEY_PIN 4

int ledcount = 8;
int segCount = 4;
long previousMillis = 0;

// 数码管段码表(0-9,共阴极)
const unsigned char DuanMa[10] = {
  0x3f, // 0: 00111111
  0x06, // 1: 00000110
  0x5b, // 2: 01011011
  0x4f, // 3: 01001111
  0x66, // 4: 01100110
  0x6d, // 5: 01101101
  0x7d, // 6: 01111101
  0x07, // 7: 00000111
  0x7f, // 8: 01111111
  0x6f  // 9: 01101111
};

int ledPins[] = {7,8,9,10,11,12,13,A0};
int segPins[] = {2,3,5,6};
// 显示缓冲区:存储四位数码管的段码
unsigned char displayTemp[4];
// 全局变量:计数启停标志、按键状态(消抖)、计数使能
bool countEnable = false;
bool lastkeystate = LOW;
bool currentkeystate = LOW;

// 数码管段码输出函数(消影处理)
void deal(unsigned char value) {
  // 关闭所有段,消影
  for(int i=0; i<8; i++) {
    digitalWrite(ledPins[i], LOW);
  }
  delayMicroseconds(100); // 100微秒消影
  
  // 输出段码
  for(int i=0; i<8; i++) {
    digitalWrite(ledPins[i], bitRead(value, i));
  }
}

// 按键处理函数:检测按键状态,控制计数启停(消抖处理)
void handleKeyPress() {
  // 读取当前按键状态(按下为高电平,需外接上拉/下拉匹配)
  currentkeystate = digitalRead(KEY_PIN);
  
  // 按键消抖:当前状态与上一次不同,且稳定为高电平(按下)
  if(currentkeystate == HIGH && lastkeystate == LOW) {
    delay(20); // 消抖延迟20ms
    // 再次确认按键按下(避免误触)
    if(digitalRead(KEY_PIN) == HIGH) {
      countEnable = !countEnable; // 翻转计数使能状态
      // 等待按键释放(避免重复触发)
      while(digitalRead(KEY_PIN) == HIGH);
    }
  }
  // 更新上一次按键状态
  lastkeystate = currentkeystate;
}

void setup() {
  // 初始化数码管段引脚
  for(int ledpin = 0; ledpin<ledcount; ledpin++) {
    pinMode(ledPins[ledpin], OUTPUT);
  }
  // 初始化数码管位引脚
  for(int segpin = 0; segpin<segCount; segpin++) {
    pinMode(segPins[segpin], OUTPUT);
  }
  // 初始化按键引脚(默认输入,需外接上拉电阻,按下为高电平)
  pinMode(KEY_PIN, INPUT);
  
  // 初始化显示缓冲区为0
  displayTemp[0] = DuanMa[0];
  displayTemp[1] = DuanMa[0];
  displayTemp[2] = DuanMa[0];
  displayTemp[3] = DuanMa[0];
}

void loop() {
  static unsigned int num = 0;
  static unsigned long lastupdateTime = 0;
  static unsigned long lastscanTime = 0;
  static int currentDigit = 0;

  // 1. 处理按键逻辑(每次循环检测)
  handleKeyPress();

  // 2. 仅当计数使能时,更新数字(1秒加1)
  if(countEnable && millis() - lastupdateTime >= 1000) {
    lastupdateTime = millis();
    num = (num + 1) % 10000; // 四位数码管,计数0-9999循环
    
    // 更新显示缓冲区
    displayTemp[0] = DuanMa[num / 1000];    // 千位
    displayTemp[1] = DuanMa[(num % 1000) / 100]; // 百位
    displayTemp[2] = DuanMa[(num % 100) / 10];   // 十位
    displayTemp[3] = DuanMa[num % 10];           // 个位
  }

  // 3. 数码管动态扫描(每3ms扫描一位,保证显示稳定)
  if(millis() - lastscanTime >= 3) {
    lastscanTime = millis();
    
    // 步骤1:关闭当前数码管(消影)
    deal(0x00); // 关闭所有段
    digitalWrite(segPins[currentDigit], HIGH); // 关闭当前位选
    
    // 步骤2:切换到下一个数码管
    currentDigit = (currentDigit + 1) % 4;
    
    // 步骤3:打开新数码管并显示内容
    digitalWrite(segPins[currentDigit], LOW); // 打开新位选
    deal(displayTemp[currentDigit]); // 显示对应段码
  }
}

1. 引脚与常量定义

这部分用 #define 和数组定义了数码管段引脚(SEG_A~SEG_H)、位选引脚(COM1~COM4)、按键引脚(KEY_PIN),以及段码表 DuanMa (存储0-9的共阴极数码管段码),同时定义了数码管段数、位数等常量,方便后续修改硬件引脚。

2. 全局变量声明

声明了显示缓冲区 displayTemp (存储四位数码管要显示的段码)、计数使能标志 countEnable (控制计数启停)、按键状态变量 lastkeystate/currentkeystate (用于按键消抖),还有计时相关的 previousMillis 等变量,全局变量可在多个函数中共享数据。

3. 段码输出函数  deal() 

这是数码管消影和段码输出的核心函数,先关闭所有段引脚消去残影,再根据传入的段码值,通过 bitRead 函数控制每个段引脚的高低电平,实现对应数字的显示。

4. 按键处理函数  handleKeyPress() 

实现按键消抖和计数启停控制:先读取当前按键状态,对比上一次状态,若检测到按键按下则延迟20ms二次确认,确认后翻转 countEnable 的状态,同时等待按键释放避免重复触发,最后更新上一次按键状态。

5. 初始化函数  setup() 

在Arduino上电后只执行一次,功能是将数码管段引脚、位选引脚设为输出模式,按键引脚设为输入模式,同时把显示缓冲区初始化为全0,确保开机时数码管显示 0000 。

6. 主循环函数  loop() 

Arduino会反复执行这个函数,包含三个核心逻辑:调用 handleKeyPress() 检测按键状态;若 countEnable 为真且间隔1秒,计数器 num 加1并对10000取模(限制0-9999),再拆分 num 的千、百、十、个位,更新显示缓冲区;每3ms执行一次数码管动态扫描,依次切换四位数码管的位选引脚,调用 deal() 输出对应段码,利用人眼视觉暂留实现四位同时显示的效果。

四.功能

这份代码是基于Arduino的四位数码管按键启停计数器程序,核心实现数码管动态扫描显示、按键消抖控制计数启停的功能:

1. 数码管动态扫描:

通过快速切换四位数码管的位选引脚,配合段码输出,利用人眼视觉暂留实现“同时显示”效果,每3ms扫描一位保证显示无闪烁。

2. 按键消抖:

通过20ms延迟和二次检测,避免机械按键的抖动导致误触发,同时等待按键释放防止重复触发。

3. 计数逻辑:

计数使能时,每1秒数字加1,模10000实现0-9999循环,通过取模和除法拆分千、百、十、个位数字并转换为段码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值