使用Arduino控制 OLED 显示屏ili9341 ,在屏幕上显示一个尽可能大的时钟表盘,包含12个刻度和对应的1~12数字,以及一个秒针。秒针最初向上指向数字12。 Arduino 上连接1个按钮。按钮第一次按下,秒表开始计时,秒针 要准确地转动。按钮第二次按下,秒针暂停,在时钟表盘旁边用数字显示过 去了多少秒(精确到0.01秒)。按钮第三次按下,秒针接着继续转动。第四 次按下,秒针再次暂停,在时钟表盘旁边换行用数字显示过去了多少秒(精 确到0.01秒) 。第五次按下,同第三次· ·如此重复。使用定时器进行准确的计时。 Arduino 上再加1个按钮,此按钮按 下时,秒针归零。全部重新开始。
时间: 2023-12-29 12:03:45 浏览: 237
以下是基于Arduino控制OLED显示屏ili9341的示例代码,实现一个时钟表盘和秒针,以及计时和控制按钮的功能:
```c++
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <SPI.h>
// OLED屏幕引脚定义
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
// OLED屏幕对象定义
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// 按钮引脚定义
#define BTN_PIN 7
// 计时器变量定义
unsigned long start_time = 0;
unsigned long elapsed_time = 0;
bool is_running = false;
// 时钟表盘参数定义
const int center_x = 120;
const int center_y = 120;
const int radius = 100;
const int digit_radius = 80;
const int digit_size = 4;
const int digit_spacing = 10;
const int tick_length = 10;
const int tick_spacing = 5;
const int tick_width = 2;
const int sec_hand_length = 80;
const int sec_hand_width = 5;
// 初始化OLED屏幕
void setup()
{
Serial.begin(9600);
tft.begin();
tft.setRotation(3);
tft.fillScreen(ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_WHITE);
tft.println("Clock");
pinMode(BTN_PIN, INPUT_PULLUP);
}
// 绘制时钟表盘
void draw_clock()
{
tft.fillScreen(ILI9341_BLACK);
// 绘制刻度和数字
for (int i = 1; i <= 12; i++)
{
float angle = (i - 3) * 30.0 * PI / 180.0;
int x = center_x + cos(angle) * digit_radius - digit_size * 3;
int y = center_y + sin(angle) * digit_radius - digit_size * 4;
tft.setCursor(x, y);
tft.print(i);
x = center_x + cos(angle) * (radius - tick_length - tick_spacing) - tick_width / 2;
y = center_y + sin(angle) * (radius - tick_length - tick_spacing) - tick_width / 2;
tft.fillRect(x, y, tick_width, tick_length, ILI9341_WHITE);
}
// 绘制秒针
float angle = (elapsed_time % 60000) / 1000.0 * 6.0 * PI / 180.0;
int x = center_x + cos(angle) * sec_hand_length - sec_hand_width / 2;
int y = center_y - sin(angle) * sec_hand_length - sec_hand_width / 2;
tft.fillRect(center_x - sec_hand_width / 2, center_y - sec_hand_length, sec_hand_width, sec_hand_length, ILI9341_RED);
tft.fillRect(x, y, sec_hand_width, sec_hand_length, ILI9341_RED);
}
// 计时器中断处理函数
void timer_isr()
{
elapsed_time = millis() - start_time;
}
// 开始计时
void start_timer()
{
start_time = millis();
elapsed_time = 0;
is_running = true;
attachInterrupt(0, timer_isr, RISING);
}
// 停止计时
void stop_timer()
{
detachInterrupt(0);
is_running = false;
}
// 归零计时器
void reset_timer()
{
stop_timer();
elapsed_time = 0;
draw_clock();
}
// 更新计时器
void update_timer()
{
if (is_running)
{
draw_clock();
}
else
{
tft.setCursor(0, digit_radius * 2 + digit_spacing);
tft.print("Elapsed time: ");
tft.print(elapsed_time / 1000);
tft.print(".");
tft.print((elapsed_time % 1000) / 10);
if (digitalRead(BTN_PIN) == LOW)
{
delay(50);
while (digitalRead(BTN_PIN) == LOW)
{
// 等待按钮释放
}
tft.println();
if (is_running)
{
stop_timer();
}
else
{
start_timer();
}
}
}
}
// 主循环
void loop()
{
update_timer();
if (digitalRead(BTN_PIN) == LOW)
{
delay(50);
while (digitalRead(BTN_PIN) == LOW)
{
// 等待按钮释放
}
reset_timer();
}
}
```
在上述代码中,我们使用了Adafruit_ILI9341库来控制OLED显示屏,通过绘制图形和文字来实现时钟表盘和计时器的显示。我们还使用了Arduino的计时器中断和按钮输入来实现计时和控制功能。在主循环中,我们不断更新计时器的显示,并检测按钮输入来进行相应的操作。
阅读全文