Skip to content

How to interface a 1.77 inch TFT with a PIC MCU?

87/ 100Editor's Pick

Interfacing a 1.77 inch TFT with a PIC MCU: A Practical Guide

To interface a 1.77 inch TFT with a PIC MCU, you typically use a 4-wire SPI (Serial Peripheral Interface) connection, as most small TFT modules like the 1.77 inch spi mcu rgb tft display come with a built-in ILI9341 or ST7735 controller. These controllers support SPI mode, which requires only four pins from the PIC: MOSI (Master Out Slave In), MISO (Master In Slave Out, though often optional), SCK (Serial Clock), and CS (Chip Select). You also need a DC (Data/Command) pin and a RESET pin. The PIC’s SPI module runs at 8 MHz to 20 MHz depending on the MCU model, but for a 1.77 inch 128x160 pixel display, a 10 MHz SPI clock is more than sufficient to achieve a 30 fps refresh rate for static images. For example, the PIC18F46K22 has a dedicated MSSP (Master Synchronous Serial Port) module that can be configured for SPI mode with a clock polarity of 0 and phase of 0 (mode 0). The display’s pixel data is sent as 16-bit RGB565 format, meaning each pixel consumes 2 bytes, so a full frame buffer is 128 * 160 * 2 = 40,960 bytes. If your PIC has less than 40 KB of RAM, you cannot store the full frame buffer in SRAM; instead, you must send data line by line or use a partial buffer. For instance, the PIC18F46K22 has 3,776 bytes of SRAM, so you can only buffer about 1,888 pixels at a time, which is about 11.8% of the full frame. This forces you to use a tiled rendering approach, where you send data for a 16x16 pixel tile, then update the display’s GRAM (Graphics RAM) via SPI commands. The display’s GRAM is typically 172,800 bytes (for 128x160 at 18-bit color), but the SPI interface only sends 16-bit data, so the controller internally converts to 18-bit by padding the least significant bits. The timing diagram for the ST7735 shows that the CS line must be low for the entire transaction, and the DC line must be set high for data bytes and low for command bytes. The RESET pin must be held low for at least 10 ms after power-up, then released high, and the display initialization sequence requires sending a series of commands like SWRESET (0x01), SLPOUT (0x11), and DISPON (0x29). The initialization sequence takes about 120 ms total, including a 5 ms delay after SWRESET and a 10 ms delay after SLPOUT. A common mistake is forgetting to set the SPI clock polarity correctly; the ST7735 requires SPI mode 0 (CPOL=0, CPHA=0) or mode 3 (CPOL=1, CPHA=1), but most libraries use mode 0. The PIC’s SPI configuration register (SSPxCON1) must have CKP=0 and CKE=1 for mode 0, which means the data is sampled on the rising edge of SCK. The MISO pin is rarely used because the display does not send data back except for read commands, which are not needed for basic drawing. However, if you want to read the display’s pixel data for double-buffering, you need to connect MISO and set the SPI to mode 0 with the read command (0x2E). The power consumption of the 1.77 inch TFT backlight is typically 20 mA at 3.3V, and the logic draws about 2 mA. The PIC’s I/O pins can source up to 25 mA, so you can drive the backlight directly through a 100-ohm resistor, but for better brightness control, use a PWM pin from the PIC. The CCP (Capture/Compare/PWM) module on the PIC can generate a 1 kHz PWM signal with a duty cycle from 0% to 100%, which controls the backlight brightness linearly. For example, the PIC18F46K22 has two CCP modules that can be used for PWM, and the frequency is set by the PR2 register. If you set PR2 to 255 and the timer prescaler to 16, the PWM frequency is (Fosc/4)/(16*256) = 4.88 kHz at 20 MHz Fosc, which is well above the audible range. The display’s SPI bus can be shared with other SPI devices, like an SD card, but you must ensure that each device has a unique CS pin. The CS pin for the display must be set high when not in use to avoid bus contention. The display’s operating voltage is 3.3V, but the PIC can run at 5V, so you need a level shifter for the SPI lines. A simple resistor divider (e.g., 1k ohm and 2k ohm) can drop 5V to 3.3V for the MOSI, SCK, and CS lines, but the MISO line from the display is 3.3V and can be read directly by a 5V PIC if the PIC’s input threshold is TTL-compatible, which most PICs are. For example, the PIC18F46K22 has a VIH of 0.8*VDD, so at 5V, the minimum high voltage is 4V, which is higher than the 3.3V output from the display. In this case, you need a 3.3V to 5V level shifter for MISO, such as a 74HC4050 buffer. Alternatively, use a PIC that runs at 3.3V, like the PIC24FJ64GA002, which eliminates the need for level shifting. The SPI clock speed is limited by the display’s maximum rating, which is 20 MHz for the ST7735, but the PIC’s SPI module can only go up to Fosc/4, so at 20 MHz Fosc, the maximum SPI clock is 5 MHz. To achieve a higher SPI clock, you need a PIC with a higher Fosc, like the PIC32MX250F128B, which runs at 40 MHz, giving a 10 MHz SPI clock. The display’s response time is about 10 ms for a full frame update at 10 MHz SPI clock, but the actual refresh rate depends on the amount of data sent. For a 128x160 pixel display, sending 40,960 bytes at 10 MHz takes 40,960 * 8 / 10,000,000 = 0.0328 seconds, or about 30 fps. However, if you include command overhead, the actual frame rate drops to about 25 fps. The display’s GRAM is organized as a 132x162 pixel matrix, but only 128x160 pixels are visible, so you must set the column and page address ranges using commands 0x2A and 0x2B. The column address range is from 0 to 127, and the page address range is from 0 to 159. The GRAM write command is 0x2C, and you must send the pixel data in RGB565 format, where the high byte is R[4:0] and G[5:3], and the low byte is G[2:0] and B[4:0]. For example, to draw a red pixel, you send 0xF8 and 0x00, which gives R=31, G=0, B=0. The display’s color depth is 262k colors (18-bit), but the SPI interface only supports 16-bit, so the controller maps the 16-bit value to 18-bit by replicating the most significant bits. For instance, a 5-bit red value of 31 (0x1F) is mapped to 6-bit red value of 63 (0x3F). The display’s refresh rate is 60 Hz internally, but the SPI interface limits the update rate. If you need to display animations, you can use the display’s partial update mode, which allows you to update only a small region of the screen. The partial update command (0x30) sets the scrolling area, and you can update a 16x16 pixel region in about 0.4 ms at 10 MHz SPI clock. This is useful for displaying moving objects without redrawing the entire screen. The display’s power-down mode can be entered by sending the SLPIN command (0x10), which reduces current consumption to about 5 uA. The PIC can also enter sleep mode and wake up via an external interrupt, such as a button press, to save power. The display’s backlight can be turned off by setting the PWM duty cycle to 0%, which reduces total current consumption to about 2 mA. The typical application circuit includes a 10 uF capacitor between VCC and GND near the display, and a 100 nF capacitor between the PIC’s VDD and VSS. The SPI lines should have pull-up resistors (10k ohm) to VCC to prevent floating during power-up. The RESET pin should have a 10k ohm pull-up resistor to VCC to ensure a clean reset. The DC pin is connected to a PIC GPIO, and the CS pin is also connected to a GPIO. The PIC’s SPI module is initialized by setting the SSPEN bit, configuring the clock polarity, and setting the baud rate. For example, the SSPADD register is set to 0x00 for a 10 MHz SPI clock at 20 MHz Fosc. The data is transmitted by writing to the SSPBUF register, and the busy flag (BF) is checked before sending the next byte. The display’s initialization sequence is critical for proper operation, and it must be sent exactly as specified in the datasheet. The sequence includes setting the display to sleep mode, turning off the display, setting the pixel format to 16-bit, setting the display orientation, and turning on the display. The display orientation is set by the MADCTL command (0x36), which controls the row and column order. For example, setting MADCTL to 0x08 gives a landscape orientation, while 0x00 gives portrait. The display’s default orientation is portrait, with the pixel address starting at (0,0) in the top-left corner. The font rendering for the display can be done using a bitmap font, where each character is stored as a 5x7 pixel array. For a 5x7 font, each character requires 5 bytes, and you can use the PIC’s program memory to store the font data. The character position is calculated by multiplying the character index by 5, and the data is sent to the display using the GRAM write command. The display’s coordinate system is such that the column address is 0 to 127, and the page address is 0 to 159. To draw a line, you can use Bresenham’s algorithm, which requires integer arithmetic. The algorithm calculates the slope and steps through the pixels, sending each pixel to the display. The display’s SPI interface does not support burst write for lines, so you must send each pixel individually. This is slow for long lines, but for a 128-pixel line, it takes about 0.1 ms at 10 MHz SPI clock. The display’s GRAM is write-only, so you cannot read back the pixel data unless you use the read command (0x2E). The read command requires the MISO pin to be connected, and the PIC must generate an extra clock cycle for the dummy byte. The read data is returned in 16-bit RGB565 format, but the display’s read timing is slower than write timing, so the SPI clock must be reduced to 5 MHz for reads. The display’s temperature range is -20°C to +70°C, but the PIC’s temperature range is -40°C to +85°C, so the display is the limiting factor. The display’s viewing angle is 120 degrees horizontally and 100 degrees vertically, but the contrast ratio is 500:1 typical. The display’s brightness is 250 cd/m² typical, which is sufficient for indoor use. The display’s pixel pitch is 0.22 mm, giving a resolution of 128x160 pixels in a 1.77 inch diagonal. The display’s weight is about 10 grams, and the PCB footprint is 34.5 mm x 45.2 mm. The display’s interface connector is a 14-pin FPC (Flexible Printed Circuit) with a 0.5 mm pitch, which requires a matching connector on the PCB. The FPC connector is typically a 0.5 mm pitch ZIF (Zero Insertion Force) connector, such as the FH12-14S-0.5SH. The pinout of the display is: pin 1 is VCC (3.3V), pin 2 is GND, pin 3 is CS, pin 4 is RESET, pin 5 is DC, pin 6 is MOSI, pin 7 is SCK, pin 8 is MISO, pin 9 is LED_A (backlight anode), pin 10 is LED_K (backlight cathode), pin 11 is GND, pin 12 is GND, pin 13 is GND, and pin 14 is GND. The backlight LED is a 3.3V device with a forward current of 20 mA, so you can connect it directly to a 3.3V supply through a 100-ohm resistor. The display’s logic supply current is 2 mA, so a 3.3V regulator like the MCP1700 can provide the necessary current. The PIC’s supply voltage can be 3.3V or 5V, but if you use a 5V PIC, you need a 3.3V regulator for the display. The display’s SPI interface is 3.3V tolerant, but the PIC’s I/O pins are 5V tolerant, so you can connect the display’s pins directly to the PIC if the PIC’s output high voltage is less than 3.3V. For example, the PIC18F46K22 has a VOH of 0.8*VDD, so at 5V, the output high voltage is 4V, which is too high for the display. In this case, you need a level shifter or a voltage divider. The voltage divider for the MOSI, SCK, and CS lines can be a 1k ohm resistor in series with a 2k ohm resistor to ground, giving a voltage of 5 * 2 / (1+2) = 3.33V. The MISO line from the display is 3.3V, and the PIC’s input low threshold is 0.2*VDD, so at 5V, the low threshold is 1V, and the high threshold is 0.8*VDD = 4V. Since the display’s output high is 3.3V, it is below the PIC’s high threshold, so you need a level shifter for MISO. A 74HC4050 buffer can convert 3.3V to 5V. Alternatively, use a PIC that runs at 3.3V, like the PIC24FJ64GA002, which has a VDD of 3.3V and can interface directly with the display. The PIC24FJ64GA002 has 16 KB of RAM, which is enough to buffer a full 128x160 pixel frame (40,960 bytes) if you use a 16-bit color depth, but the RAM is 16 KB, so you can only buffer about 8,192 pixels, which is about 5% of the full frame. For this reason, a partial buffer approach is still necessary. The display’s SPI speed can be increased to 20 MHz if you use a PIC32MX250F128B, which runs at 40 MHz and has a dedicated SPI module with a 20 MHz clock. The PIC32MX250F128B has 128 KB of RAM, which is enough to buffer a full frame, so you can implement double-buffering. Double-buffering involves writing to a RAM buffer and then transferring the entire buffer to the display in one burst. This reduces tearing artifacts and improves animation smoothness. The display’s GRAM write command (0x2C) supports continuous write, so you can send all 40,960 bytes in one SPI transaction without needing to resend the address. The transaction time is about 16.4 ms at 20 MHz SPI clock, which gives a frame rate of 60 fps. However, the display’s internal refresh rate is 60 Hz, so the maximum frame rate is 60 fps. The display’s response time is 10 ms, so the actual visible update rate is limited by the display’s pixel response. The display’s pixel response time is 10 ms for rising and 15 ms for falling, so the total response time is 25 ms, which limits the frame rate to 40 fps. The display’s contrast ratio is 500:1, which is typical for a TN (Twisted Nematic) display. The display’s viewing angle is 120 degrees horizontal and 100 degrees vertical, which is narrow compared to IPS (In-Plane Switching) displays. The display’s color gamut is 60% NTSC, which is adequate for basic graphics but not for photo-realistic images. The display’s brightness is 250 cd/m², which is sufficient for indoor use but not for direct sunlight. The display’s power consumption is 50 mW typical, including the backlight. The PIC’s power consumption is 10 mA at 20 MHz, so the total power consumption is about 60 mW. For battery-powered applications, you can use the display’s sleep mode and the PIC’s sleep mode to reduce power to 5 uA. The display’s sleep mode is entered by sending the SLPIN command (0x10), and the PIC’s sleep mode is entered by executing the SLEEP instruction. The wake-up time for the display is 120 ms, so you need to account for this delay in your application. The display’s initialization sequence is stored in the PIC’s program memory and is sent during power-up. The sequence includes setting the display to 16-bit color mode, setting the display orientation, and turning on the display. The display’s orientation can be changed dynamically by sending the MADCTL command with a different value. For example, to rotate the display 90 degrees, set MADCTL to 0x28. The display’s pixel address is

a

admin

Staff Reviewer · Game Quarters

The Daily Drop — one sharp take, every weekday morning.

218,000 readers. 42% open rate. No filler.

Subscribe Free