前言
不久前我們收到用戶反饋問題中,多次反饋各種不同型號(hào)的屏幕驅(qū)動(dòng)不起來,從0開始編寫代碼花費(fèi)大量時(shí)間,也有不少初次學(xué)習(xí)驅(qū)動(dòng)屏幕代碼編寫經(jīng)驗(yàn)過少等問題,為此我們決定以文章的形式發(fā)布到出來分享相應(yīng)的一些經(jīng)驗(yàn)以及收集整理好的資料,希望可以幫助用戶更加簡單的學(xué)習(xí)或快速移植代碼進(jìn)行項(xiàng)目開發(fā)。
后續(xù)我們將陸續(xù)分享有關(guān)ST7789
、GC9A01
、ST7735
、ILI9341
等驅(qū)動(dòng)IC的屏幕驅(qū)動(dòng)案例。
還是老樣子需要整理好的代碼可以在評(píng)論區(qū)留言郵箱!
關(guān)于ST7735
市面采用ST7789
驅(qū)動(dòng)IC的屏幕不算少見,本人有幸使用過的屏幕中有一款1.44寸
和一款1.8寸
的屏幕驅(qū)動(dòng)芯片為ST7735
,兩者的分辨率為128x128
、128x160
,比較遺憾的一個(gè)點(diǎn)是這款驅(qū)動(dòng)芯片驅(qū)動(dòng)的一些屏幕市面上分辨率相對(duì)比較低,顯示效果不如之前使用的ST7789
和GC9A01
好,這里有網(wǎng)上搜集加上自己編寫以及移植整理有stm32f10x、stm32f407、arduino、stc89c516、ESP32等單片機(jī)代碼,需要整理好的代碼可以在評(píng)論區(qū)留言郵箱!
綜合了解并觀察屏幕一下的一些參數(shù)之后開始進(jìn)行驅(qū)動(dòng)。
硬件接口使用的 2.54mm
間距的排針接口,這使用杜邦線進(jìn)行連接,需要設(shè)計(jì)到自己的PCB上高度也是剛好匹配上面的銅柱做定位使用的。
ST7735 | 參數(shù) |
---|---|
供電電壓 | 3.3~5.5V |
驅(qū)動(dòng)IC | ST7735 |
分辨率 | 128x128/128x160 |
尺寸 | 1.44 / 1.8寸 |
驅(qū)動(dòng)接口 | 4線SPI |
產(chǎn)商在屏幕設(shè)計(jì)上添加了3.3V穩(wěn)壓
芯片以及電平轉(zhuǎn)換芯片,使得這款原本3.3V供電的裸屏可以兼容5V和3.3V
的單片機(jī),這也意味著arduino
和51單片機(jī)
的用戶也可以驅(qū)動(dòng)這款屏幕了,雖然51單片機(jī)性能很一般但總比不能驅(qū)動(dòng)的好。
最后了解各個(gè)引腳功能之后就可以開始進(jìn)行驅(qū)動(dòng)
引腳名稱 | 引腳功能 |
---|---|
VCC | 電源正,3.3 - 5V,需要與通信電平一致 |
GND | 電源負(fù),地 |
CS | 片選,低電平使能 |
RST | 復(fù)位,低電平使能 |
DC | 數(shù)據(jù)/命令選擇,低電平命令,高電平數(shù)據(jù) |
SDA | SPI數(shù)據(jù)輸入端口 |
SCL | SPI時(shí)鐘信號(hào)輸入端口 |
BLK | 背光,懸空使能接地關(guān)閉,默認(rèn)上拉至3.3V |
stm32驅(qū)動(dòng)
引腳接線
代碼方面先按照下表接好線燒錄程序之后再對(duì)代碼移植的關(guān)鍵部分進(jìn)行說明
stm32f10x | ST7735 |
---|---|
3V3 | VIN |
GND | GND |
CS | PB6 |
RST | PA6 |
DC | PA7 |
SDA | PA4 |
SCL | PA5 |
BLK | PB7 |
BLK背光
引腳不用可以懸空不接
默認(rèn)的代碼燒錄進(jìn)行之后顯示上面圖片中大大的 優(yōu)信電子logo
,先把示例代碼驅(qū)動(dòng)起來,如果示例代碼驅(qū)動(dòng)不起來先檢查一下接線供電方面的問題,不然后面代碼改了半天沒有用找問題就和我剛驅(qū)動(dòng)的時(shí)候一樣頭皮發(fā)麻。
驅(qū)動(dòng)成功之后用戶可以開始移植代碼。
代碼移植
文件復(fù)制
將 lcd
、lcd_init
的C文件
和h文件
復(fù)制到自己的工程里面,這四個(gè)文件包含屏幕初始化以及驅(qū)動(dòng)畫點(diǎn)劃線顯示文字圖像的代碼。
另外還有兩個(gè)文件為image.h
和lcdfont.h
,這兩個(gè)文件分別存儲(chǔ)顯示圖片數(shù)組與顯示文字?jǐn)?shù)組。
復(fù)制到自己工程中編譯后會(huì)報(bào)錯(cuò),因?yàn)槿鄙倭?code>pbdata.h中的毫秒級(jí)延時(shí)函數(shù)
,可以把原工程中的ms延時(shí)函數(shù)復(fù)制過來也可以使用自己編寫的,名稱與下面的相同即可
void delay_ms(u16 a)
添加好文件到工程里面之后再次編譯一般不會(huì)報(bào)錯(cuò),如果仍然報(bào)錯(cuò)就只能看具體報(bào)錯(cuò)信息去修改了
和上面的接線不變,編寫下面主函數(shù)先進(jìn)行測試
int main(void)
{
LCD_Init();
LCD_Fill(0,0,LCD_W,LCD_H,WHITE); //填充為白色背景色
while(1)
{
LCD_ShowPicture(0,0,LCD_W,LCD_H,YXDZ_logo); //顯示一張圖片
}
}
需要用戶修改的接口一般有一下幾個(gè)點(diǎn)
端口修改
lcdfont.h
文件中包含對(duì)使用引腳的宏定義,修改其中的GPIO
以及引腳
即可修改使用的端口
//-----------------LCD端口定義----------------
#define LCD_SCLK_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_5)//SCL=SCLK
#define LCD_SCLK_Set() GPIO_SetBits(GPIOA,GPIO_Pin_5)
#define LCD_MOSI_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_4)//SDA=MOSI
#define LCD_MOSI_Set() GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define LCD_RES_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_6)//RES
#define LCD_RES_Set() GPIO_SetBits(GPIOA,GPIO_Pin_6)
#define LCD_DC_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_7)//DC
#define LCD_DC_Set() GPIO_SetBits(GPIOA,GPIO_Pin_7)
#define LCD_CS_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_6)//CS
#define LCD_CS_Set() GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define LCD_BLK_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_7)//BLK
#define LCD_BLK_Set() GPIO_SetBits(GPIOB,GPIO_Pin_7)
但值得注意的是僅僅修改這里的`宏定義`是沒辦法使用的,在`lcdfont.c`文件中包含著對(duì)`GPIO引腳`以及`時(shí)鐘初始化`的函數(shù)需要進(jìn)行端口的修改
void LCD_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); //使能端口時(shí)鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);
}
修改完這里之后才算是將端口修改完畢
在lcdfont.h
頂部還有兩個(gè)宏定義可以自行決定是否修改,分別對(duì)應(yīng)這屏幕顯示方向
和屏幕分辨率
的參數(shù)
#define USE_HORIZONTAL 0 //設(shè)置橫屏或者豎屏顯示 0或1為豎屏 2或3為橫屏
#define LCD_W 240
#define LCD_H 240
顯示函數(shù)
在lcd.h
中包含了屏幕顯示內(nèi)容的函數(shù),以及部分顏色的色號(hào)
主要用于刷新屏幕背景色
的
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color);//指定區(qū)域填充顏色
void LCD_DrawPoint(u16 x,u16 y,u16 color);//在指定位置畫一個(gè)點(diǎn)
void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color);//在指定位置畫一條線
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color);//在指定位置畫一個(gè)矩形
void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color);//在指定位置畫一個(gè)圓
void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//顯示漢字串
void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//顯示單個(gè)12x12漢字
void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//顯示單個(gè)16x16漢字
void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//顯示單個(gè)24x24漢字
void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//顯示單個(gè)32x32漢字
void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode);//顯示一個(gè)字符
void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode);//顯示字符串
u32 mypow(u8 m,u8 n);//求冪
void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey);//顯示整數(shù)變量
void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey);//顯示兩位小數(shù)變量
void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[]);//顯示圖片
//畫筆顏色
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40 //棕色
#define BRRED 0XFC07 //棕紅色
#define GRAY 0X8430 //灰色
#define DARKBLUE 0X01CF //深藍(lán)色
#define LIGHTBLUE 0X7D7C //淺藍(lán)色
#define GRAYBLUE 0X5458 //灰藍(lán)色
#define LIGHTGREEN 0X841F //淺綠色
#define LGRAY 0XC618 //淺灰色(PANNEL),窗體背景色
#define LGRAYBLUE 0XA651 //淺灰藍(lán)色(中間層顏色)
#define LBBLUE 0X2B12 //淺棕藍(lán)色(選擇條目的反色)
在使用的時(shí)候只需要看后面的中文注釋
去調(diào)用
對(duì)應(yīng)的函數(shù)即可,非常方便使用
但是如果需要顯示文字
和圖片
的話只是直接調(diào)用上面的函數(shù)還不夠,漢字?jǐn)?shù)組
存儲(chǔ)的lcdfont.h
文件中只包含了中英文字母
、數(shù)字
、符號(hào)
以及非常少量的中文數(shù)組
,中文數(shù)組存儲(chǔ)在以下幾個(gè)數(shù)組中,按照相同的格式自行添加進(jìn)去即可
中文漢字?jǐn)?shù)組
typedef struct
{
unsigned char Index[2];
unsigned char Msk[24];
}typFNT_GB12;
const typFNT_GB12 tfont12[]={
"優(yōu)",0x24,0x01,0x24,0x02,0x22,0x00,0xFA,0x07,0xA3,0x00,0xA2,0x00,0xA2,0x00,0xA2,0x00,
0x92,0x00,0x92,0x04,0x8A,0x04,0x06,0x07,
"信",0x44,0x00,0x84,0x00,0xFA,0x07,0x02,0x00,0xF3,0x03,0x02,0x00,0xF2,0x03,0x02,0x00,
0xF2,0x03,0x12,0x02,0xF2,0x03,0x12,0x02,
"電",0x10,0x00,0x10,0x00,0xFF,0x01,0x11,0x01,0x11,0x01,0xFF,0x01,0x11,0x01,0x11,0x01,
0xFF,0x01,0x11,0x04,0x10,0x04,0xE0,0x07,
"子",0x00,0x00,0xFC,0x01,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0xFF,0x07,0x20,0x00,
0x20,0x00,0x20,0x00,0x20,0x00,0x38,0x00,
};
typedef struct
{
unsigned char Index[2];
unsigned char Msk[32];
}typFNT_GB16;
const typFNT_GB16 tfont16[]={
"優(yōu)",0x10,0x09,0x10,0x11,0x10,0x11,0x08,0x01,0xE8,0x7F,0x0C,0x05,0x0C,0x05,0x0A,0x05,
0x09,0x05,0x08,0x05,0x88,0x04,0x88,0x44,0x88,0x44,0x48,0x44,0x48,0x78,0x28,0x00,
"信",0x10,0x02,0x10,0x04,0xD0,0x7F,0x08,0x00,0x08,0x00,0x8C,0x3F,0x0C,0x00,0x0A,0x00,
0x89,0x3F,0x08,0x00,0x08,0x00,0x88,0x3F,0x88,0x20,0x88,0x20,0x88,0x3F,0x88,0x20,
"電",0x80,0x00,0x80,0x00,0x80,0x00,0xFC,0x1F,0x84,0x10,0x84,0x10,0x84,0x10,0xFC,0x1F,
0x84,0x10,0x84,0x10,0x84,0x10,0xFC,0x1F,0x84,0x50,0x80,0x40,0x80,0x40,0x00,0x7F,
"子",0x00,0x00,0xFE,0x1F,0x00,0x08,0x00,0x04,0x00,0x02,0x80,0x01,0x80,0x00,0xFF,0x7F,
0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xA0,0x00,0x40,0x00,
};
數(shù)組名字里面的GB12
和GB16
代表了12號(hào)字體
和16號(hào)字體
的數(shù)組,文件中也有24號(hào)
和32號(hào)
圖片
圖片存儲(chǔ)在image.h
文件中,圖片文件中的內(nèi)容比較簡單,一個(gè)純數(shù)組取模放進(jìn)去的
const unsigned char YXDZ_logo[32768] = { /* 0X10,0X10,0X00,0X80,0X00,0X80,0X01,0X1B, */
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
...................
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
};
記得在數(shù)組前面加const
就行
其他單片機(jī)驅(qū)動(dòng)
使用其他單片機(jī)編寫的代碼顯示的效果與上面的STM32
的相同,都是一張圖片,空間不夠的單片機(jī)只是顯示了一張小一點(diǎn)的圖片。
51單片機(jī)
51單片機(jī)程序由stm32的移植過去的,所以是一樣的使用,唯一的區(qū)別是51單片機(jī)空間小顯示不了大圖片,速度也比較慢。
arduino/ESP32
arduino
和ESP32
的代碼也是從原來STM32
的移植過去的,不過因?yàn)榫幾g器不同做了比較多的修改,總體上做的函數(shù)接口
和stm32
的是一致的并沒有做修改,由于數(shù)據(jù)兼容性不一樣在調(diào)用漢字顯示之類的功能的時(shí)候需要對(duì)數(shù)據(jù)做類型轉(zhuǎn)換,如下所示的中文漢字顯示函數(shù)調(diào)用。
LCD_ShowChinese(0,0,(unsigned char*)"優(yōu)信電子",RED,WHITE,32,0);
其他的參數(shù)沒發(fā)現(xiàn)有哪里和STM32函數(shù)上的不同,由于是移植,并沒有像C++一樣做庫進(jìn)行使用(還是懶。。。),所以函數(shù)修改還是在文件中進(jìn)行修改,而不是聲明的方式去定義使用引腳,用戶修改使用引腳的話只需要打開lcd_init.h文件找到下面的代碼段,看到了自然知道怎么進(jìn)行修改。
//-----------------LCD端口定義----------------
#define CS 5
#define RST 33
#define DC 27
#define SDA 23
#define SCL 18
#define BLK 22
沒有采用硬件SPI,所以速度沒有想象中的那么快,確實(shí)肉眼可見的慢了很多。
總結(jié)
后續(xù)我們將編寫、移植或者收集測試好的一些屏幕代碼分享相應(yīng)的一些LCD、OLED等顯示器件的驅(qū)動(dòng)案例,也由衷的感謝中景園開源了如此優(yōu)秀的LCD驅(qū)動(dòng)庫非常方便了用戶的使用與移植,供大家共同學(xué)習(xí)進(jìn)步,前行路上,優(yōu)信與大家同在,歡迎一鍵三連,感謝各位大佬!
審核編輯 黃宇
-
嵌入式
+關(guān)注
關(guān)注
5140文章
19524瀏覽量
314755 -
STM32
+關(guān)注
關(guān)注
2289文章
11011瀏覽量
362276 -
Arduino
+關(guān)注
關(guān)注
188文章
6490瀏覽量
190072
發(fā)布評(píng)論請(qǐng)先 登錄
GC9A01-TFT屏幕驅(qū)動(dòng)(整理有stm32/51單片機(jī)/arduino等驅(qū)動(dòng)代碼)

