
This is the dedicated graphics hardware-specific library for ILI9325 TFT LCD display driver. It needs to be paired with the core graphics Adafruit GFX Library.

The point here is the datasheet will specify the maximun current allowable and each display is a bit different. Some might even NOT have the internal zener diodes. So while this usually works it might not always do so and any newby reading this might actually blow his LCD trying to use this method, because the display is different. People reading the topics should know the theory before just deciding on using a random value found online before atempting to do the same. Many know they need to use a resistor but are clueless about the reason for it.
Soulds like how I used to be! "This works, and I"m pretty sure I need it, but I have no idea why." Being on a tight budget though tends to keep you a bit on the cautious side until you build confidence and start experimenting. (or find documentation, not really easily available to kid in the 80"s) I"ve read the specs on a number of LCD panels and their associated driver ICs, and yes quite a few of them lack the limiting on the input. Probably the easiest way to really know if it"s happening (ie you don"t have a dataheet) is to tie in a very low current voltage source at say, 3.5v to an input pin and check it for 3.3v. Digital inputs should be very high impedence, and are unlikely to be damaged by such a small overvoltage, but should easily be clamped down to the standard 3.3v if you"re supplying under a few milliamps, especially at a low fraction of a volt over spec.

Learn how to use inexpensive ILI9325 colour TFT LCD modules in chapter fifty of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.
Colour TFT LCD modules just keep getting cheaper, so in this tutorial we’ll show you how to get going with some of the most inexpensive modules we could find. The subject of our tutorial is a 2.8″ 240 x 320 TFT module with the ILI9325 LCD controller chip. If you look in ebay this example should appear pretty easily, here’s a photo of the front and back to help identify it:
There is also the line “HY-TFT240_262k HEYAODZ110510″ printed on the back of the module. They should cost less than US$10 plus shipping. Build quality may not be job number one at the factory so order a few, however considering the cost of something similar from other retailers it’s cheap insurance. You’ll also want sixteen male to female jumper wires to connect the module to your Arduino.
To make life easier we’ll use an Arduino library “UTFT” written for this and other LCD modules. It has been created by Henning Karlsen and can be downloaded from his website. If you can, send him a donation – this library is well worth it. Once you’ve downloaded and installed the UTFT library, the next step is to wire up the LCD for a test.
If you’re curious, the LCD module and my Eleven board draws 225 mA of current. If that didn’t work for you, double-check the wiring against the list provided earlier. Now we’ll move forward and learn how to display text and graphics.
Where red, green and blue are values between zero and 255. So if you want white use 255,255,255 etc. For some named colours and their RGB values, click here. To select the required font, use one of the following:myGLCD.setFont(SmallFont); // Allows 20 rows of 40 characters
where the top-left of the rectangle is x1,y1 and the bottom-right is x2, y2. You can also have rectangles with rounded corners, just use:myGLCD.drawRoundRect(x1,y2,x2,y2); // for open rectangles
If you already have an image in .gif, .jpg or .png format that’s less than 300 KB in size, this can be displayed on the LCD. To do so, the file needs to be converted to an array which is inserted into your sketch. Let’s work with a simple example to explain the process. Below is our example image:
Past the #include statement and the array into your sketch above void setup(). After doing that, don’t be tempted to “autoformat” the sketch in the Arduino IDE. Now you can use the following function to display the bitmap on the LCD:
Wherex and y are the top-left coordinates of the image, width and height are the … width and height of the image, and name is the name of the array. Scale is optional – you can double the size of the image with this parameter. For example a value of two will double the size, three triples it – etc. The function uses simple interpolation to enlarge the image, and can be a clever way of displaying larger images without using extra memory. Finally, you can also display the bitmap on an angle – using:myGLCD.drawBitmap(x,y,width,height, name, angle, cx, cy);
So there you have it – an incredibly inexpensive and possibly useful LCD module. Thank you to Henning Karlsen for his useful library, and if you found it useful – send him a donation via his page.

Displaying a custom image or graphic on a LCD display is a very useful task as displays are now a premium way of providing feedback to users on any project. With this functionality, we can build projects that display our own logo, or display images that help users better understand a particular task the project is performing, providing an all-round improved User Experience (UX) for your Arduino or ESP8266 based project. Today’s tutorial will focus on how you can display graphics on most Arduino compatible displays.
The procedure described in this tutorial works with all color displays supported by Adafruit’s GFX library and also works for displays supported by the TFTLCD library from Adafruit with little modification. Some of the displays on which this procedure works include:
For this tutorial, we will use the 2.8″ ILI9325 TFT Display which offers a resolution of 320 x 340 pixels and we will display a bitmap image of a car.
To demonstrate how things work, we will use the 2.8″ TFT Display. The 2.8″ TFT display comes as a shield which plugs directly into the Arduino UNO as shown in the image below.
Image2Code is an easy-to-use, small Java utility to convert images into a byte array that can be used as a bitmap on displays that are compatible with the Adafruit-GFX or Adafruit TFTLCD (with little modification) library.
To reduce the amount of code, and stress involved in displaying the graphics, we will use two wonderful libraries; The GFX library and the TFTLCD library from Adafruit.
As usual, we start writing the sketch by including the libraries required. For this procedure, we will use the TFTLCD library alone, since we are assuming you are using a display that is not supported by the GFX library.
The last section of the code is the drawBitmap function itself, as earlier mentioned, to use the drawbitmap() function with the Adafruit TFTLCD library, we need to copy the function’s code and paste into the Arduino sketch.

In this tutorial, you will learn how to use and set up 2.4″ Touch LCD Shield for Arduino. First, you’ll see some general information about this shield. And after learning how to set the shield up, you’ll see 3 practical projects.
The role of screens in electronic projects is very important. Screens can be of very simple types such as 7 Segment or character LCDs or more advanced models like OLEDs and TFT LCDs.
One of the most important features of this LCD is including a touch panel. If you are about to use the LCD, you need to know the coordinates of the point you touch. To do so, you should upload the following code on your Arduino board and open the serial monitor. Then touch your desired location and write the coordinates displayed on the serial monitor. You can use this coordination in any other project./*TFT LCD - TFT Touch CoordinateBased on Librery Examplemodified on 21 Feb 2019by Saeed Hosseinihttps://electropeak.com/learn/*/#include #include "TouchScreen.h"#define YP A2#define XM A3#define YM 8#define XP 9// For better pressure precision, we need to know the resistance// between X+ and X- Use any multimeter to read it// For the one we"re using, its 300 ohms across the X plateTouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);void setup(void) {Serial.begin(9600);}void loop(void) {TSPoint p = ts.getPoint();if (p.z > ts.pressureThreshhold) {Serial.print("X = "); Serial.print(p.x);Serial.print("\tY = "); Serial.print(p.y);Serial.print("\tPressure = "); Serial.println(p.z);}delay(100);}
Displaying Text and Shapes on Arduino 2.4 LCD/*TFT LCD - TFT Simple drivingmodified on 21 Feb 2019by Saeed Hosseinihttps://electropeak.com/learn/*/#include #include #define LCD_CS A3#define LCD_CD A2#define LCD_WR A1#define LCD_RD A0#define LCD_RESET A4#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 ORANGE 0xFD20#define GREENYELLOW 0xAFE5#define NAVY 0x000F#define DARKGREEN 0x03E0#define DARKCYAN 0x03EF#define MAROON 0x7800#define PURPLE 0x780F#define OLIVE 0x7BE0#define LIGHTGREY 0xC618#define DARKGREY 0x7BEFAdafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);void setup() {Serial.begin(9600);Serial.println(F("TFT LCD test"));#ifdef USE_ADAFRUIT_SHIELD_PINOUTSerial.println(F("Using Adafruit 2.4\" TFT Arduino Shield Pinout"));#elseSerial.println(F("Using Adafruit 2.4\" TFT Breakout Board Pinout"));#endifSerial.print("TFT size is ");Serial.print(tft.width());Serial.print("x");Serial.println(tft.height());tft.reset();uint16_t identifier = tft.readID();if (identifier == 0x9325) {Serial.println(F("Found ILI9325 LCD driver"));} else if (identifier == 0x9328) {Serial.println(F("Found ILI9328 LCD driver"));} else if (identifier == 0x7575) {Serial.println(F("Found HX8347G LCD driver"));} else if (identifier == 0x9341) {Serial.println(F("Found ILI9341 LCD driver"));} else if (identifier == 0x8357) {Serial.println(F("Found HX8357D LCD driver"));} else {Serial.print(F("Unknown LCD driver chip: "));Serial.println(identifier, HEX);Serial.println(F("If using the Adafruit 2.4\" TFT Arduino shield, the line:"));Serial.println(F(" #define USE_ADAFRUIT_SHIELD_PINOUT"));Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));Serial.println(F("If using the breakout board, it should NOT be #defined!"));Serial.println(F("Also if using the breakout, double-check that all wiring"));Serial.println(F("matches the tutorial."));return;}tft.begin(identifier);Serial.println(F("Benchmark Time (microseconds)"));Serial.print(F("Screen fill "));Serial.println(FillScreen());delay(500);tft.setTextColor(YELLOW);tft.setCursor(70, 180);tft.setTextSize(1);tft.println("Electropeak");delay(200);tft.fillScreen(PURPLE);tft.setCursor(50, 170);tft.setTextSize(2);tft.println("Electropeak");delay(200);tft.fillScreen(PURPLE);tft.setCursor(20, 160);tft.setTextSize(3);tft.println("Electropeak");delay(500);tft.fillScreen(PURPLE);for (int rotation = 0; rotation < 4; rotation++) { tft.setRotation(rotation); tft.setCursor(0, 0); tft.setTextSize(3); tft.println("Electropeak"); delay(700); } delay(500); Serial.print(F("Rectangles (filled) ")); Serial.println(testFilledRects(YELLOW, MAGENTA)); delay(500); } void loop() { } unsigned long FillScreen() { unsigned long start = micros(); tft.fillScreen(RED); delay(500); tft.fillScreen(GREEN); delay(500); tft.fillScreen(BLUE); delay(500); tft.fillScreen(WHITE); delay(500); tft.fillScreen(MAGENTA); delay(500); tft.fillScreen(PURPLE); delay(500); 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(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 resultstft.drawRect(cx - i2, cy - i2, i, i, color2);}return t;}
Displaying BMP pictures/*This code is TFTLCD Library Example*/#include #include #include #include #define LCD_CS A3#define LCD_CD A2#define LCD_WR A1#define LCD_RD A0#define SD_CS 10Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);void setup(){Serial.begin(9600);tft.reset();uint16_t identifier = tft.readID();if (identifier == 0x9325) {Serial.println(F("Found ILI9325 LCD driver"));} else if (identifier == 0x9328) {Serial.println(F("Found ILI9328 LCD driver"));} else if (identifier == 0x7575) {Serial.println(F("Found HX8347G LCD driver"));} else if (identifier == 0x9341) {Serial.println(F("Found ILI9341 LCD driver"));} else if (identifier == 0x8357) {Serial.println(F("Found HX8357D LCD driver"));} else {Serial.print(F("Unknown LCD driver chip: "));Serial.println(identifier, HEX);Serial.println(F("If using the Adafruit 2.4\" TFT Arduino shield, the line:"));Serial.println(F(" #define USE_ADAFRUIT_SHIELD_PINOUT"));Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));Serial.println(F("If using the breakout board, it should NOT be #defined!"));Serial.println(F("Also if using the breakout, double-check that all wiring"));Serial.println(F("matches the tutorial."));return;}tft.begin(identifier);Serial.print(F("Initializing SD card..."));if (!SD.begin(SD_CS)) {Serial.println(F("failed!"));return;}Serial.println(F("OK!"));bmpDraw("pic1.bmp", 0, 0);delay(1000);bmpDraw("pic2.bmp", 0, 0);delay(1000);bmpDraw("pic3.bmp", 0, 0);delay(1000);}void loop(){}#define BUFFPIXEL 20void bmpDraw(char *filename, int x, int y) {File bmpFile;int bmpWidth, bmpHeight; // W+H in pixelsuint8_t bmpDepth; // Bit depth (currently must be 24)uint32_t bmpImageoffset; // Start of image data in fileuint32_t rowSize; // Not always = bmpWidth; may have paddinguint8_t sdbuffer[3 * BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit per pixel)uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbufferboolean goodBmp = false; // Set to true on valid header parseboolean flip = true; // BMP is stored bottom-to-topint w, h, row, col;uint8_t r, g, b;uint32_t pos = 0, startTime = millis();uint8_t lcdidx = 0;boolean first = true;if ((x >= tft.width()) || (y >= tft.height())) return;Serial.println();Serial.print(F("Loading image ""));Serial.print(filename);Serial.println("\"");// Open requested file on SD cardif ((bmpFile = SD.open(filename)) == NULL) {Serial.println(F("File not found"));return;}// Parse BMP headerif (read16(bmpFile) == 0x4D42) { // BMP signatureSerial.println(F("File size: ")); Serial.println(read32(bmpFile));(void)read32(bmpFile); // Read & ignore creator bytesbmpImageoffset = read32(bmpFile); // Start of image dataSerial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);// Read DIB headerSerial.print(F("Header size: ")); Serial.println(read32(bmpFile));bmpWidth = read32(bmpFile);bmpHeight = read32(bmpFile);if (read16(bmpFile) == 1) { // # planes -- must be "1"bmpDepth = read16(bmpFile); // bits per pixelSerial.print(F("Bit Depth: ")); Serial.println(bmpDepth);if ((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressedgoodBmp = true; // Supported BMP format -- proceed!Serial.print(F("Image size: "));Serial.print(bmpWidth);Serial.print("x");Serial.println(bmpHeight);// BMP rows are padded (if needed) to 4-byte boundaryrowSize = (bmpWidth * 3 + 3) & ~3;// If bmpHeight is negative, image is in top-down order.// This is not canon but has been observed in the wild.if (bmpHeight < 0) { bmpHeight = -bmpHeight; flip = false; } // Crop area to be loaded w = bmpWidth; h = bmpHeight; if ((x + w - 1) >= tft.width()) w = tft.width() - x;if ((y + h - 1) >= tft.height()) h = tft.height() - y;// Set TFT address window to clipped image boundstft.setAddrWindow(x, y, x + w - 1, y + h - 1);for (row = 0; row < h; row++) { // For each scanline...// Seek to start of scan line. It might seem labor-// intensive to be doing this on every line, but this// method covers a lot of gritty details like cropping// and scanline padding. Also, the seek only takes// place if the file position actually needs to change// (avoids a lot of cluster math in SD library).if (flip) // Bitmap is stored bottom-to-top order (normal BMP)pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;else // Bitmap is stored top-to-bottompos = bmpImageoffset + row * rowSize;if (bmpFile.position() != pos) { // Need seek?bmpFile.seek(pos);buffidx = sizeof(sdbuffer); // Force buffer reload}for (col = 0; col < w; col++) { // For each column... // Time to read more pixel data? if (buffidx >= sizeof(sdbuffer)) { // Indeed// Push LCD buffer to the display firstif (lcdidx > 0) {tft.pushColors(lcdbuffer, lcdidx, first);lcdidx = 0;first = false;}bmpFile.read(sdbuffer, sizeof(sdbuffer));buffidx = 0; // Set index to beginning}// Convert pixel from BMP to TFT formatb = sdbuffer[buffidx++];g = sdbuffer[buffidx++];r = sdbuffer[buffidx++];lcdbuffer[lcdidx++] = tft.color565(r, g, b);} // end pixel} // end scanline// Write any remaining data to LCDif (lcdidx > 0) {tft.pushColors(lcdbuffer, lcdidx, first);}Serial.print(F("Loaded in "));Serial.print(millis() - startTime);Serial.println(" ms");} // end goodBmp}}bmpFile.close();if (!goodBmp) Serial.println(F("BMP format not recognized."));}// These read 16- and 32-bit types from the SD card file.// BMP data is stored little-endian, Arduino is little-endian too.// May need to reverse subscript order if porting elsewhere.uint16_t read16(File f) {uint16_t result;((uint8_t *)&result)[0] = f.read(); // LSB((uint8_t *)&result)[1] = f.read(); // MSBreturn result;}uint32_t read32(File f) {uint32_t result;((uint8_t *)&result)[0] = f.read(); // LSB((uint8_t *)&result)[1] = f.read();((uint8_t *)&result)[2] = f.read();((uint8_t *)&result)[3] = f.read(); // MSBreturn result;}
To display pictures on this LCD you should save the picture in 24bit BMP colored format and size of 240*320. Then move them to SD card and put the SD card in the LCD shield. we use the following function to display pictures. This function has 3 arguments; the first one stands for the pictures name, and the second and third arguments are for length and width coordinates of the top left corner of the picture.bmpdraw(“filename.bmp”,x,y);
Create A Paint App w/ Arduino 2.4 Touchscreen/*This code is TFTLCD Library Example*/#include #include #include #if defined(__SAM3X8E__)#undef __FlashStringHelper::F(string_literal)#define F(string_literal) string_literal#endif#define YP A3#define XM A2#define YM 9#define XP 8#define TS_MINX 150#define TS_MINY 120#define TS_MAXX 920#define TS_MAXY 940TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);#define LCD_CS A3#define LCD_CD A2#define LCD_WR A1#define LCD_RD A0#define LCD_RESET A4#define BLACK 0x0000#define BLUE 0x001F#define RED 0xF800#define GREEN 0x07E0#define CYAN 0x07FF#define MAGENTA 0xF81F#define YELLOW 0xFFE0#define WHITE 0xFFFFAdafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);#define BOXSIZE 40#define PENRADIUS 3int oldcolor, currentcolor;void setup(void) {Serial.begin(9600);Serial.println(F("Paint!"));tft.reset();uint16_t identifier = tft.readID();if(identifier == 0x9325) {Serial.println(F("Found ILI9325 LCD driver"));} else if(identifier == 0x9328) {Serial.println(F("Found ILI9328 LCD driver"));} else if(identifier == 0x7575) {Serial.println(F("Found HX8347G LCD driver"));} else if(identifier == 0x9341) {Serial.println(F("Found ILI9341 LCD driver"));} else if(identifier == 0x8357) {Serial.println(F("Found HX8357D LCD driver"));} else {Serial.print(F("Unknown LCD driver chip: "));Serial.println(identifier, HEX);Serial.println(F("If using the Adafruit 2.4\" TFT Arduino shield, the line:"));Serial.println(F(" #define USE_ADAFRUIT_SHIELD_PINOUT"));Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));Serial.println(F("If using the breakout board, it should NOT be #defined!"));Serial.println(F("Also if using the breakout, double-check that all wiring"));Serial.println(F("matches the tutorial."));return;}tft.begin(identifier);tft.fillScreen(BLACK);tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, GREEN);tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, CYAN);tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, BLUE);tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, MAGENTA);tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);currentcolor = RED;pinMode(13, OUTPUT);}#define MINPRESSURE 10#define MAXPRESSURE 1000void loop(){digitalWrite(13, HIGH);TSPoint p = ts.getPoint();digitalWrite(13, LOW);pinMode(XM, OUTPUT);pinMode(YP, OUTPUT);if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {if (p.y < (TS_MINY-5)) {Serial.println("erase");tft.fillRect(0, BOXSIZE, tft.width(), tft.height()-BOXSIZE, BLACK);}p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);if (p.y < BOXSIZE) {oldcolor = currentcolor;if (p.x < BOXSIZE) {currentcolor = RED;tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);} else if (p.x < BOXSIZE*2) {currentcolor = YELLOW;tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE);} else if (p.x < BOXSIZE*3) {currentcolor = GREEN;tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, WHITE);} else if (p.x < BOXSIZE*4) {currentcolor = CYAN;tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, WHITE);} else if (p.x < BOXSIZE*5) {currentcolor = BLUE;tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, WHITE);} else if (p.x < BOXSIZE*6) { currentcolor = MAGENTA; tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, WHITE); } if (oldcolor != currentcolor) { if (oldcolor == RED) tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED); if (oldcolor == YELLOW) tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW); if (oldcolor == GREEN) tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, GREEN); if (oldcolor == CYAN) tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, CYAN); if (oldcolor == BLUE) tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, BLUE); if (oldcolor == MAGENTA) tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, MAGENTA); } } if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);}}}

Atmel ASF library has the driver for ili9325 controller, but I"m not sure if you"ll be able to use it with Mega series. At least you can run Atmel Studio, there are example projects for this lcd controller (for atmel boards with this controller) with the source code that you can use in your projects. You can review and edit it to implement your own code.

This second article in the series of documentation-by-example posts will present a C++ driver for 320×240 (QVGA) TFT LCD panels that have an ILI9325 controller built in to them. This driver is included with my open source stm32plus C++ library and this article will show you how to use it with the STM32F103* ARM Cortex M3 microcontroller family running at 72Mhz. As of stm32plus 2.0.0 the driver is fully compatible with the STM32 F4 series of microcontrollers.
I like Ilitek controllers. They’re consistent across the range, they’re well documented and they’re easy to program if you’re familiar with TFT controllers, which I am.
The ILI9325 is a 320×240 (QVGA) device that supports 64K (5-6-5 RGB) or 262K (6-6-6 RGB). To the outside world (that’s us by the way) it presents 18-bit, 16-bit, SPI or a direct-drive RGB interface. It has its own onboard GRAM frame-buffer and expects you to send it commands that read and write from that buffer unless you’re in direct RGB mode in which case you are directly addressing the GRAM via a synchronised clock.
The schematic for the STM32 dev board documents the pinout for the TFT panel. Helpfully, the port numbers are annotated as well as the function of each pin. 16 data lines are broken out, so that implies we’re talking to the controller over its 16 bit bus (it has 18-bit, serial and RGB capabilities as well). Register-select (/RS), chip-select (CS), read (nOE) and write (nWE) are all there. There are additional pins for the reset line (RST) and the backlight. A pleasant surprise is the presence of the touch-screen interface on SPI1 up at the top right; we’ll be kicking the tires of the ADS7843 touch screen IC in a future article.
Here’s the code used to initialise the LCD. When this code has completed the LCD will be reset, initialised with your chosen colour mode, gamma and orientation and ready to use.
That’s all there is to it. If you’ve also read my previous article on driving the HX8347A controller then this will all look familiar. That’s because stm32plus hides away all the device-specific details and presents you with a unified interface for controlling graphic devices. Here’s a quickie image taken from the rolling demo. As usual the camera is less than kind to the TFT. The actual display is sharp and contrasty.
We declare an Fsmc8080Lcdtiming object that takes care of the timing details. The two parameters are the address setup and data setup times in HCLK cycles. At full speed the STM32F1 has a 36MHz FSMC bus and the STM32F4 has a 60MHz bus. Therefore the timings may be different for each MCU if the bus is faster than the panel.
Our example initialises it in portrait mode, 18 bit colour (262K). If you take a look at TftInterfaces.h you will see that following modes are available:

I have connected the display using GPIO and configured notro"s fbtft driver (GitHub - notro/fbtft: Linux Framebuffer drivers for small TFT LCD display modules ). I succeeded in getting an image on the screen, however the refresh rate was too low. I then changed the driver a little just to make it toggle a GPIO and it seems that they"re not able to toggle fast enough to get a decent refresh rate.