User:日向 无境/testsandbox
跳到导航
跳到搜索
虚拟仿真·倒计时器
参见:https://wokwi.com/projects/464970327855306753
// Arduino UNO + 4x4键盘 + TM1637数码管 倒计时
// 完全无库,纯底层代码
// 支持 0~59分59秒(1小时内)
// # = 开始/暂停 * = 清零
// —————— 引脚定义 ——————
#define CLK 11 // 数码管时钟
#define DIO 12 // 数码管数据
// 键盘行引脚:R1 R2 R3 R4
int rowPins[4] = {9, 8, 7, 6};
// 键盘列引脚:C1 C2 C3 C4
int colPins[4] = {5, 4, 3, 2};
// —————— 全局变量 ——————
int min = 0, sec = 0;
bool isRun = false;
unsigned long lastTime = 0;
// 数码管 0~9 段码表
byte segCode[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
// —————— 初始化 ——————
void setup() {
// 初始化键盘
for(int i=0; i<4; i++) {
pinMode(rowPins[i], INPUT_PULLUP);
pinMode(colPins[i], OUTPUT);
digitalWrite(colPins[i], HIGH);
}
// 初始化数码管
pinMode(CLK, OUTPUT);
pinMode(DIO, OUTPUT);
tmInit();
tmBright(5);
showTime();
}
// —————— 主循环 ——————
void loop() {
char key = readKey();
// —————— 按键处理 ——————
if(key != 0){
if(key >= '0' && key <= '9'){
// 输入时间
min = min * 10 + (key - '0');
if(min > 59) min = 59;
showTime();
}
else if(key == '#'){
// 【开始 / 暂停】
if(min == 0 && sec == 0) return;
isRun = !isRun;
lastTime = millis();
}
else if(key == '*'){
// 【清零】
min = 0;
sec = 0;
isRun = false;
showTime();
}
}
// —————— 倒计时运行 ——————
if(isRun) {
if(millis() - lastTime >= 1000) {
lastTime = millis();
sec--;
if(sec < 0) {
sec = 59;
min--;
}
// 倒计时结束
if(min < 0) {
min = 0; sec = 0;
isRun = false;
alarm();
}
showTime();
}
}
}
// —————— 键盘读取函数 ——————
char readKey() {
char keys[4][4] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
for(int c=0; c<4; c++) {
digitalWrite(colPins[c], LOW);
for(int r=0; r<4; r++) {
if(digitalRead(rowPins[r]) == LOW) {
delay(20);
if(digitalRead(rowPins[r]) == LOW){
while(digitalRead(rowPins[r])==LOW);
digitalWrite(colPins[c], HIGH);
return keys[r][c];
}
}
}
digitalWrite(colPins[c], HIGH);
}
return 0;
}
// —————— 数码管显示时间 MM:SS ——————
void showTime() {
byte data[4];
data[0] = segCode[min / 10];
data[1] = segCode[min % 10] | 0x80; // 冒号
data[2] = segCode[sec / 10];
data[3] = segCode[sec % 10];
tmStart();
tmWrite(0xC0);
for(int i=0; i<4; i++) tmWrite(data[i]);
tmStop();
}
// —————— 结束提醒(闪烁)——————
void alarm() {
for(int i=0; i<6; i++) {
tmClear();
delay(200);
showTime();
delay(200);
}
}
// —————— TM1637 底层驱动(无库)——————
void tmStart() {
digitalWrite(CLK, HIGH);
digitalWrite(DIO, HIGH);
digitalWrite(DIO, LOW);
digitalWrite(CLK, LOW);
}
void tmStop() {
digitalWrite(CLK, LOW);
digitalWrite(DIO, LOW);
digitalWrite(CLK, HIGH);
digitalWrite(DIO, HIGH);
}
void tmWrite(byte b) {
for(int i=0; i<8; i++) {
digitalWrite(CLK, LOW);
digitalWrite(DIO, b & 1);
b >>= 1;
digitalWrite(CLK, HIGH);
}
digitalWrite(CLK, LOW);
digitalWrite(DIO, HIGH);
digitalWrite(CLK, HIGH);
}
void tmInit() {
tmStart(); tmWrite(0x40); tmStop();
}
void tmBright(byte b) {
tmStart(); tmWrite(0x88 | b); tmStop();
}
void tmClear() {
tmStart(); tmWrite(0xC0);
for(int i=0; i<4; i++) tmWrite(0x00);
tmStop();
}