Driving ST7735 TFT

Preface

There are many options when it comes to choosing an LCD, with various sizes available. However, if you need to display colorful images, we recommend the ST7735 display. It offers excellent value for money and delivers good performance. This example will introduce the usage of the 1.8-inch ST7735 color display screen with STM32 microcontrollers. We will be referencing the Arduino Adafruit library, which provides universal syntax and graphic functions for all LCD and OLED displays.

Partial Wiring Diagram

You can refer to the following instructions.

  • BL >> 3.3V
  • CS >> (Any GPIO)
  • DC (A0, RS) >> PIN 8
  • RES >> (Any GPIO)
  • MOSI (SDA) >> (SPI Connection)
  • SCK (SCL) >> (SPI Connection)
  • VCC >> 5V or 3.3V (Refer to the purchased manual)
  • GND >> GND

Sample Code

Here, you can directly port the Arduino code or obtain the driver from the internet. This is popular because it’s affordable, widely chosen, and there are plenty of open-source resources available.

The following two functions are the most commonly used.

 ST7735_DrawImage(0, 30, 80, 62, (uint16_t*)outputBuffer);//import image
ST7735_WriteString(offset? 80:0, 5, outString, Font_7x10, RED,BLACK);//write word

Below, you can see the detailed contents of commonly used functions.

void ST7735_Select()
{
    HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
}

void ST7735_Unselect()
{
    HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
}

void ST7735_Reset()
{
    HAL_GPIO_WritePin(RST_PORT, RST_PIN, GPIO_PIN_RESET);
    HAL_Delay(5);
    HAL_GPIO_WritePin(RST_PORT, RST_PIN, GPIO_PIN_SET);
}

  void ST7735_WriteCommand(uint8_t cmd)
  {
    HAL_GPIO_WritePin(DC_PORT, DC_PIN, GPIO_PIN_RESET);
    HAL_SPI_Transmit(&hspi2, &cmd, sizeof(cmd), HAL_MAX_DELAY);
}

void ST7735_WriteData(uint8_t* buff, size_t buff_size)
{
    HAL_GPIO_WritePin(DC_PORT, DC_PIN, GPIO_PIN_SET);
    HAL_SPI_Transmit(&hspi2, buff, buff_size, HAL_MAX_DELAY);
}

void DisplayInit(const uint8_t *addr)
{
    uint8_t numCommands, numArgs;
    uint16_t ms;

    numCommands = *addr++;
    while(numCommands--) {
        uint8_t cmd = *addr++;
        ST7735_WriteCommand(cmd);

        numArgs = *addr++;
        // If high bit set, delay follows args
        ms = numArgs & DELAY;
        numArgs &= ~DELAY;
        if(numArgs) {
            ST7735_WriteData((uint8_t*)addr, numArgs);
            addr += numArgs;
        }

        if(ms) {
            ms = *addr++;
            if(ms == 255) ms = 500;
            HAL_Delay(ms);
        }
    }
}

void ST7735_SetAddressWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
{
    // column address set
    ST7735_WriteCommand(ST7735_CASET);
    uint8_t data[] = { 0x00, x0 + _xstart, 0x00, x1 + _xstart };
    ST7735_WriteData(data, sizeof(data));

    // row address set
    ST7735_WriteCommand(ST7735_RASET);
    data[1] = y0 + _ystart;
    data[3] = y1 + _ystart;
    ST7735_WriteData(data, sizeof(data));

    // write to RAM
    ST7735_WriteCommand(ST7735_RAMWR);
}

void ST7735_Init(uint8_t rotation)
{
    ST7735_Select();
    ST7735_Reset();
    DisplayInit(init_cmds1);
    DisplayInit(init_cmds2);
    DisplayInit(init_cmds3);
#if ST7735_IS_160X80
    _colstart = 24;
    _rowstart = 0;
 /*****  IF Doesn't work, remove the code below (before #elif) *****/
    uint8_t data = 0xC0;
    ST7735_Select();
    ST7735_WriteCommand(ST7735_MADCTL);
    ST7735_WriteData(&data,1);
    ST7735_Unselect();

#elif ST7735_IS_128X128
    _colstart = 2;
    _rowstart = 3;
#else
    _colstart = 0;
    _rowstart = 0;
#endif
    ST7735_SetRotation (rotation);
    ST7735_Unselect();

}


void ST7735_WriteString(uint16_t x, uint16_t y, const char* str, FontDef font, uint16_t color, uint16_t bgcolor) {
    ST7735_Select();

    while(*str) {
        if(x + font.width >= _width) {
            x = 0;
            y += font.height;
            if(y + font.height >= _height) {
                break;
            }

            if(*str == ' ') {
                // skip spaces in the beginning of the new line
                str++;
                continue;
            }
        }

        ST7735_WriteChar(x, y, *str, font, color, bgcolor);
        x += font.width;
        str++;
    }

    ST7735_Unselect();
}

void ST7735_FillRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color)
{
    if((x >= _width) || (y >= _height)) return;
    if((x + w - 1) >= _width) w = _width - x;
    if((y + h - 1) >= _height) h = _height - y;

    ST7735_Select();
    ST7735_SetAddressWindow(x, y, x+w-1, y+h-1);

    uint8_t data[] = { color >> 8, color & 0xFF };
    HAL_GPIO_WritePin(DC_PORT, DC_PIN, GPIO_PIN_SET);
    for(y = h; y > 0; y--) {
        for(x = w; x > 0; x--) {
            HAL_SPI_Transmit(&hspi2, data, sizeof(data), HAL_MAX_DELAY);
        }
    }

    ST7735_Unselect();
}

void ST7735_DrawImage(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t* data) {
    if((x >= _width) || (y >= _height)) return;
    if((x + w - 1) >= _width) return;
    if((y + h - 1) >= _height) return;

    ST7735_Select();
    ST7735_SetAddressWindow(x, y, x+w-1, y+h-1);
    ST7735_WriteData((uint8_t*)data, sizeof(uint16_t)*w*h);
    ST7735_Unselect();
}

Refer Video

Key Points for ST7735 Driver Programming

  • The registers are 8-bit: commands are 8 bits, and data is sent one after another. Color values are 16 bits and need to be sent in two bytes.
  • Command + Data: Regardless of writing pixels or refreshing the screen, the steps are the same: send the command first, then send the data.
  • Operation for sending commands: Pull down the DC pin and send an 8-bit command value.
  • Operation for sending data: Pull up the DC pin and send the data byte by byte.
  • Screen orientation: After sending the command 0x36, the immediately following byte of data determines the screen orientation. Optional parameters: C0/00/A0/60/C8/08/A8/68.
  • Screen artifacts: If there are artifacts on the right or bottom, it means the pixels are not filled enough. Increase the screen refresh values, for example, 130*163.
  • English, Chinese, Images: In essence, they all involve pixel rendering and caching.

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart