91 lines
1.9 KiB
C++
91 lines
1.9 KiB
C++
const unsigned int scan[] = {5, 6, 7, 8};
|
|
const unsigned int LED[] = {9, 13, 2, 3};
|
|
const unsigned int BUTTON[] = {A0, A1};
|
|
#define DATA 10
|
|
#define LATCH 11
|
|
#define CLK 12
|
|
|
|
void setup() {
|
|
for (int i = 0; i < 4; i++) {
|
|
pinMode(scan[i], OUTPUT);
|
|
digitalWrite(scan[i], HIGH);
|
|
}
|
|
for (int i = 0; i < 4; i++) {
|
|
pinMode(LED[i], OUTPUT);
|
|
digitalWrite(LED[i], HIGH);
|
|
}
|
|
for (int i = 0; i < 2; i++) {
|
|
pinMode(BUTTON[i], INPUT);
|
|
}
|
|
pinMode(DATA, OUTPUT);
|
|
pinMode(LATCH, OUTPUT);
|
|
pinMode(CLK, OUTPUT);
|
|
}
|
|
|
|
int get_mode() {
|
|
static int last = 0;
|
|
for (int i = 0; i < 2; i++) {
|
|
if (!digitalRead(BUTTON[i])) {
|
|
last = i+1;
|
|
return last;
|
|
}
|
|
}
|
|
return last;
|
|
}
|
|
|
|
void show(byte digits[4]) {
|
|
for (int i = 0; i < 4; i++) {
|
|
digitalWrite(LATCH, LOW);
|
|
shiftOut(DATA, CLK, MSBFIRST, ~digits[i]); // 低態觸發
|
|
digitalWrite(LATCH, HIGH);
|
|
digitalWrite(scan[3 - i], LOW); // 點亮一毫秒
|
|
delay(1);
|
|
digitalWrite(scan[3 - i], HIGH);
|
|
}
|
|
}
|
|
|
|
void mode_display() {
|
|
static byte digits[4]; // 所有數字的狀態
|
|
static byte p = 0; // 現在要改變的數字
|
|
static unsigned long checkpoint = 0;
|
|
show(digits);
|
|
if (millis() - checkpoint > 200) {
|
|
if (p == 4) {
|
|
// 所有 LED 皆點亮,重設所有值
|
|
p = 0;
|
|
for (int i = 0; i < 4; i++) digits[i] = 0;
|
|
}
|
|
digits[p] <<= 1; // 向左移位
|
|
digits[p] += 1; // 補一
|
|
if (digits[p] == 0xFF) {
|
|
// if current digit is full, change to the next one
|
|
p++;
|
|
}
|
|
checkpoint = millis();
|
|
}
|
|
}
|
|
|
|
void mode_led() {
|
|
static unsigned long checkpoint;
|
|
static int c = 0;
|
|
if (millis() - checkpoint > 200) {
|
|
for (int i = 0; i < 4; i++) {
|
|
digitalWrite(LED[i], i != c%4);
|
|
}
|
|
c++;
|
|
checkpoint = millis();
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
switch (get_mode()) {
|
|
case 1:
|
|
mode_display();
|
|
break;
|
|
|
|
case 2:
|
|
mode_led();
|
|
break;
|
|
}
|
|
}
|