【雕爷学编程】Arduino动手做(153)---2.4寸TFT
37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百五十三:2.4寸TFT液晶触摸屏 彩屏模块 可直插UNO R3 Mega2560开发板
![](https://img.haomeiwen.com/i17690760/dfaab93a980e27b4.jpg)
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百五十三:2.4寸TFT液晶触摸屏 彩屏模块 TFT-LCD 高清真彩显示屏
项目之十二:读取MCUFRIEND UNO shield上的寄存器16位或8位值序列
实验开源代码:
/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百五十三:2.4寸TFT液晶触摸屏 彩屏模块 TFT-LCD 高清真彩显示屏
项目之十二:读取MCUFRIEND UNO shield上的寄存器16位或8位值序列
模块直插,引脚用法如下:
LCD_CS LCD_CD LCD_WR LCD_RD LCD_RST SD_SS SD_DI SD_DO SD_SCK
Arduino Uno A3 A2 A1 A0 A4 10 11 12 13
LCD_D0 LCD_D1 LCD_D2 LCD_D3 LCD_D4 LCD_D5 LCD_D6 LCD_D7
Arduino Uno 8 9 2 3 4 5 6 7
*/
//Arduino UNO或Mega 2560作为扩展
#define LCD_RST A4
#define LCD_CS A3
#define LCD_RS A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_D0 8
#define LCD_D1 9
#define LCD_D2 2
#define LCD_D3 3
#define LCD_D4 4
#define LCD_D5 5
#define LCD_D6 6
#define LCD_D7 7
void setup(){
Serial.begin(9600);
while (!Serial) ;
Serial.println("Read Registers on MCUFRIEND UNO shield");
Serial.println("controllers either read as single 16-bit");
Serial.println("e.g. the ID is at readReg(0)");
Serial.println("or as a sequence of 8-bit values");
Serial.println("in special locations (first is dummy)");
Serial.println("");
lcdInit();
lcdReset(); //ensures that controller is in default state
// for (uint16_t i = 0; i < 256; i++) readReg(i, 7, "f.k");
readReg(0x00, 2, "ID: ILI9320, ILI9325, ILI9335, ...");
readReg(0x04, 4, "Manufacturer ID");
readReg(0x09, 5, "Status Register");
readReg(0x0A, 2, "Get Power Mode");
readReg(0x0C, 2, "Get Pixel Format");
readReg(0x61, 2, "RDID1 HX8347-G");
readReg(0x62, 2, "RDID2 HX8347-G");
readReg(0x63, 2, "RDID3 HX8347-G");
readReg(0x64, 2, "RDID1 HX8347-A");
readReg(0x65, 2, "RDID2 HX8347-A");
readReg(0x66, 2, "RDID3 HX8347-A");
readReg(0x67, 2, "RDID Himax HX8347-A");
readReg(0x70, 2, "Panel Himax HX8347-A");
readReg(0xA1, 5, "RD_DDB SSD1963");
readReg(0xB0, 2, "RGB Interface Signal Control");
readReg(0xB4, 2, "Inversion Control");
readReg(0xB6, 5, "Display Control");
readReg(0xB7, 2, "Entry Mode Set");
readReg(0xBF, 6, "ILI9481, HX8357-B");
readReg(0xC0, 9, "Panel Control");
readReg(0xC8, 13, "GAMMA");
readReg(0xCC, 2, "Panel Control");
readReg(0xD0, 3, "Power Control");
readReg(0xD2, 5, "NVM Read");
readReg(0xD3, 4, "ILI9341, ILI9488");
readReg(0xD4, 4, "Novatek ID");
readReg(0xDA, 2, "RDID1");
readReg(0xDB, 2, "RDID2");
readReg(0xDC, 2, "RDID3");
readReg(0xE0, 16, "GAMMA-P");
readReg(0xE1, 16, "GAMMA-N");
readReg(0xEF, 6, "ILI9327");
readReg(0xF2, 12, "Adjust Control 2");
readReg(0xF6, 4, "Interface Control");
}
void loop() {
}
void printhex(uint8_t val){
if (val < 0x10) Serial.print("0");
Serial.print(val, HEX);
}
void readReg(uint16_t reg, uint8_t n, const char *msg){
uint8_t val8;
lcdReset();
lcdSetWriteDir();
lcdWriteCommand(0xB0); //Command Access Protect
lcdWriteData(0x00); //looks wrong
/*
lcdWriteCommand(0xF6);
lcdWriteData(0x01);
lcdWriteData(0x01);
lcdWriteData(0x03);
*/
lcdWriteCommand(reg);
Serial.print("reg(0x");
printhex(reg >> 8);
printhex(reg);
Serial.print(")");
lcdSetReadDir();
while (n--) {
val8 = lcdReadData8();
Serial.print(" ");
printhex(val8);
}
lcdSetWriteDir();
Serial.print("\t");
Serial.println(msg);
}
void lcdInit(){
pinMode(LCD_CS, OUTPUT);
digitalWrite(LCD_CS, HIGH);
pinMode(LCD_RS, OUTPUT);
digitalWrite(LCD_RS, HIGH);
pinMode(LCD_WR, OUTPUT);
digitalWrite(LCD_WR, HIGH);
pinMode(LCD_RD, OUTPUT);
digitalWrite(LCD_RD, HIGH);
pinMode(LCD_RST, OUTPUT);
digitalWrite(LCD_RST, HIGH);
}
void lcdReset(){
digitalWrite(LCD_RST, LOW);
delay(2);
digitalWrite(LCD_RST, HIGH);
delay(10); //允许控制器重新启动
}
void lcdWrite8(uint16_t data){
digitalWrite(LCD_D0, data & 1);
digitalWrite(LCD_D1, (data & 2) >> 1);
digitalWrite(LCD_D2, (data & 4) >> 2);
digitalWrite(LCD_D3, (data & 8) >> 3);
digitalWrite(LCD_D4, (data & 16) >> 4);
digitalWrite(LCD_D5, (data & 32) >> 5);
digitalWrite(LCD_D6, (data & 64) >> 6);
digitalWrite(LCD_D7, (data & 128) >> 7);
}
uint16_t lcdRead8(){
uint16_t result = digitalRead(LCD_D7);
result <<= 1;
result |= digitalRead(LCD_D6);
result <<= 1;
result |= digitalRead(LCD_D5);
result <<= 1;
result |= digitalRead(LCD_D4);
result <<= 1;
result |= digitalRead(LCD_D3);
result <<= 1;
result |= digitalRead(LCD_D2);
result <<= 1;
result |= digitalRead(LCD_D1);
result <<= 1;
result |= digitalRead(LCD_D0);
return result;
}
void lcdSetWriteDir(){
pinMode(LCD_D0, OUTPUT);
pinMode(LCD_D1, OUTPUT);
pinMode(LCD_D2, OUTPUT);
pinMode(LCD_D3, OUTPUT);
pinMode(LCD_D4, OUTPUT);
pinMode(LCD_D5, OUTPUT);
pinMode(LCD_D6, OUTPUT);
pinMode(LCD_D7, OUTPUT);
}
void lcdSetReadDir(){
pinMode(LCD_D0, INPUT);
pinMode(LCD_D1, INPUT);
pinMode(LCD_D2, INPUT);
pinMode(LCD_D3, INPUT);
pinMode(LCD_D4, INPUT);
pinMode(LCD_D5, INPUT);
pinMode(LCD_D6, INPUT);
pinMode(LCD_D7, INPUT);
}
void lcdWriteData(uint16_t data){
lcdSetWriteDir();
digitalWrite(LCD_CS, LOW);
digitalWrite(LCD_RS, HIGH);
digitalWrite(LCD_RD, HIGH);
digitalWrite(LCD_WR, HIGH);
lcdWrite8(data >> 8);
digitalWrite(LCD_WR, LOW);
delayMicroseconds(10);
digitalWrite(LCD_WR, HIGH);
lcdWrite8(data);
digitalWrite(LCD_WR, LOW);
delayMicroseconds(10);
digitalWrite(LCD_WR, HIGH);
digitalWrite(LCD_CS, HIGH);
}
void lcdWriteCommand(uint16_t command){
lcdSetWriteDir();
digitalWrite(LCD_CS, LOW);
digitalWrite(LCD_RS, LOW);
digitalWrite(LCD_RD, HIGH);
digitalWrite(LCD_WR, HIGH);
lcdWrite8(command >> 8);
digitalWrite(LCD_WR, LOW);
delayMicroseconds(10);
digitalWrite(LCD_WR, HIGH);
lcdWrite8(command);
digitalWrite(LCD_WR, LOW);
delayMicroseconds(10);
digitalWrite(LCD_WR, HIGH);
digitalWrite(LCD_CS, HIGH);
}
uint8_t lcdReadData8(){
uint8_t result;
lcdSetReadDir();
digitalWrite(LCD_CS, LOW);
digitalWrite(LCD_RS, HIGH);
digitalWrite(LCD_RD, HIGH);
digitalWrite(LCD_WR, HIGH);
digitalWrite(LCD_RD, LOW);
delayMicroseconds(10);
result = lcdRead8();
digitalWrite(LCD_RD, HIGH);
delayMicroseconds(10);
return result;
}
uint16_t lcdReadData16(){
uint16_t result;
result = lcdReadData8() << 8;
result |= lcdReadData8();
return result;
}
void lcdWriteRegister(uint16_t addr, uint16_t data){
lcdWriteCommand(addr);
lcdWriteData(data);
}
实验串口返回情况
![](https://img.haomeiwen.com/i17690760/424d692008893d71.jpg)
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百五十三:2.4寸TFT液晶触摸屏 彩屏模块 TFT-LCD 高清真彩显示屏
项目十三:诊断TFT是否支持此控制器,并换背景四面显示字符串
实验开源代码
/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百五十三:2.4寸TFT液晶触摸屏 彩屏模块 TFT-LCD 高清真彩显示屏
项目十三:诊断TFT是否支持此控制器,并换背景四面显示字符串
模块直插,引脚用法如下:
LCD_CS LCD_CD LCD_WR LCD_RD LCD_RST SD_SS SD_DI SD_DO SD_SCK
Arduino Uno A3 A2 A1 A0 A4 10 11 12 13
LCD_D0 LCD_D1 LCD_D2 LCD_D3 LCD_D4 LCD_D5 LCD_D6 LCD_D7
Arduino Uno 8 9 2 3 4 5 6 7
*/
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
// 为一些常见的16位颜色值指定可读的名称
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define GRAY 0x8410
uint16_t version = MCUFRIEND_KBV_H_;
void setup() {
Serial.begin(9600);
if (!Serial) delay(3000); //给 Leonardo多留点时间
uint16_t ID = tft.readID();
Serial.println(F("Diagnose whether this controller is supported"));
Serial.println(F("There are FAQs in extras/mcufriend_how_to.txt"));
Serial.println(F(""));
Serial.print(F("tft.readID() finds: ID = 0x"));
Serial.println(ID, HEX);
Serial.println(F(""));
Serial.print(F("MCUFRIEND_kbv version: "));
Serial.print(version / 100);
Serial.print(F("."));
Serial.print((version / 10) % 10);
Serial.print(F("."));
Serial.println(version % 10);
Serial.println(F(""));
if (ID == 0x0404) {
Serial.println(F("Probably a write-only Mega2560 Shield"));
Serial.println(F("#define USE_SPECIAL in mcufriend_shield.h"));
Serial.println(F("#define appropriate SPECIAL in mcufriend_special.h"));
Serial.println(F("e.g. USE_MEGA_16BIT_SHIELD"));
Serial.println(F("e.g. USE_MEGA_8BIT_SHIELD"));
Serial.println(F("Hint. A Mega2560 Shield has a 18x2 male header"));
Serial.println(F("Often a row of resistor-packs near the 18x2"));
Serial.println(F("RP1-RP7 implies 16-bit but it might be 8-bit"));
Serial.println(F("RP1-RP4 or RP1-RP5 can only be 8-bit"));
}
if (ID == 0xD3D3) {
uint16_t guess_ID = 0x9481; // write-only shield
Serial.println(F("Probably a write-only Mega2560 Shield"));
Serial.print(F("Try to force ID = 0x"));
Serial.println(guess_ID, HEX);
tft.begin(guess_ID);
}
else tft.begin(ID);
Serial.println(F(""));
if (tft.width() == 0) {
Serial.println(F("This ID is not supported"));
Serial.println(F("look up ID in extras/mcufriend_how_to.txt"));
Serial.println(F("you may need to edit MCUFRIEND_kbv.cpp"));
Serial.println(F("to enable support for this ID"));
Serial.println(F("e.g. #define SUPPORT_8347D"));
Serial.println(F(""));
Serial.println(F("New controllers appear on Ebay often"));
Serial.println(F("If your ID is not supported"));
Serial.println(F("run LCD_ID_readreg.ino from examples/"));
Serial.println(F("Copy-Paste the output from the Serial Terminal"));
Serial.println(F("to a message in Displays topic on Arduino Forum"));
Serial.println(F("or to Issues on GitHub"));
Serial.println(F(""));
Serial.println(F("Note that OPEN-SMART boards have diff pinout"));
Serial.println(F("Edit the pin defines in LCD_ID_readreg to match"));
Serial.println(F("Edit mcufiend_shield.h for USE_SPECIAL"));
Serial.println(F("Edit mcufiend_special.h for USE_OPENSMART_SHIELD_PINOUT"));
while (1); //休止
}
else {
Serial.print(F("PORTRAIT is "));
Serial.print(tft.width());
Serial.print(F(" x "));
Serial.println(tft.height());
Serial.println(F(""));
Serial.println(F("Run the examples/graphictest_kbv sketch"));
Serial.println(F("All colours, text, directions, rotations, scrolls"));
Serial.println(F("should work. If there is a problem, make notes on paper"));
Serial.println(F("Post accurate description of problem to Forum"));
Serial.println(F("Or post a link to a video (or photos)"));
Serial.println(F(""));
Serial.println(F("I rely on good information from remote users"));
}
}
void loop() {
static uint8_t aspect = 0;
const char *aspectname[] = {
"PORTRAIT", "LANDSCAPE", "PORTRAIT_REV", "LANDSCAPE_REV"
};
const char *colorname[] = { "BLUE", "GREEN", "RED", "GRAY" };
uint16_t colormask[] = { BLUE, GREEN, RED, GRAY };
uint16_t ID = tft.readID(); //
tft.setRotation(aspect);
int width = tft.width();
int height = tft.height();
tft.fillScreen(colormask[aspect]);
tft.drawRect(0, 0, width, height, WHITE);
tft.drawRect(32, 32, width - 64, height - 64, WHITE);
tft.setTextSize(2);
tft.setTextColor(BLACK);
tft.setCursor(40, 40);
tft.print("ID=0x");
tft.print(ID, HEX);
if (ID == 0xD3D3) tft.print(" w/o");
tft.setCursor(40, 70);
tft.print(aspectname[aspect]);
tft.setCursor(40, 100);
tft.print(width);
tft.print(" x ");
tft.print(height);
tft.setTextColor(WHITE);
tft.setCursor(40, 130);
tft.print(colorname[aspect]);
tft.setCursor(40, 160);
tft.setTextSize(1);
tft.print("MCUFRIEND_KBV_H_ = ");
tft.print(version);
if (++aspect > 3) aspect = 0;
delay(800);
}
实验串口返回情况
![](https://img.haomeiwen.com/i17690760/6a4bd4cbe76576f1.jpg)
Arduino实验场景图
![](https://img.haomeiwen.com/i17690760/b7945275ed919183.gif)
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百五十三:2.4寸TFT液晶触摸屏 彩屏模块 TFT-LCD 高清真彩显示屏
项目十四:绘制位图8张
实验开源代码
/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百五十三:2.4寸TFT液晶触摸屏 彩屏模块 TFT-LCD 高清真彩显示屏
项目十四:绘制位图8张
模块直插,引脚用法如下:
LCD_CS LCD_CD LCD_WR LCD_RD LCD_RST SD_SS SD_DI SD_DO SD_SCK
Arduino Uno A3 A2 A1 A0 A4 10 11 12 13
LCD_D0 LCD_D1 LCD_D2 LCD_D3 LCD_D4 LCD_D5 LCD_D6 LCD_D7
Arduino Uno 8 9 2 3 4 5 6 7
*/
#include "MCUFRIEND_kbv.h"
MCUFRIEND_kbv tft;
#define LOWFLASH (defined(__AVR_ATmega328P__) && defined(MCUFRIEND_KBV_H_))
#include "bitmap_mono.h"
#include "bitmap_RGB.h"
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define GREY 0x8410
#define ORANGE 0xE880
void setup() {
Serial.begin(9600);
uint16_t ID = tft.readID();
Serial.print(F("ID = 0x"));
Serial.println(ID, HEX);
Serial.println(F("GFX drawBitmap() plots one mono pixel at a time"));
Serial.println(F("it defaults to transparent plotting"));
Serial.println(F("unless you specify foreground and background colours"));
Serial.println(F("it can plot a monochrome bitmap from Flash or SRAM"));
Serial.println(F(""));
Serial.println(F("GFX drawGrayscaleBitmap() is not relevant for OLED, TFT"));
Serial.println(F("GFX drawRGBBitmap() plots one colour pixel at a time"));
Serial.println(F("from Flash or SRAM and with a monochrome transparent bitmask"));
Serial.println(F(""));
Serial.println(F("Using the hardware pushColors() methods is faster"));
Serial.println(F("pushColors() expects uint16 array in SRAM"));
Serial.println(F("for any runtime generated images"));
Serial.println(F("but it expects uint8_t array of serialised bytes in Flash"));
Serial.println(F(""));
Serial.println(F("Colour TFTs are natively big-endian"));
Serial.println(F("Many microcontrollers and Tools are little-endian"));
Serial.println(F("you can use the optional argument to select big-end"));
tft.begin(ID);
// invertmap(betty_1_bmp + 62, 8960);
// while (1);
}
// GFX drawBitmap() expects each row to be on 8-bit boundary. i.e. pad = 7
// Mono BMP rows are on 32-bit boundary. i.e. pad = 31, rows are in RVS order.
// FreeFont bitmaps have no padding. i.e. pad = 0. e.g. 5x4 bitmap is in 3 bytes
void showbgd(int x, int y, const uint8_t *bmp, int w, int h, uint16_t color, uint16_t bg, uint8_t pad = 7) {
int yy, xx;
uint8_t first = 1, RVS = pad & 0x80;
uint16_t pixel;
pad &= 31;
uint16_t wid = (w + pad) & ~pad; //每行位数
tft.setAddrWindow(x, y, x + w - 1, y + h - 1);
for (yy = 0; yy < h; yy++) {
uint32_t ofs = (RVS ? (h - yy - 1) : yy) * wid; //位偏移量
const uint8_t *p = bmp + (ofs >> 3); //闪存地址
uint8_t mask = 0x80 >> (ofs & 7); //位元遮罩
uint8_t c = pgm_read_byte(p++);
for (xx = 0; xx < w; xx++) {
if (mask == 0) {
c = pgm_read_byte(p++);
mask = 0x80;
}
pixel = (c & mask) ? color : bg;
tft.pushColors(&pixel, 1, first);
first = 0;
mask >>= 1;
}
}
tft.setAddrWindow(0, 0, tft.width() - 1, tft.height() - 1);
}
void msg_time(int x, int y, String msg, uint32_t t) {
t = millis() - t;
tft.setCursor(x, y);
tft.print(msg);
tft.print(t);
tft.print(F("ms"));
}
void loop(void){
int x = 5, y, w = 128, h = 64;
uint32_t t;
const int SZ = w * h / 8;
uint8_t sram[SZ];
memcpy_P(sram, tractor_128x64, SZ);
tft.fillScreen(BLACK);
y = 0; t = millis();
tft.drawBitmap(x, y, tractor_128x64, 128, 64, BLUE);
msg_time(0, y + 66, F("drawBitmap() transparent flash "), t);
y = 80; t = millis();
tft.drawBitmap(x, y, tractor_128x64, 128, 64, RED, YELLOW);
msg_time(0, y + 66, F("drawBitmap() background flash "), t);
y = 160; t = millis();
tft.fillRect(x, y, w, h, GREY);
tft.drawBitmap(x, y, sram, 128, 64, GREEN);
msg_time(0, y + 66, F("drawBitmap() fill bgd SRAM "), t);
y = 240; t = millis();
showbgd(x, y, tractor_128x64, 128, 64, MAGENTA, YELLOW);
msg_time(0, y + 66, F("pushColors() background flash "), t);
delay(1500);
tft.fillScreen(BLACK);
y = 0; t = millis();
tft.drawRGBBitmap(x, y, marilyn_64x64, 64, 64);
msg_time(0, y + 66, "drawRGBBitmap() flash ", t);
y = 80; t = millis();
tft.setAddrWindow(x, y, x + 64 - 1, y + 64 - 1);
tft.pushColors((const uint8_t*)marilyn_64x64, 64 * 64, 1, false);
tft.setAddrWindow(0, 0, tft.width() - 1, tft.height() - 1);
msg_time(0, y + 66, F("pushColors() flash "), t);
y = 160; t = millis();
w = 64;
tft.fillRect(x, y, w, h, GREY);
tft.drawRGBBitmap(x, y, marilyn_64x64, magnify_64x64, 64, 64);
msg_time(0, y + 66, F("drawRGBBitmap() with mask "), t);
y = 240; t = millis();
w = 64;
tft.fillRect(x, y, w, h, GREY);
tft.drawRGBBitmap(x, y, marilyn_64x64, magnify_inv_64x64, 64, 64);
msg_time(0, y + 66, F("drawRGBBitmap() with mask "), t);
delay(1500);
#if !LOWFLASH
tft.fillScreen(BLACK);
y = 0; t = millis();
tft.drawRGBBitmap(x, y, tractor10_96x64, 96, 64);
msg_time(0, y + 66, "drawRGBBitmap() flash ", t);
y = 80; t = millis();
tft.setAddrWindow(x, y, x + 96 - 1, y + 64 - 1);
tft.pushColors((const uint8_t*)tractor10_96x64, 96 * 64, 1, false);
tft.setAddrWindow(0, 0, tft.width() - 1, tft.height() - 1);
msg_time(0, y + 66, F("pushColors() flash "), t);
y = 160; t = millis();
w = 96;
tft.fillRect(x, y, w, h, GREY);
tft.drawRGBBitmap(x, y, tractor10_96x64, camera_96x64, 96, 64);
msg_time(0, y + 66, F("drawRGBBitmap() with mask "), t);
y = 240; t = millis();
w = 96;
tft.fillRect(x, y, w, h, GREY);
tft.drawRGBBitmap(x, y, tractor10_96x64, camera_inv_96x64, 96, 64);
msg_time(0, y + 66, F("drawRGBBitmap() with mask "), t);
delay(1500);
#endif
}
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百六十五:2.4寸TFT液晶触摸屏 彩屏模块 TFT-LCD 高清真彩显示屏
项目十四:绘制位图8张
实验串口绘图器返回情况
![](https://img.haomeiwen.com/i17690760/f45ec8effab5be35.jpg)
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百六十五:2.4寸TFT液晶触摸屏 彩屏模块 TFT-LCD 高清真彩显示屏
项目十四:绘制位图8张
Arduino实验场景图
![](https://img.haomeiwen.com/i17690760/8f8d23d79bfcdf8a.gif)
以低廉的价格学习和开始使用 Arduino UNO 和 这款2.4寸TFT LCD 显示器(淘宝上17元)是一个非常好的选择。
TFT LCD 是使用薄膜晶体管 (TFT) 技术的液晶显示器 (LCD) 的一种变体。这提高了图像质量、更好的对比度和可寻址性。液晶屏驱动芯片为ILI9341,触摸屏驱动芯片为XPT2046。
在基于Arduino的项目中,处理器频率很低。因此无法显示复杂的高清图像和高速运动。Arduino UNO扩展板 全彩 TFT LCD 适合显示简单的数据和命令。使用的 TFT 控制器无法切换内部显示 RAM,因此不能将双缓冲技术用于动画,但仍然只能重新绘制屏幕的一小部分。
鉴于 Arduino UNO 的局限性,显示器越大,性能越差。2.4寸屏幕的尺寸足以满足 Arduino UNO 的像素数量、显示面积和功能之间的折衷。
该模块消耗了 Arduino UNO 中的大部分可用资源。这不是模块本身的限制。作为回报,使用并行接口可以快速更新图像。如果想利用其所有功能(LCD + 触摸屏 + SD 卡),只有引脚 0 和 1(分别为 RX 和 TX)以及引脚 19 (A5) 未使用。如果不使用 SD 卡,则额外提供引脚 10、11、12 和 13。通过适当的布局,即使使用 SD 卡,也可以连接一些 SPI 设备。
![](https://img.haomeiwen.com/i17690760/efbfb5cba6a92a7f.jpg)