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
- 英文、中文、圖片: 其實都是畫點和快取的處理