// 指定 loop 执行的次数
// 所有的 LED 灯的引脚,如果自定义了引脚,请修改这里的数组内容
int ledPins[] = {22, 5, 4, 2, 15, 21, 16, 0};
// 位选择用的引脚,设定为 4 位数码管
int controlPins[] = {23, 19, 18, 17};
// 七段数码管字符对应的二进制编码
uint8_t chars[] = {
0b00111111, // 字符 '0'
0b00000110, // 字符 '1'
0b01011011, // 字符 '2'
0b01001111, // 字符 '3'
0b01100110, // 字符 '4'
0b01101101, // 字符 '5'
0b01111101, // 字符 '6'
0b00000111, // 字符 '7'
0b01111111, // 字符 '8'
0b01111111, // 字符 '9'
// 小数点表示(假设小数点只点亮最右边一位的LED)
0b00000001, // 小数点
};
unsigned char virtualchars[10]; // 在全局作用域中声明
// 为了方便,我们添加 -0.1 到 -0.9 的编码(这里简单处理为在数字后添加小数点)
int8_t charsWithDecimal[] = {
virtualchars[9] = 0b00000001, // -0.9
virtualchars[8] = 0b00000010, // -0.8
virtualchars[7] = 0b00000011, // -0.7
virtualchars[6] = 0b00000100, // -0.6
virtualchars[5] = 0b00000101, // -0.5
virtualchars[4] = 0b00000110, // -0.4
virtualchars[3] = 0b00000111, // -0.3
virtualchars[2] = 0b00001000, // -0.2
virtualchars[1] = 0b00001001, // -0.1
// 假设我们简单地将小数点添加到对应数字后。
};
// 延时的时间长度,默认500ms
uint32_t interval = 500;
// 现在要显示哪个字符的索引
int indexOfChar = 0;
// 判断一个数是否为质数
bool isPrime(int num) {
if (num <= 1) return false;
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) return false;
}
return true;
}
const int pin = 13; // 声明一个常量引脚号
// 在指定的位置输出字符(包括小数点的处理)
void outputChar(int n, uint8_t charCode, bool decimal = false) {
pinMode(pin, OUTPUT);
// 打开对应位的位选,关闭其他的位选
for (int i = 0; i < 4; i++) {
if (i == n) {
digitalWrite(controlPins[i], LOW);
} else {
digitalWrite(controlPins[i], HIGH);
}
}
// 把字符输出到相应的位选上
for (int i = 0; i < 7; i++) {
int bit = bitRead(charCode, i);
if (bit == 1) {
digitalWrite(ledPins[i], HIGH);
} else {
digitalWrite(ledPins[i], LOW);
}
}
// 处理小数点(如果需要的话)
if (decimal) {
digitalWrite(ledPins[7], HIGH); // 假设小数点连接在ledPins[7]
} else {
digitalWrite(ledPins[7], LOW);
}
digitalWrite(pin, HIGH);
}
// 清除当前位置的内容
void clearChar() {
digitalWrite(pin, LOW);
for (int i = 0; i < 8; i++) { // 包括小数点
digitalWrite(ledPins[i], LOW);
}
for (int i = 0; i < 4; i++) {
digitalWrite(controlPins[i], HIGH); // 确保所有位选都是关闭的
}
digitalWrite(pin, HIGH);
}
void setup() {
pinMode(pin, OUTPUT); // 设置引脚模式
// 通过 for 循环,把所有的 LED 灯和控制的引脚设定为 OUTPUT 模式
for (uint8_t pin : ledPins) {
pinMode(pin, OUTPUT);
}
for (uint8_t pin : controlPins) {
pinMode(pin, OUTPUT);
}
}
void loop() {
pinMode(pin, OUTPUT); // 设置引脚模式
digitalWrite(pin, HIGH); // 写入引脚
delay(1000); // 等待一秒
digitalWrite(pin, LOW); // 写入引脚
delay(1000); // 等待一秒
// 清除鬼影
clearChar();
// 显示负数部分 -9 到 -1
for (int i = -9; i >= -1; i++) {
int charIndex = abs(i); // 获取字符的索引(忽略负号)
outputChar(0, chars[charIndex]); // 在第一个位置显示字符
delay(interval);
}
// 显示小数部分 -0.9 到 -0.1
// 你需要确保charsWithDecimal数组正确填充了这些值
for (int i = 0; i < 9; i++) {
outputChar(0, charsWithDecimal[i], true); // 显示小数并点亮小数点
delay(interval);
}
// 显示正数部分 0 到 20,质数闪烁3次
for (int i = 0; i <= 20; i++) {
bool isPrimeNum = isPrime(i);
for (int j = 0; j < (isPrimeNum ? 3 : 1); j++) { // 质数闪烁3次
outputChar(0, chars[i]); // 在第一个位置显示字符
delay(interval / 3); // 缩短延时以加快闪烁效果
clearChar(); // 清除显示以形成闪烁效果
}
delay(interval - (isPrimeNum ? interval / 3 * 2 : 0)); // 补偿之前的延时缩短
}
}