|
點(diǎn)擊上方「嵌入式實(shí)驗(yàn)基地」,選擇「置頂公眾號」第一時間查看嵌入式筆記!
sul4tpmcmit64047053639.png (100.54 KB, 下載次數(shù): 1)
下載附件
保存到相冊
sul4tpmcmit64047053639.png
2024-10-26 05:24 上傳
??在日常開發(fā)項(xiàng)目中,顯示屏是經(jīng)常使用的一個部件,顯示屏的種類也是多種多樣,但對于開發(fā)者來說,主要關(guān)心的是顯示屏所用到的驅(qū)動芯片,本次給小伙伴們帶來的是 STM32 下的 HAL 庫硬件 SPI 驅(qū)動 320*240 分辨率的 TFT-LCD,LCD 顯示屏驅(qū)動芯片為 ST7789,一步步實(shí)現(xiàn)如何驅(qū)動此類驅(qū)動芯片的 LCD 屏幕,話不多說,上干貨!
完成目標(biāo)1、cubemx配置硬件SPI
2、驅(qū)動240*320分辨率LCD顯示屏(驅(qū)動芯片為ST7789)
硬件環(huán)境1、STM32F103C8T6(自設(shè)計(jì))
2、ST7789驅(qū)動LCD顯示屏
軟件環(huán)境1、cubemx
2、keil5
一、cubemx配置硬件SPI及LCD相關(guān)引腳1.1 時鐘配置
??第一步仍然是時鐘配置,由于板子上設(shè)計(jì)沒有預(yù)留外部晶振,我使用的是內(nèi)部RC振蕩器,內(nèi)部RC振蕩器只能配置到64MHZ,如下,如果你使用的是外部晶振,最大到72MHZ
s5vuyshfdjg64047053740.png (136.76 KB, 下載次數(shù): 0)
下載附件
保存到相冊
s5vuyshfdjg64047053740.png
2024-10-26 05:24 上傳
1.2 LCD與STM32硬件連接關(guān)系
LCDMCULCD-RSTPB1LCD-CSPB0LCD-DCPA4LCD-MOSIPA7LCD-CLKPA5LCD-LDE+VCC-3.3(可接IO控制)LCD-LDE-GNDLCD-VCCVCC-3.3VLCD-GNDGND1.3 LCD相關(guān)引腳配置
??本次使用的是SPI1,對SPI1的引腳及參數(shù)進(jìn)行配置,相關(guān)IO初始化狀態(tài)可以根據(jù)需要進(jìn)行配置u,比如CS引腳,拉低有效,初始化我們可以配置為高,根據(jù)自己需要進(jìn)行配置即可
mntl1p30ixy64047053840.png (90.21 KB, 下載次數(shù): 0)
下載附件
保存到相冊
mntl1p30ixy64047053840.png
2024-10-26 05:24 上傳
lvcsqi24kln64047053940.png (73.35 KB, 下載次數(shù): 0)
下載附件
保存到相冊
lvcsqi24kln64047053940.png
2024-10-26 05:24 上傳
0npskxjrzus64047054040.png (56.8 KB, 下載次數(shù): 0)
下載附件
保存到相冊
0npskxjrzus64047054040.png
2024-10-26 05:24 上傳
??小伙伴們有沒有遇到過配置完發(fā)現(xiàn)不能仿真,這里需要設(shè)置一下,根據(jù)自己的仿真器接口進(jìn)行配置,是SWD模式還是JTAG模式
lpepn34m0du64047054140.png (103.44 KB, 下載次數(shù): 0)
下載附件
保存到相冊
lpepn34m0du64047054140.png
2024-10-26 05:24 上傳
生成工程配置,配置完之后,直接點(diǎn)擊生成即可,注意工程路徑不要有中文,記得以前可以有,不知道什么時候有的臭毛病...只能按照做了
kkgf3v2xelc64047054240.png (55.39 KB, 下載次數(shù): 0)
下載附件
保存到相冊
kkgf3v2xelc64047054240.png
2024-10-26 05:24 上傳
zgxrpugd5ri64047054340.png (56.22 KB, 下載次數(shù): 1)
下載附件
保存到相冊
zgxrpugd5ri64047054340.png
2024-10-26 05:24 上傳
二、代碼編寫??先定義LCD相關(guān)引腳,CS、RST、DC
#define LCD_REST_LOW() HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET);
#define LCD_REST_HIGH() HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET);
#define LCD_DC_LOW() HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_RESET);
#define LCD_DC_HIGH() HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET);
#define LCD_CS_LOW() HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
#define LCD_CS_HIGH() HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
#define LCD_WR_RS(n) (n?HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_RESET))
??定義用到的幾個基本函數(shù)
/**
* @brief 寫16位的數(shù)據(jù)(兩個字節(jié))到LCD
* @param dat —— 需要發(fā)送的16bit數(shù)據(jù)
* @return none
*/
void LCD_Write_2Bytes(const uint16_t dat)
{
uint8_t data[2] = {0};
data[0] = dat >> 8;
LCD_data_write(data[0]);
data[1] = dat;
LCD_data_write(data[1]);
// LCD_SPI_Send(data, 2);
}
void LCD_command_write(uint8_t command)
{ // 寫命令
LCD_DC_LOW();
LCD_CS_LOW();
lcd_SendBytes(command);
LCD_CS_HIGH();
}
void LCD_data_write(uint8_t data)
{ //寫數(shù)據(jù)
LCD_DC_HIGH();
LCD_CS_LOW();
lcd_SendBytes(data);
LCD_CS_HIGH();
}
void delay_lcd(unsigned int time)
{
while (time)
{
time--;
time--;
time--;
time--;
}
}
void LCD_Reset(void)
{
LCD_REST_HIGH();
delay_lcd(1000);
LCD_REST_LOW();
delay_lcd(10000);
LCD_REST_HIGH();
delay_lcd(10000);
LCD_CS_HIGH();
}
LCD行列設(shè)置
//========================================================
//CASET (2Ah): Column Address Set
//RASET (2Bh): Row Address Set
//x1,y1:起始地址,x2,y2:終點(diǎn)地址
//========================================================
void lcd_set_address(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
LCD_command_write(0x2a);
LCD_data_write(x1 >> 8);
LCD_data_write(x1);
LCD_data_write(x2 >> 8);
LCD_data_write(x2);
LCD_command_write(0x2b);
LCD_data_write(y1 >> 8);
LCD_data_write(y1);
LCD_data_write(y2 >> 8);
LCD_data_write(y2);
LCD_command_write(0x2C); // write_ram
}
LCD初始化代碼,這部分主要是參考網(wǎng)上已經(jīng)完成的,相關(guān)配置可以在手冊具體查看
void lcd_init(void)
{
LCD_CS_HIGH();
LCD_Reset();
/************* display Setting *************/
LCD_command_write(0x01);
delay_lcd(10000);
LCD_command_write(LCD_CMD_SLPOUT);
delay_lcd(10000);
//修改此處,可以改變屏幕的顯示方向,橫屏,豎屏等
LCD_command_write(LCD_CMD_MADCTL); // 0x36 ///
LCD_data_write(0x00); //50//40//C0
LCD_command_write(LCD_CMD_COLMOD); // 0x3A ///
LCD_data_write(0x05); /// 16bit/pixel
/*********** Frame Rate Setting ***********/
LCD_command_write(LCD_CMD_PORCTRL); //0xB2 ///
LCD_data_write(0x0c); ///
LCD_data_write(0x0c); ///
LCD_data_write(0x00); ///
LCD_data_write(0x33); ///
LCD_data_write(0x33); ///
LCD_command_write(LCD_CMD_GCTRL); // 0xB7 ///
LCD_data_write(0x72); ///
LCD_command_write(LCD_CMD_VCOMS); // 0xBB ///
LCD_data_write(0x3d); ///
LCD_command_write(LCD_CMD_LCMCTRL); ///0xC0 ///
LCD_data_write(0x2c);
LCD_command_write(LCD_CMD_VDVVRHEN); //0xC2 ///
LCD_data_write(0x01);
LCD_data_write(0xFF);
/* VRH Set */
LCD_command_write(LCD_CMD_VRHS); //0xC3
LCD_data_write(0x19);
/* VDV Set */
LCD_command_write(LCD_CMD_VDVS); //0xC4
LCD_data_write(0x20);
LCD_command_write(LCD_CMD_FRCTRL2); // 0xC6 ///
LCD_data_write(0x0f); ///
LCD_command_write(LCD_CMD_PWCTRL1); // 0xD0 ///
LCD_data_write(0xa4);
LCD_data_write(0xa1); ///
/* Positive Voltage Gamma Control */
LCD_command_write(0xE0);
LCD_data_write(0xD0);
LCD_data_write(0x04);
LCD_data_write(0x0D);
LCD_data_write(0x11);
LCD_data_write(0x13);
LCD_data_write(0x2B);
LCD_data_write(0x3F);
LCD_data_write(0x54);
LCD_data_write(0x4C);
LCD_data_write(0x18);
LCD_data_write(0x0D);
LCD_data_write(0x0B);
LCD_data_write(0x1F);
LCD_data_write(0x23);
/* Negative Voltage Gamma Control */
LCD_command_write(0xE1);
LCD_data_write(0xD0);
LCD_data_write(0x04);
LCD_data_write(0x0C);
LCD_data_write(0x11);
LCD_data_write(0x13);
LCD_data_write(0x2C);
LCD_data_write(0x3F);
LCD_data_write(0x44);
LCD_data_write(0x51);
LCD_data_write(0x2F);
LCD_data_write(0x1F);
LCD_data_write(0x1F);
LCD_data_write(0x20);
LCD_data_write(0x23);
// LCD_command_write( 0x21); ///
//LCD_command_write( 0x13);
//LCD_InitSequence();
//Display_logo();
// lcd_clear(LCD_DISP_RED);
lcd_clear(LCD_DISP_WRITE);
LCD_command_write(LCD_CMD_DISPON); ///
}
常用顏色定義,為RGB565格式,其他顏色可以自己改變配比
/************** 顏色(RGB 5,6,5) **************/
#define LCD_DISP_RED 0xF800 //先高字節(jié),后低字節(jié)
#define LCD_DISP_GREEN 0x07E0
#define LCD_DISP_BLUE 0x001F
#define LCD_DISP_WRITE 0xFFFF
#define LCD_DISP_BLACK 0x0000
#define LCD_DISP_GRAY 0xEF5D
#define LCD_DISP_GRAY75 0x39E7
#define LCD_DISP_GRAY50 0x7BEF
#define LCD_DISP_GRAY25 0xADB5
LCD清屏,可以填充指定的顏色
//========================================================
//LCD清屏 color:要寫入的顏色
//先關(guān)顯示,等所有的數(shù)據(jù)寫入到RAM后,再打開顯示
//========================================================
void lcd_clear(uint16_t color)
{
uint16_t i, j;
LCD_command_write(0x2A);
LCD_data_write(0);
LCD_data_write(0);
LCD_data_write(0);
LCD_data_write(240);
LCD_command_write(0X2B);
LCD_data_write(0);
LCD_data_write(0);
LCD_data_write(0X01);
LCD_data_write(0X40);
LCD_command_write(0X2C);
for (i = 0; i 240; i++)
{
for (j = 0; j 320; j++)
{
LCD_data_write(color >> 8);
LCD_data_write(color);
}
}
lcd_display_on(); /* 開LCD顯示 */
}
??還有一些打點(diǎn)、劃線、畫圓等函數(shù),就不再一一介紹了,編寫測試代碼,刷屏,畫圓、畫矩形、顯示漢字,一氣呵成,直接來看演示視頻吧~
后面會分享更多有意思的顯示小項(xiàng)目,包括界面等的設(shè)計(jì),敬請期待吧!
本次的介紹就到這里啦,后面有更精彩的內(nèi)容,歡迎大家持續(xù)關(guān)注嵌入式實(shí)驗(yàn)基地!
??如果你覺得對自己有幫助的話,給個贊,點(diǎn)個關(guān)注,點(diǎn)個在看,感謝前進(jìn)的道路上有你的陪伴!
2lxs3idwa4a64047054440.jpg (187.43 KB, 下載次數(shù): 0)
下載附件
保存到相冊
2lxs3idwa4a64047054440.jpg
2024-10-26 05:24 上傳
推薦閱讀
?開源電路のSTM32最小系統(tǒng)設(shè)計(jì)
?一種你值得擁有的簡單易實(shí)現(xiàn)的開關(guān)電路
?無線通訊之紅外通訊?DIY一個離線語音控制器
?HAL庫us延時的3種實(shí)現(xiàn)方式?邏輯分析儀的簡單使用介紹(附帶iic,uart,spi數(shù)據(jù)波形分析)
?ART-PI重力感應(yīng)無線智能小車第一彈----ART-PI擴(kuò)展板設(shè)計(jì)?ART-PI重力感應(yīng)無線智能小車第二彈----Onenet+wifi+L298N電機(jī)驅(qū)動?ART-PI重力感應(yīng)無線智能小車第三彈----RT-Studio+MPU6050+MQTT發(fā)布訂閱?STM32 DAC音頻輸出
?pcb設(shè)計(jì)基礎(chǔ)?OLED+ESP8266網(wǎng)絡(luò)小時鐘 |
|