#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
// 引脚定义
#define TFT_DC 2 // LCD数据/命令控制引脚
#define TFT_CS 3 // LCD片选引脚
#define BUTTON_INC 6 // 增加按键(红色)
#define BUTTON_DEC 5 // 减少按键(蓝色)
#define BUTTON_RST 4 // 复位按键
#define BUTTON_A 7 // 货物A计数按键
#define BUTTON_B 8 // 货物B计数按键
#define BUTTON_C 9 // 货物C计数按键
#define BUTTON_D 10 // 货物D计数按键
#define PIN_MODE INPUT_PULLUP // 按键引脚模式(上拉输入)
// LED引脚定义
#define LED_A PA0 // A货物对应LED
#define LED_B PA1 // B货物对应LED
#define LED_C PA2 // C货物对应LED
#define LED_D PA3 // D货物对应LED
// 全局变量
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
byte buttonState[7]; // 七个按键的当前状态
byte lastButtonState[7]; // 七个按键的上一状态
const uint32_t DEBOUNCE_DELAY = 20; // 消抖延时(毫秒)
uint32_t lastDebounceTime[7] = {0}; // 各按键的最后检测时间
uint32_t lastUpdateTime = 0; // 上次更新显示的时间
const uint32_t UPDATE_INTERVAL = 20; // 显示更新最小间隔(毫秒)
// 显示相关变量
int count = 0; // 当前计数
int goodsCount[4] = {0}; // 四种货物的计数:A、B、C、D
const uint16_t TEXT_COLOR = ILI9341_WHITE; // 文本颜色
const uint16_t BG_COLOR = ILI9341_BLACK; // 背景颜色
const uint16_t ACCENT_COLOR = ILI9341_GREEN; // 强调色
const uint16_t GOODS_COLORS[4] = { // 四种货物的颜色
ILI9341_RED, ILI9341_BLUE,
ILI9341_YELLOW, ILI9341_MAGENTA
};
bool updateRequired = false; // 是否需要更新显示
// LED控制函数:点亮指定LED
void turnOnLED(int index) {
switch(index) {
case 0: digitalWrite(LED_A, HIGH); break;
case 1: digitalWrite(LED_B, HIGH); break;
case 2: digitalWrite(LED_C, HIGH); break;
case 3: digitalWrite(LED_D, HIGH); break;
}
}
// LED控制函数:熄灭所有LED
void turnOffAllLEDs() {
digitalWrite(LED_A, LOW);
digitalWrite(LED_B, LOW);
digitalWrite(LED_C, LOW);
digitalWrite(LED_D, LOW);
}
// 更新LCD显示(优化版:只更新变化的部分)
void updateDisplay() {
static int lastCount = count; // 记录上次的总计数
static int lastGoodsCount[4] = {0}; // 记录上次的货物计数
// 如果计数未变化且不是强制更新,则不执行任何操作
if (!updateRequired && count == lastCount) {
bool goodsChanged = false;
for (int i = 0; i < 4; i++) {
if (goodsCount[i] != lastGoodsCount[i]) {
goodsChanged = true;
break;
}
}
if (!goodsChanged) return;
}
// 清屏(只在首次调用或复位时执行)
if (updateRequired) {
tft.fillScreen(BG_COLOR);
// 绘制标题
tft.setTextColor(TEXT_COLOR);
tft.setTextSize(2);
tft.setCursor(20, 20);
tft.println("货物计数器");
// 绘制按键说明 - 原有的三个按键
tft.setTextColor(TEXT_COLOR);
tft.setTextSize(2);
tft.setCursor(20, 160);
tft.print("+");
tft.setCursor(20, 190);
tft.print("-");
tft.setCursor(20, 220);
tft.print("R");
tft.setCursor(50, 160);
tft.print("增加(红)");
tft.setCursor(50, 190);
tft.print("减少(蓝)");
tft.setCursor(50, 220);
tft.print("复位");
// 绘制货物类型说明
tft.setCursor(20, 250);
tft.setTextColor(GOODS_COLORS[0]);
tft.print("A");
tft.setTextColor(GOODS_COLORS[1]);
tft.print(" B");
tft.setTextColor(GOODS_COLORS[2]);
tft.print(" C");
tft.setTextColor(GOODS_COLORS[3]);
tft.print(" D");
updateRequired = false;
}
// 绘制当前计数(大字体)
tft.setTextColor(ACCENT_COLOR);
tft.setTextSize(5);
// 只清除数字区域,不影响其他部分
tft.fillRect(80, 80, 160, 50, BG_COLOR);
tft.setCursor(80, 80);
tft.print(count);
// 绘制货物计数
tft.setTextSize(3);
for (int i = 0; i < 4; i++) {
// 清除之前的显示
tft.fillRect(80, 140 + i*30, 160, 30, BG_COLOR);
// 绘制新的计数
tft.setTextColor(GOODS_COLORS[i]);
tft.setCursor(180, 140 + i*30);
tft.print((char)('A' + i));
tft.print(": ");
tft.print(goodsCount[i]);
}
// 更新记录值
lastCount = count;
for (int i = 0; i < 4; i++) {
lastGoodsCount[i] = goodsCount[i];
}
}
// 按键按下的视觉反馈
void flashFeedback() {
tft.fillScreen(ILI9341_DARKGREY);
delay(10); // 减少延迟时间
updateDisplay();
}
// 初始化
void setup() {
Serial.begin(115200);
// 初始化按键引脚
pinMode(BUTTON_INC, PIN_MODE);
pinMode(BUTTON_DEC, PIN_MODE);
pinMode(BUTTON_RST, PIN_MODE);
pinMode(BUTTON_A, PIN_MODE);
pinMode(BUTTON_B, PIN_MODE);
pinMode(BUTTON_C, PIN_MODE);
pinMode(BUTTON_D, PIN_MODE);
// 初始化LED引脚为输出模式
pinMode(LED_A, OUTPUT);
pinMode(LED_B, OUTPUT);
pinMode(LED_C, OUTPUT);
pinMode(LED_D, OUTPUT);
// 初始状态熄灭所有LED
turnOffAllLEDs();
// 初始化LCD
tft.begin();
tft.setRotation(3); // 竖屏显示
// 初始化按键状态
for (int i = 0; i < 7; i++) {
buttonState[i] = (PIN_MODE == INPUT_PULLUP);
lastButtonState[i] = buttonState[i];
}
// 显示初始界面
updateRequired = true;
updateDisplay();
}
// 主循环
void loop() {
// 扫描按键状态
byte currentStates[7] = {
digitalRead(BUTTON_INC),
digitalRead(BUTTON_DEC),
digitalRead(BUTTON_RST),
digitalRead(BUTTON_A),
digitalRead(BUTTON_B),
digitalRead(BUTTON_C),
digitalRead(BUTTON_D)
};
// 默认先熄灭所有LED,只在按键按下时点亮对应LED
turnOffAllLEDs();
for (int i = 0; i < 7; i++) {
// 检测状态变化
if (currentStates[i] != lastButtonState[i]) {
lastDebounceTime[i] = millis();
}
// 消抖处理
if ((millis() - lastDebounceTime[i]) > DEBOUNCE_DELAY) {
// 确认状态变化稳定
if (currentStates[i] != buttonState[i]) {
buttonState[i] = currentStates[i];
// 处理按键按下事件(上拉输入模式下,低电平表示按下)
if (buttonState[i] == LOW) {
bool needUpdate = true;
switch (i) {
case 0: // 增加按键(红色)
count++;
break;
case 1: // 减少按键(蓝色)
count--;
break;
case 2: // 复位按键
count = 0;
for (int j = 0; j < 4; j++) {
goodsCount[j] = 0;
}
updateRequired = true; // 强制全屏更新
break;
case 3: // 货物A按键
goodsCount[0]++;
count++;
turnOnLED(0); // 点亮A对应的LED
break;
case 4: // 货物B按键
goodsCount[1]++;
count++;
turnOnLED(1); // 点亮B对应的LED
break;
case 5: // 货物C按键
goodsCount[2]++;
count++;
turnOnLED(2); // 点亮C对应的LED
break;
case 6: // 货物D按键
goodsCount[3]++;
count++;
turnOnLED(3); // 点亮D对应的LED
break;
default:
needUpdate = false;
break;
}
// 如果有操作,提供视觉反馈并标记需要更新
if (needUpdate) {
flashFeedback();
updateRequired = true;
}
}
}
}
lastButtonState[i] = currentStates[i];
}
// 控制显示更新频率,避免过于频繁
if (updateRequired && (millis() - lastUpdateTime) > UPDATE_INTERVAL) {
updateDisplay();
lastUpdateTime = millis();
}
}Loading
st-nucleo-c031c6
st-nucleo-c031c6