#include <LedControl.h> // 引入LedControl库,用于控制MAX7219点阵屏幕
// LED连接的数字输出引脚
int ledOutput[] = {A2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; // 定义LED连接的数字输出引脚,使用A2替换2号引脚
// 滑动变阻器连接到模拟输入的引脚
int potentiometer = A0; // 定义滑动变阻器连接的模拟输入引脚
// 存储速度值的变量
int speed; // 定义一个变量用于存储速度值
// MAX7219的引脚定义
#define DIN 12 // 定义MAX7219的数据输入引脚
#define CLK 13 // 定义MAX7219的时钟引脚
#define CS A1 // 定义MAX7219的片选引脚,使用A1作为15号引脚
// 创建LedControl对象
LedControl ledCtrl = LedControl(DIN, CLK, CS, 1); // 创建LedControl对象,用于控制MAX7219
// 数字的点阵图案(0到9)
byte digitPatterns[10][8] = { // 定义0到9的点阵图案
{96, 144, 144, 144, 144, 144, 144, 96}, // 0
{32, 96, 160, 32, 32, 32, 32, 240}, // 1
{240, 16, 16, 112, 128, 128, 128, 240}, // 2
{240, 16, 16, 240, 16, 16, 16, 240}, // 3
{16, 48, 80, 240, 16, 16, 16, 16}, // 4
{240, 128, 128, 240, 16, 16, 16, 240}, // 5
{240, 128, 128, 240, 144, 144, 144, 240}, // 6
{240, 16, 16, 16, 16, 16, 16, 16}, // 7
{240, 144, 144, 240, 144, 144, 144, 240}, // 8
{240, 144, 144, 240, 16, 16, 144, 240} // 9
};
volatile bool isButtonPressed = false; // 定义一个易失性布尔变量,用于存储按钮是否被按下的状态
void setup() { // 初始化函数,设置引脚模式和初始化MAX7219
// 初始化所有LED引脚为输出模式
for (int i = 0; i < 10; i++) {
pinMode(ledOutput[i], OUTPUT); // 将LED引脚设置为输出模式
}
// 初始化模拟输入引脚
pinMode(potentiometer, INPUT); // 将滑动变阻器引脚设置为输入模式
// 初始化MAX7219
ledCtrl.shutdown(0, false); // 启动MAX7219
ledCtrl.setIntensity(0, 15); // 设置亮度 (0最暗到15最亮)
ledCtrl.clearDisplay(0); // 清空显示
pinMode(2, INPUT_PULLUP); //引脚2设置为输入上拉模式
attachInterrupt(digitalPinToInterrupt(2), handleInterrupt, FALLING); // 当引脚2接收到下降沿时,调用handleInterrupt函数
}
void loop() { // 主循环函数,控制LED灯和点阵屏幕的显示
// 读取变阻器的值并映射为延迟时间
speed = analogRead(potentiometer); // 读取滑动变阻器的值
int delayDuration = map(speed, 0, 1023, 100, 20); // 将滑动变阻器的值映射为延迟时间
// 循环点亮每个LED,创造从中间向两边亮的效果
for (int i = 0; i < 5; i++) {
digitalWrite(ledOutput[4 - i], HIGH); // 从中间向左亮
digitalWrite(ledOutput[5 + i], HIGH); // 从中间向右亮
delay(delayDuration); // 延迟
digitalWrite(ledOutput[4 - i], LOW); // 熄灭LED
digitalWrite(ledOutput[5 + i], LOW); // 熄灭LED
}
// 循环点亮每个LED,创造从两边向中间亮的效果
for (int i = 4; i >= 0; i--) {
digitalWrite(ledOutput[4 - i], HIGH); // 从左向中间亮
digitalWrite(ledOutput[5 + i], HIGH); // 从右向中间亮
delay(delayDuration); // 延迟
digitalWrite(ledOutput[4 - i], LOW); // 熄灭LED
digitalWrite(ledOutput[5 + i], LOW); // 熄灭LED
}
// 计算电压值并显示在点阵屏幕上
float voltage = speed * (5.0 / 1023.0); // 计算电压值
showNumber(voltage); // 在点阵屏幕上显示电压值
if (isButtonPressed) { // 如果按钮被按下
while (1) { // 无限循环
if (digitalRead(2) == LOW) { // 如果引脚2的电平为低
delay(70); // 消抖
if (digitalRead(2) == LOW) { // 如果引脚2的电平仍为低
isButtonPressed = false; // 将按钮状态设置为未按下
break; // 跳出无限循环
}
}
}
}
}
// 在点阵屏幕上显示数字的函数
void showNumber(float num) {
int displayNum = round(num * 10); // 将电压值乘以10并四舍五入
if (displayNum < 0) displayNum = 0; // 如果显示值小于0,则设置为0
if (displayNum > 99) displayNum = 99; // 如果显示值大于99,则设置为99
int tens = displayNum / 10; // 计算十位数
int ones = displayNum % 10; // 计算个位数
// 为了创建滚动效果,我们将逐列更新显示
for (int col = 0; col < 8; col++) {
ledCtrl.clearDisplay(0); // 清空显示
// 显示十位数,从右向左滚动
for (int row = 0; row < 8; row++) {
byte rowData = digitPatterns[tens][row] << col; // 将十位数的点阵向左移动col列
ledCtrl.setRow(0, row, rowData); // 在点阵屏幕上显示每行的数据
}
delay(100); // 短暂延迟以创建滚动效果
}
// 显示个位数,从右向左滚动
for (int col = 0; col < 8; col++) {
ledCtrl.clearDisplay(0); // 清空显示
for (int row = 0; row < 8; row++) {
byte rowData = digitPatterns[ones][row] << col; // 将个位数的点阵向左移动col列
ledCtrl.setRow(0, row, rowData); // 在点阵屏幕上显示每行的数据
}
delay(100); // 短暂延迟以创建滚动效果
}
}
void handleInterrupt() { // 中断处理函数
isButtonPressed = true; // 当引脚2接收到下降沿时,将按钮状态设置为已按下
}