#include <LedControl.h>
// MAX7219 接线(DIN, CLK, CS)
#define PIN_DIN 11
#define PIN_CLK 13
#define PIN_CS 10
LedControl lc(PIN_DIN, PIN_CLK, PIN_CS, 1); // 最后一个参数=设备数
bool isPrime(int n) {
if (n < 2) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int d = 3; d * d <= n; d += 2) {
if (n % d == 0) return false;
}
return true;
}
void clearAll() {
lc.clearDisplay(0);
}
// 在4位窗口内右对齐显示整数(无前导0;负数显示减号)
void showIntegerNoLeadingZeros(int value) {
clearAll();
// 显示窗口使用最右4位(pos0=最右,pos3=第4位)
if (value == 0) {
lc.setDigit(0, 0, 0, false);
return;
}
bool negative = value < 0;
unsigned int v = negative ? (unsigned int)(-value) : (unsigned int)value;
int pos = 0; // 从最右开始
while (v > 0 && pos <= 3) {
byte d = v % 10;
lc.setDigit(0, pos, d, false);
v /= 10;
pos++;
}
if (negative && pos <= 3) {
lc.setChar(0, pos, '-', false); // 紧靠最高位数字左侧放减号
}
}
// 显示 -0.9 ~ -0.1,格式:[ ][-][0.][d] (从左到右)
// 对应位:pos3 blank, pos2 '-', pos1 '0.'(带小数点), pos0 d
void showNegativeTenthDigit(int tenth) {
int d = -tenth; // tenth: -9..-1 -> d:1..9
clearAll();
lc.setChar(0, 2, '-', false);
lc.setDigit(0, 1, 0, true); // 0. 小数点=true
lc.setDigit(0, 0, d, false); // 1..9
}
void blinkCurrentIfPrime(int value, uint16_t onMs = 150, uint16_t offMs = 150) {
if (!isPrime(value)) {
delay(700);
return;
}
for (int i = 0; i < 3; i++) {
showIntegerNoLeadingZeros(value);
delay(onMs);
clearAll();
delay(offMs);
}
showIntegerNoLeadingZeros(value);
delay(700);
}
void setup() {
lc.shutdown(0, false); // 退出省电模式
lc.setIntensity(0, 8); // 亮度 0..15
lc.clearDisplay(0);
}
void loop() {
// 1) -9 到 -1
for (int i = -9; i <= -1; i++) {
showIntegerNoLeadingZeros(i);
delay(700);
}
// 2) -0.9 到 -0.1
for (int t = -9; t <= -1; t++) {
showNegativeTenthDigit(t);
delay(700);
}
// 3) 0 到 20(质数闪烁3次;整数无前导0)
for (int i = 0; i <= 20; i++) {
showIntegerNoLeadingZeros(i);
blinkCurrentIfPrime(i);
}
}