赞
踩
本文主要记录自己在VSCode+PlatformIO平台下学习ESP32-S的TFT_eSPI库时对库自带例程的学习。本次学习的第一个项目是TFT_Clock_Digital。本人作为一名单片机爱好者未写过自己的代码,仅仅在业余时间学习此类知识,希望通过阅读别人的代码提升自己的代码能力,难免出现各种错误,请大家批评指正。
TFT_Clock_Digital是一个简单的时钟例程,使用TFT屏幕展示时间。该例程能够更新时间但日期只能显示编译时的日期,没有更新功能。
例程更新时间的方式是通过编译时获取“TIME”并累加millis()函数计算时间。作者提示如果需要更加精确的时间,可以使用RTClib库。
#include <TFT_eSPI.h>
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI(); //初始化TFT_eSPI对象
uint32_t targetTime = 0; //更新时间标志(本程序中为1秒更新)
byte omm = 99;//时间的背景阴影的刷新标志
bool initial = 1;//代码段初始化标志
byte xcolon = 0;//xpos的中间储存变量
unsigned int colour = 0;
上述代码建立了各种后续代码中需要的全局变量,标志等。
static uint8_t conv2d(const char* p) {
uint8_t v = 0;
if ('0' <= *p && *p <= '9')//比较字符的ASCII码是否在0和9之间
v = *p - '0';//转化为数字
return 10 * v + *++p - '0';//把两个字符转化为两位数字
}
uint8_t hh=conv2d(__TIME__), mm=conv2d(__TIME__+3), ss=conv2d(__TIME__+6); //从编译时间中分别获取小时分钟秒
该函数实现了将字符串中的前两位取出并转换为数字的功能,其中char*为字符串指针,需要保证输入的字符串为0-99之间的字符才能按照预想输出相应数字,此处输入的是__TIME__,TIME+3,TIME+6。__TIME__是内置宏定义,其意义为在源文件中插入当前编译时间。函数取出的数值为xx:xx:xx这个字符串的零一位,三四位,六七位。
void setup(void) {
tft.init();
tft.setRotation(1);//旋转90度
tft.fillScreen(TFT_BLACK);//填满黑色
tft.setTextColor(TFT_YELLOW, TFT_BLACK); // 文本颜色为黄,背景为黑
targetTime = millis() + 1000; //初始化计时,单位为毫秒
}
初始化程序实现了调用了实例的函数,完成了相应的功能。
if (targetTime < millis()) {//每秒
targetTime = millis()+1000;
ss++; // Advance second
if (ss==60) {
ss=0;
omm = mm;//刷新标志,每分钟更新一次
mm++; // Advance minute
if(mm>59) {
mm=0;
hh++; // Advance hour
if (hh>23) {
hh=0;
}
}
}//更新时间的内容
首先判断targettime的值,其值在初始化时被赋值为millis()+1000,判断的目的是为了保证每一秒更新一次输出。当millis()函数计数达到上限,时钟就会停止更新。剩下的语句更新时间。
if (ss==0 || initial) {//每一分钟更新一次
initial = 0;
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.setCursor (8, 52);
tft.print(__DATE__); // This uses the standard ADAFruit small font
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.drawCentreString("It is windy",120,48,2); // Next size up font 2
//tft.setTextColor(0xF81F, TFT_BLACK); // Pink
//tft.drawCentreString("12.34",80,100,6); // Large font 6 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 . : a p m
}
在第一次更新或每一分钟开始,都会更新当前日期(绿色)和字符串“It is windy”(蓝色)。
// Update digital time更新显示 byte xpos = 6; byte ypos = 0; if (omm != mm) { // Only redraw every minute to minimise flicker // Uncomment ONE of the next 2 lines, using the ghost image demonstrates text overlay as time is drawn over it tft.setTextColor(0x39C4, TFT_BLACK); // Leave a 7 segment ghost image, comment out next line! //tft.setTextColor(TFT_BLACK, TFT_BLACK); // Set font colour to black to wipe image // Font 7 is to show a pseudo 7 segment display. // Font 7 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : . tft.drawString("88:88",xpos,ypos,7); // Overwrite the text to clear it tft.setTextColor(0xFBE0); // Orange omm = mm;//omm此处作为刷新标志,每分钟刷新分钟和小时这两个数 if (hh<10) xpos+= tft.drawChar('0',xpos,ypos,7);//多绘制一个零 xpos+= tft.drawNumber(hh,xpos,ypos,7);//写小时,并返回位置保存在xpos xcolon=xpos;//记录小时后面的坐标位置 xpos+= tft.drawChar(':',xpos,ypos,7);//写冒号 if (mm<10) xpos+= tft.drawChar('0',xpos,ypos,7);//多绘制一个零 tft.drawNumber(mm,xpos,ypos,7);//分钟 }
在这个程序段中,会显示整个程序中最主要的部分——电子时钟。电子时钟前景数字(橘色)和阴影(灰色)组成,字体为7号字体(七段数码管样式),程序通过TFT库的绘制函数将每个部分分别绘制出来。
if (ss%2) { // Flash the colon每两秒刷新冒号 tft.setTextColor(0x39C4, TFT_BLACK); xpos+= tft.drawChar(':',xcolon,ypos,7); tft.setTextColor(0xFBE0, TFT_BLACK); } else { tft.drawChar(':',xcolon,ypos,7); colour = random(0xFFFF); // Erase the old text with a rectangle, the disadvantage of this method is increased display flicker tft.fillRect (0, 64, 160, 20, TFT_BLACK); tft.setTextColor(colour); tft.drawRightString("Colour",75,64,4); // Right justified string drawing to x position 75 String scolour = String(colour,HEX); scolour.toUpperCase();//小写变大写 char buffer[20]; scolour.toCharArray(buffer,20); tft.drawString(buffer,82,64,4); //tft.drawString(scolour,82,64,4);//这样也能实现效果,但时常花屏和画面出错。作者用的是buffer数组实现 }
上述程序段完成偶数秒绘制阴影颜色(0x39C4)的冒号,奇数秒绘制文本颜色(0xFBE0)的冒号,同时绘制随机颜色的字符串Colour,并输出Colour颜色的十六进制数值。在程序中通过实例化一个String对象获取字符串,转换为大写,储存在了数组中,最后绘制在了屏幕上。经试验,drawString()函数也能通过直接输出String对象实现字符输出,此处创建一个数组暂未知作者用意。
本文试图通过详细阅读TFT_eSPI库作者提供的例程学校库的用法,并加以记录,希望能在学习库的过程中借鉴其编程方法,提高自身编程技巧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。