基于51/32單片機(jī)按鍵控制步進(jìn)電機(jī)正反轉(zhuǎn),A4988驅(qū)動(dòng)
單片機(jī)學(xué)習(xí)—C51源代碼和Proteus仿真文件
51單片機(jī)中為什么很少出現(xiàn)printf的身影

物聯(lián)網(wǎng)行業(yè)中的TFT-LCD屏驅(qū)動(dòng)_ST7735S設(shè)計(jì)詳解

51單片機(jī)驅(qū)動(dòng)
stm32和51單片機(jī)的區(qū)別是什么
燒錄器怎么連接單片機(jī)
stm32單片機(jī)的優(yōu)勢有哪些?
其利天下技術(shù)·STM32和51的區(qū)別·無刷電機(jī)驅(qū)動(dòng)開發(fā)

基于51單片機(jī)直流電機(jī)驅(qū)動(dòng)測速電路圖及程序及元件清單
第五講:51單片機(jī)+RA8889驅(qū)動(dòng)控制彩屏 完整源碼說明 【 源碼v1.2 】
第四講:單片機(jī)STC89C52+RA8889驅(qū)動(dòng)控制彩屏 代碼移植范例(包含API接口)

第三講:單片機(jī)STC89C52+RA8889驅(qū)動(dòng)控制彩屏 代碼的壓縮(Keil編譯器)

評(píng)論