//#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <time.h>
#include <stdio.h>
// oled
// 定义oled 地址
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
// 开关
// 定义 LED 与 按键引脚
#define LED_PIN 5
#define BUTTON_PIN 4
// 定义 LED 逻辑值
int led_logic = 0;
// 判断 LED 的状态是否改变过
bool status = false;
// 数码管
// 定义位选线引脚
int seg_1 = 38;
int seg_2 = 41;
int seg_3 = 42;
int seg_4 = 48;
// 定义位选线数组
int seg_array[4] = {seg_1, seg_2, seg_3, seg_4};
// 定义段选线引脚;
int a = 39;
int b = 2;
int c = 0;
int d = 36;
int e = 37;
int f = 40;
int g = 45;
int dp = 35;
int com = 47;
int cln = 1;
// 定义段选线引脚数组
int led_array[8] = {a, b, c, d, e, f, g, dp};
// 定义共阴极数码管不同数字对应的逻辑电平的二维数组
int logic_array[10][10] = {
//a, b, c, d, e, f, g, dp
{1, 1, 1, 1, 1, 1, 0, 0}, // 0
{0, 1, 1, 0, 0, 0, 0, 0}, // 1
{1, 1, 0, 1, 1, 0, 1, 0}, // 2
{1, 1, 1, 1, 0, 0, 1, 0}, // 3
{0, 1, 1, 0, 0, 1, 1, 0}, // 4
{1, 0, 1, 1, 0, 1, 1, 0}, // 5
{1, 0, 1, 1, 1, 1, 1, 0}, // 6
{1, 1, 1, 0, 0, 0, 0, 0}, // 7
{1, 1, 1, 1, 1, 1, 1, 0}, // 8
{1, 1, 1, 1, 0, 1, 1, 0}, // 9
};
void setup()
{
Serial.begin(115200);
Serial.println("Hello, ESP32-S3!");
Wire.begin();
Wire.setClock(400000L);
setOled();
setTube();
setBtnAndLed();
}
void loop()
{
//execOled();
//execTube();
execBtnAndLed();
}
void setOled()
{
#if RST_PIN >= 0
oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0
}
void execOled()
{
time_t rawtime;
struct tm *info;
char buffer[80];
time( &rawtime );
info = localtime( &rawtime );
oled.setFont(System5x7);
//char curtime[] = strcat("time:", asctime(info));
char curtime[35], a[30];
strcpy(curtime, "Time:");
strcpy(a, asctime(info));
strcat(curtime, a);
oled.println(curtime);
Serial.println(curtime);
delay(1000);
}
void setBtnAndLed()
{
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLDOWN);
}
void execBtnAndLed()
{
// 按键消抖
if (digitalRead(BUTTON_PIN)) {
Serial.println("Press Buttn");
// 睡眠 10ms,如果依然为高电平,说明抖动已消失。
delay(10);
if (digitalRead(BUTTON_PIN) && !status)
{
led_logic = !led_logic;
digitalWrite(LED_PIN, led_logic);
// led 的状态发生了变化,即使持续按着按键,LED 的状态也不应该改变。
status = !status;
}
else if (!digitalRead(BUTTON_PIN))
{
status = false;
}
}
}
// 清屏函数
void clear() {
for (int i=0;i<4;i++) {
digitalWrite(seg_array[i], HIGH);
}
for (int i=0;i<8;i++) {
digitalWrite(led_array[i], LOW);
}
}
void setTube()
{
// 设置所有位选线引脚为输出模式,初始化所有位选线引脚为高电平
for (int i=0;i<4;i++)
{
pinMode(seg_array[i], OUTPUT);
digitalWrite(seg_array[i], HIGH);
}
// 设置所有段选线引脚为输出模式,初始化所有段选线引脚为低电平
for (int i=0;i<8;i++)
{
pinMode(led_array[i], OUTPUT);
digitalWrite(led_array[i], LOW);
}
}
void execTube()
{
for(int i=0;i<10000;i++)
{
display_4_number(i);
}
}
// 4 位数码管显示函数
void display_4_number(int number)
{
// 把输入的数字格式化为 4 位数的数组
if (number >= 10000) return;
// 定义格式化数组
int number_array[4];
// 使用循环获取格式化数组
for (int i=3;i>=0;i--)
{
number_array[i] = number % 10;
number /= 10;
}
// 显示数字
for (int i=0;i<4;i++)
{
int x = number_array[i];
// 清屏
clear();
// 把对应位选线的电平拉低
digitalWrite(seg_array[i], LOW);
// 显示数字
for (int k=0;k<8;k++) {
digitalWrite(led_array[k], logic_array[x][k]);
}
delay(25);
}
}