نمایشگر های TFT نوعی دیگر از نمایشگر های LCD هستند که وضوح تصویر بالاتری دارند . در LCD های معمولی الگوی کنترل پیکسل ها مانند تابلو روان های LED می باشد به این صورت که هر سطر و هرستون دارای یک سوئیچ ترانزیستوری است و درایور LCD وظیفه اسکن سطر ها و قرار دادن دیتا در ستون ها را بر عهده دارد . یکی از مشکلات رایج این روش این است که با فعال شدن سوئیچ هر سطر ، سطر های اطراف نیز تا حدودی فعال می شوند ( به دلیل نشت جریان ) . این امر موجب کاهش کیفت تصویر LCD می شود . در TFT با قرار دادن سوئیچ های مجزا برای هر پیکسل از این مشکل جلوگیر کرده اند .در واقع یک TFT ساختاری مانند LCD دارد با این تفاوت که هر پیکسل به صورت مستقل توسط سوئیچ خود کنترل می شود . سوئیچ هر پیکسل یک ترانزیستور است که در مجموع هر TFT دارای یک لایه ماتریس ترانزیستور است . TFT کاربرد فروانایی در مدارات امبدد دارند چرا که مصرف انرژی آن ها بسیار پایین است . در این آموزش می خواهیم به راه اندازی TFT با درایور ILI9341 بپردازیم . راه اندازی این نمایشگر ها با میکروکنترلر های سرعت پایین همانند AVR ها کار چالش برانگیزی است اما خوشبختانه کتابخانه های کاملی برای راه انداری آن وجود دارد . در بسیاری از میکروکنترلر های ARM واحد های مدیریت و راه اندازی LCD وجود دارد . حتی AFS های اتمل پیکر بندی های ILI9341 را برای میکروکنترلر های SAM3X8E و… پشتیبانی می کند .
نکته مهم در اره اندازی TFT این است که متاسفانه نمونه های کپی شده این TFT ها بسیار زیاد است و راه اندازی نمونه های کپی اغلب با نمونه های اصلی بسیاری متفاوت است ( گاها تصاویر را وارونه یا رنگ ها را متفاوت نشان می دهند ) . به دلیل اینکه دیتاشیت مشخصی هم ندارند لذا تنها از طریق آزمون و خطا ( بر اساس دیتاشیت نمونه های اصلی ) می توانید به راه اندازی نمونه های کپی پی ببرید .
مشخصات :
- ولتاژ تغذیه 3.3 ولت ( با 5 ولت نیز سازاگار است اما بهترین ولتاژ 3.3 ولت است)
- رابط ارتباطی I2C
- دارای ابعاد 2 اینچ
- رزولوشن 240×320
- ولتاژ نور پس زمینه 5+ ولت
- دارای اسلات MMC جهت اتصال SD کارت
کد های آردوینو برای راه اندازی TFT ILI9341 :
ابتدا ماژول TFT را مانند تصویر زیر به برذ آردوینو متصل کنید :
#define ILI9341_BLACK 0x0000 ///< 0, 0, 0 #define ILI9341_NAVY 0x000F ///< 0, 0, 123 #define ILI9341_DARKGREEN 0x03E0 ///< 0, 125, 0 #define ILI9341_DARKCYAN 0x03EF ///< 0, 125, 123 #define ILI9341_MAROON 0x7800 ///< 123, 0, 0 #define ILI9341_PURPLE 0x780F ///< 123, 0, 123 #define ILI9341_OLIVE 0x7BE0 ///< 123, 125, 0 #define ILI9341_LIGHTGREY 0xC618 ///< 198, 195, 198 #define ILI9341_DARKGREY 0x7BEF ///< 123, 125, 123 #define ILI9341_BLUE 0x001F ///< 0, 0, 255 #define ILI9341_GREEN 0x07E0 ///< 0, 255, 0 #define ILI9341_CYAN 0x07FF ///< 0, 255, 255 #define ILI9341_RED 0xF800 ///< 255, 0, 0 #define ILI9341_MAGENTA 0xF81F ///< 255, 0, 255 #define ILI9341_YELLOW 0xFFE0 ///< 255, 255, 0 #define ILI9341_WHITE 0xFFFF ///< 255, 255, 255 #define ILI9341_ORANGE 0xFD20 ///< 255, 165, 0 #define ILI9341_GREENYELLOW 0xAFE5 ///< 173, 255, 41 #define ILI9341_PINK 0xFC18 ///< 255, 130, 198 #include "SPI.h" #include "Adafruit_GFX.h" #include "Adafruit_ILI9341.h" // For the Adafruit shield, these are the default. #define TFT_CLK 13 #define TFT_MISO 12 #define TFT_MOSI 11 #define TFT_DC 9 #define TFT_CS 10 #define TFT_RST 8 // Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC //Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); // If using the breakout, change pins as desired Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO); void setup() { Serial.begin(9600); Serial.println("ILI9341 Test!"); tft.begin(); // read diagnostics (optional but can help debug problems) uint8_t x = tft.readcommand8(ILI9341_RDMODE); Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDMADCTL); Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDPIXFMT); Serial.print("Pixel Format: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDIMGFMT); Serial.print("Image Format: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDSELFDIAG); Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); /* Serial.println(F("Benchmark Time (microseconds)")); delay(10); Serial.print(F("Screen fill ")); Serial.println(testFillScreen()); delay(500); Serial.print(F("Text ")); Serial.println(testText()); delay(3000); Serial.print(F("Lines ")); Serial.println(testLines(ILI9341_CYAN)); delay(500); Serial.print(F("Horiz/Vert Lines ")); Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE)); delay(500); Serial.print(F("Rectangles (outline) ")); Serial.println(testRects(ILI9341_GREEN)); delay(500); Serial.print(F("Rectangles (filled) ")); Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA)); delay(500); Serial.print(F("Circles (filled) ")); Serial.println(testFilledCircles(10, ILI9341_MAGENTA)); Serial.print(F("Circles (outline) ")); Serial.println(testCircles(10, ILI9341_WHITE)); delay(500); Serial.print(F("Triangles (outline) ")); Serial.println(testTriangles()); delay(500); Serial.print(F("Triangles (filled) ")); Serial.println(testFilledTriangles()); delay(500); Serial.print(F("Rounded rects (outline) ")); Serial.println(testRoundRects()); delay(500); Serial.print(F("Rounded rects (filled) ")); Serial.println(testFilledRoundRects()); delay(500); Serial.println(F("Done!")); */ } void loop(void) { tft.fillScreen(ILI9341_NAVY); tft.setCursor(0, 0); tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1); tft.println("Hello World!"); tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2); tft.println(1234.56); tft.setTextColor(ILI9341_RED); tft.setTextSize(3); tft.println(0xDEADBEEF, HEX); tft.println(); tft.setTextColor(ILI9341_GREEN); tft.setTextSize(5); tft.println("Groop"); tft.setTextSize(2); tft.println("I implore thee,"); tft.setTextSize(1); tft.println("my foonting turlingdromes."); tft.println("And hooptiously drangle me"); tft.println("with crinkly bindlewurdles,"); tft.println("Or I will rend thee"); tft.println("in the gobberwarts"); tft.println("with my blurglecruncheon,"); tft.println("see if I don't!"); delay(5000); } unsigned long testFillScreen() { unsigned long start = micros(); tft.fillScreen(ILI9341_BLACK); yield(); tft.fillScreen(ILI9341_RED); yield(); tft.fillScreen(ILI9341_GREEN); yield(); tft.fillScreen(ILI9341_BLUE); yield(); tft.fillScreen(ILI9341_BLACK); yield(); return micros() - start; } unsigned long testText() { tft.fillScreen(ILI9341_BLACK); unsigned long start = micros(); tft.setCursor(0, 0); tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1); tft.println("Hello World!"); tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2); tft.println(1234.56); tft.setTextColor(ILI9341_RED); tft.setTextSize(3); tft.println(0xDEADBEEF, HEX); tft.println(); tft.setTextColor(ILI9341_GREEN); tft.setTextSize(5); tft.println("Groop"); tft.setTextSize(2); tft.println("I implore thee,"); tft.setTextSize(1); tft.println("my foonting turlingdromes."); tft.println("And hooptiously drangle me"); tft.println("with crinkly bindlewurdles,"); tft.println("Or I will rend thee"); tft.println("in the gobberwarts"); tft.println("with my blurglecruncheon,"); tft.println("see if I don't!"); return micros() - start; } unsigned long testLines(uint16_t color) { unsigned long start, t; int x1, y1, x2, y2, w = tft.width(), h = tft.height(); tft.fillScreen(ILI9341_BLACK); yield(); x1 = y1 = 0; y2 = h - 1; start = micros(); for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color); x2 = w - 1; for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color); t = micros() - start; // fillScreen doesn't count against timing yield(); tft.fillScreen(ILI9341_BLACK); yield(); x1 = w - 1; y1 = 0; y2 = h - 1; start = micros(); for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color); x2 = 0; for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color); t += micros() - start; yield(); tft.fillScreen(ILI9341_BLACK); yield(); x1 = 0; y1 = h - 1; y2 = 0; start = micros(); for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color); x2 = w - 1; for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color); t += micros() - start; yield(); tft.fillScreen(ILI9341_BLACK); yield(); x1 = w - 1; y1 = h - 1; y2 = 0; start = micros(); for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color); x2 = 0; for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color); yield(); return micros() - start; } unsigned long testFastLines(uint16_t color1, uint16_t color2) { unsigned long start; int x, y, w = tft.width(), h = tft.height(); tft.fillScreen(ILI9341_BLACK); start = micros(); for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1); for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2); return micros() - start; } unsigned long testRects(uint16_t color) { unsigned long start; int n, i, i2, cx = tft.width() / 2, cy = tft.height() / 2; tft.fillScreen(ILI9341_BLACK); n = min(tft.width(), tft.height()); start = micros(); for(i=2; i<n; i+=6) { i2 = i / 2; tft.drawRect(cx-i2, cy-i2, i, i, color); } return micros() - start; } unsigned long testFilledRects(uint16_t color1, uint16_t color2) { unsigned long start, t = 0; int n, i, i2, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1; tft.fillScreen(ILI9341_BLACK); n = min(tft.width(), tft.height()); for(i=n; i>0; i-=6) { i2 = i / 2; start = micros(); tft.fillRect(cx-i2, cy-i2, i, i, color1); t += micros() - start; // Outlines are not included in timing results tft.drawRect(cx-i2, cy-i2, i, i, color2); yield(); } return t; } unsigned long testFilledCircles(uint8_t radius, uint16_t color) { unsigned long start; int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2; tft.fillScreen(ILI9341_BLACK); start = micros(); for(x=radius; x<w; x+=r2) { for(y=radius; y<h; y+=r2) { tft.fillCircle(x, y, radius, color); } } return micros() - start; } unsigned long testCircles(uint8_t radius, uint16_t color) { unsigned long start; int x, y, r2 = radius * 2, w = tft.width() + radius, h = tft.height() + radius; // Screen is not cleared for this one -- this is // intentional and does not affect the reported time. start = micros(); for(x=0; x<w; x+=r2) { for(y=0; y<h; y+=r2) { tft.drawCircle(x, y, radius, color); } } return micros() - start; } unsigned long testTriangles() { unsigned long start; int n, i, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1; tft.fillScreen(ILI9341_BLACK); n = min(cx, cy); start = micros(); for(i=0; i<n; i+=5) { tft.drawTriangle( cx , cy - i, // peak cx - i, cy + i, // bottom left cx + i, cy + i, // bottom right tft.color565(i, i, i)); } return micros() - start; } unsigned long testFilledTriangles() { unsigned long start, t = 0; int i, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1; tft.fillScreen(ILI9341_BLACK); start = micros(); for(i=min(cx,cy); i>10; i-=5) { start = micros(); tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, tft.color565(0, i*10, i*10)); t += micros() - start; tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, tft.color565(i*10, i*10, 0)); yield(); } return t; } unsigned long testRoundRects() { unsigned long start; int w, i, i2, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1; tft.fillScreen(ILI9341_BLACK); w = min(tft.width(), tft.height()); start = micros(); for(i=0; i<w; i+=6) { i2 = i / 2; tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0)); } return micros() - start; } unsigned long testFilledRoundRects() { unsigned long start; int i, i2, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1; tft.fillScreen(ILI9341_BLACK); start = micros(); for(i=min(tft.width(), tft.height()); i>20; i-=6) { i2 = i / 2; tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0)); yield(); } return micros() - start; }
مطابق تصویر سیم ها را وصل کردم با برنامه شما اما فقط یک تصویر سفید دارم چرا؟