/*--------------------------------------------------------------------------1--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------本程序所引用库--------------------------------------------------------------------*/
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ILI9341.h> // Hardware-specific library for ILI9341
/*--------------------------------------------------------------------------2--------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------变量声明-----------------------------------------------------------------------*/
/******************************常量声明******************************/
#define Num_Rows 4 // 4行
#define Num_Cols 4 // 4列
#define Membrane_Debounce_Time 200 // 薄膜按键消抖时间
/******************************引脚声明******************************/
const int Row_Pins[Num_Rows] = { 14, 15, 16, 17 };
const int Col_Pins[Num_Cols] = { 18, 19, 20, 21 };
// 定义连接到TFT显示屏的引脚
const int TFT_CS = 10;
const int TFT_RST = 9;
const int TFT_DC = 53;
/******************************变量声明******************************/
// 为键盘上的每个位置赋值
const char Key_Map[Num_Rows][Num_Cols] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
int hours = 0;
int minutes = 0;
int seconds = 0;
int currentPosition = 0; // 0 - hours, 1 - minutes, 2 - seconds
bool settingTime = true;
/******************************对象声明******************************/
// 无
// 使用硬件SPI并指定CS/DC引脚
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
/*--------------------------------------------------------------------------3--------------------------------------------------------------------------*/
/*-------------------------------------------------------------------setup()程序初始化------------------------------------------------------------------*/
void setup() {
/******************************启动串口通讯******************************/
Serial.begin(9600); // 初始化串口通信,并设置波特率为9600
Serial.println("ILI9341 Test!");
// 初始化显示屏
tft.begin();
// 清屏为黑色
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
/******************************设置引脚模式******************************/
for (int row = 0; row < Num_Rows; row++) {
pinMode(Row_Pins[row], INPUT); // 设置 行 为 输入模式
digitalWrite(Row_Pins[row], HIGH); // 先设定为HIGH
}
for (int col = 0; col < Num_Cols; col++) {
pinMode(Col_Pins[col], OUTPUT); // 设置 列 为 输出模式
digitalWrite(Col_Pins[col], HIGH); // 先设定为HIGH
}
// 在屏幕上显示文本
tft.setCursor(10, 70);
tft.setTextSize(2);
tft.println("Please set time!");
displayTime();
displayIndicator();
while (settingTime) {
char key = getkey();
if (key != 0) {
Serial.println(key);
if (key == '#') {
settingTime = false;
continue;
} else if (key == '*') {
currentPosition++;
if (currentPosition > 2) {
currentPosition = 0;
}
displayIndicator();
continue;
}
int num = key - '0';
if (num >= 0 && num <= 9) {
if (currentPosition == 0) {
hours = (hours % 10) * 10 + num; // 最后两个数字
if (hours > 23) hours = 23;
} else if (currentPosition == 1) {
minutes = (minutes % 10) * 10 + num; // 最后两个数字
if (minutes > 59) minutes = 59;
} else if (currentPosition == 2) {
seconds = (seconds % 10) * 10 + num; // 最后两个数字
if (seconds > 59) seconds = 59;
}
displayTime();
}
}
}
displayTime();
// 清屏为黑色
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
}
/*--------------------------------------------------------------------------4--------------------------------------------------------------------------*/
/*-------------------------------------------------------------------loop()基础循环体-------------------------------------------------------------------*/
void loop() {
static unsigned long lastMillis = 0;
unsigned long currentMillis = millis();
if (currentMillis - lastMillis >= 1000) {
lastMillis = currentMillis;
// 每秒增加1秒
incrementTime();
displayTime();
}
}
/*--------------------------------------------------------------------------5--------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------函数定义-----------------------------------------------------------------------*/
/*
函数:得到4*3薄膜按键的对应字符
返回值:按钮按下对应的字符
*/
char getkey() {
char key = 0;
for (int col = 0; col < Num_Cols; col++) { // 遍历3列
digitalWrite(Col_Pins[col], LOW); // 将每一列变成LOW(列视为接地)
for (int row = 0; row < Num_Rows; row++) { // 每一列遍历4行
if (digitalRead(Row_Pins[row]) == LOW) { // 检测每一行是否有按钮按下,按下为LOW
delay(Membrane_Debounce_Time); // 防抖
while (digitalRead(Row_Pins[row]) == LOW) // 按着就保持为LOW,直到松手
;
key = Key_Map[row][col]; // 找到按钮按下的值
}
}
digitalWrite(Col_Pins[col], HIGH); // 将列变回HIGH
}
return key;
}
/*
函数:增加时间
*/
void incrementTime() {
seconds++;
if (seconds > 59) {
seconds = 0;
minutes++;
}
if (minutes > 59) {
minutes = 0;
hours++;
}
if (hours > 23) {
hours = 0;
}
}
/*
函数:显示时间
*/
void displayTime() {
// 格式化时间字符串
char timeStr[9];
sprintf(timeStr, "%02d:%02d:%02d", hours, minutes, seconds);
// 更新显示
tft.fillRect(20, 150, 220, 40, ILI9341_BLACK);
tft.setCursor(20, 150);
tft.setTextSize(4);
tft.println(timeStr);
}
/*
函数:显示指示标志
*/
void displayIndicator() {
// 清除之前的指示标志
tft.fillRect(20, 190, 220, 20, ILI9341_BLACK);
// 显示新的指示标志
tft.setCursor(20, 190);
tft.setTextSize(2);
if (currentPosition == 0) {
tft.println("Setting: Hours");
} else if (currentPosition == 1) {
tft.println("Setting: Minutes");
} else if (currentPosition == 2) {
tft.println("Setting: Seconds");
}
}