STM32驅動ST7735 TFT

前言

LCD的選擇有很多種,尺寸也很多,但若需要顯示彩色的畫面,這邊推薦ST7735, CP值最高,效果也不錯的。本範例將介紹ST7735 彩色1.8吋顯示螢幕與STM32的使用方式。這邊參考Arduino Adafruit函式庫,函式庫為所有的LCD和OLED顯示器提供了通用語法和圖形功能。

接線說明

這邊可以參考以下說明

  • BL >> 3.3V
  • CS >> (任意GPIO)
  • DC(A0、RS) >> PIN 8
  • RES >> (任意GPIO)
  • MOSI(SDA) >> (SPI 接線)
  • SCK(SCL) >> (SPI 接線)
  • VCC >> 5V or 3.3V(看購買的說明書)
  • GND >> GND

Sample Code

這邊可以直接移植Arduino或網路直接抓Driver這塊因為便宜有更多人選用開放資源也很多

以下2個是最常使用到Function

 ST7735_DrawImage(0, 30, 80, 62, (uint16_t*)outputBuffer);//寫入圖片
ST7735_WriteString(offset? 80:0, 5, outString, Font_7x10, RED,BLACK);//寫入文字

下面可以看到是常用Fuction詳細內容

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();
}



影片參考

ST7735驅動程式設計要點

  • 暫存器是8位的:命令8位的,而資料發送時一個跟一個;顏色值16位,要分兩字節發送
  • 指令+資料:不管寫字點還是刷屏,步驟都只是:先發指令,後發數據
  • 發指令的操作:拉低 DC接腳,發送1個8位的指令值
  • 發送資料的操作:拉高 DC引腳,挨字節發出要傳送資料
  • 螢幕顯示方向:在發出指令0x36後,緊接的一位元組資料為螢幕顯示方向,可選參數:C0/00/A0/60/C8/08/A8/68
  • 花屏:如果右邊或下邊有花屏,表示像素沒填充夠,加大一點刷屏值,如130*163
  • 英文、中文、圖片: 其實都是畫點和快取的處理

Leave a Comment

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

Shopping Cart