日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 單片機
[導讀]一、用STM32控制TFTLCD顯示的編程方法,在編程驅動TFTLCD液晶顯示器之前,我們先熟悉以下概念:1、色彩深度,這是一個與TFTLCD顯存對應的概念;所謂色彩深度就是每個像素點需要多少位的RGB 數(shù)據(jù)表示該點的顏色信息。

一、用STM32控制TFTLCD顯示的編程方法,在編程驅動TFTLCD液晶顯示器之前,我們先熟悉以下概念:

1、色彩深度,這是一個與TFTLCD顯存對應的概念;所謂色彩深度就是每個像素點需要多少位的RGB

數(shù)據(jù)表示該點的顏色信息。注意,不同的TFTLCD顯示器的RGB的對應關系不一樣,這個可以在LCD

控制芯片手冊中找到答案。

例: 某LCD顯示支持8、16、24位RGB,這些位數(shù)是指該像素點顏色由8、16、24位RGB構成,但是

RGB三種顏色各占的位數(shù)可以查看數(shù)據(jù)手冊。

2、TFTLCD的操作分為兩種:

A、對控制寄存器的讀寫操作(即程序員將要操作LCD顯存寄存器的地址設置成可讀或者可寫)。

B、對顯存寄存器的讀寫操作(即讀寫LCD顯存寄存器)。

3、TFTLCD有一個索引寄存器,對控制寄存器操作前,需要對索引寄存器進行定入操作,用以指明

寄存器讀寫是針對那個寄存器的,具體操作步驟如下:

RS為低電平狀態(tài)下,寫入兩個字節(jié)的數(shù)據(jù),第一個字節(jié)為零,第二個字節(jié)為寄存器索引值。

RS為高電平狀態(tài)下,讀取兩個字節(jié)數(shù)據(jù),第一個字節(jié)為高八位,第二個字節(jié)為低八位。

二、實驗平臺STM32F103RCT6與ILI9341 TFTLCD驅動模塊

硬件采用 16 位的并方式與外部連接,之所以不采用 8 位的方式,是因為彩屏的數(shù)據(jù)量比較大,

尤其在顯示圖片的時候,如果用 8 位數(shù)據(jù)線,就會比 16 位方式慢一倍以上,我們當然希望速

度越快越好,所以我們選擇 16 位的80 并口。有如下一些信號線:
CS:TFTLCD 片選信號。
WR:向 TFTLCD 寫入數(shù)據(jù)。
RD:從 TFTLCD 讀取數(shù)據(jù)。
D[15:0]:16 位雙向數(shù)據(jù)線。
RST:硬復位 TFTLCD。
RS:命令/數(shù)據(jù)標志(0,讀寫命令;1,讀寫數(shù)據(jù))。

在 16 位模式下,ILI9341 采用 RGB565 格式存儲顏色數(shù)據(jù),接下來看一下ILI9341 的幾個重要命令

1、0XD3,用于讀取 LCD 控制器的 ID。

2、0X36,這是存儲訪問控制指令,可以控制 ILI9341 存儲器的讀寫方向,簡單的說,就是在連續(xù)寫

GRAM 的時候,可以控制 GRAM 指針的增長方向,從而控制顯示方式。

3、0X2A,這是列地址設置指令,在從左到右,從上到下的掃描方式(默認)下面,該指令用于設置

橫坐標(x 坐標)。

4、0X2B,是頁地址設置指令,在從左到右,從上到下的掃描方式(默認)下面,該指令用于設置縱

坐標(y 坐標)。

5、0X2C,該指令是寫 GRAM 指令,在發(fā)送該指令之后,我們便可以往 LCD的 GRAM 里面寫入顏色

數(shù)據(jù)了,該指令支持連續(xù)寫,在收到指令 0X2C 之后,數(shù)據(jù)有效位寬變?yōu)?16 位,我們可以連續(xù)寫入

LCDGRAM 值,而 GRAM 的地址將根據(jù) MY/MX/MV 設置的掃描方向進行自增。

6、0X2E, 該指令是讀 GRAM 指令,用于讀取 ILI9341 的顯存(GRAM)。



三、軟件編程

lcd.h 里面的一個重要結構體:

//LCD重要參數(shù)集
typedef struct
{
u16 width;//LCD 寬度
u16 height;//LCD 高度
u16 id;//LCD ID
u8 dir;//橫屏還是豎屏控制:0,豎屏;1,橫屏。
u16wramcmd;//開始寫gram指令
u16 setxcmd;//設置x坐標指令
u16 setycmd;//設置y坐標指令
}_lcd_dev;

//LCD參數(shù)
extern _lcd_dev lcddev; //管理LCD重要參數(shù)


該結構體用于保存一些 LCD 重要參數(shù)信息,比如 LCD 的長寬、LCD ID(驅動 IC 型號)、
LCD 橫豎屏狀態(tài)等,這個結構體雖然占用了 14 個字節(jié)的內存,但是卻可以讓我們的驅動函數(shù)
支持不同尺寸的 LCD,同時可以實現(xiàn) LCD 橫豎屏切換等重要功能,所以還是利大于弊的。有
了以上了解,下面我們開始介紹 ILI93xx.c 里面的一些重要函數(shù)。
第一個是 LCD_WR_DATA 函數(shù),該函數(shù)在 lcd.h 里面,通過宏定義的方式申明。該函數(shù)通
過 80 并口向 LCD 模塊寫入一個 16 位的數(shù)據(jù),使用頻率是最高的,這里我們采用了宏定義的方
式,以提高速度。其代碼如下

//寫數(shù)據(jù)函數(shù)
#define LCD_WR_DATA(data){
LCD_RS_SET;
LCD_CS_CLR;
DATAOUT(data);
LCD_WR_CLR;
LCD_WR_SET;
LCD_CS_SET;
}


//寫數(shù)據(jù)函數(shù)
//可以替代LCD_WR_DATAX宏,拿時間換空間.
//data:寄存器值
void LCD_WR_DATAX(u16 data)
{
LCD_RS_SET;
LCD_CS_CLR;
DATAOUT(data);
LCD_WR_CLR;
LCD_WR_SET;
LCD_CS_SET;
}


第三個是 LCD_WR_REG 函數(shù),該函數(shù)是通過 8080 并口向 LCD 模塊寫入寄存器命令,因
為該函數(shù)使用頻率不是很高,我們不采用宏定義來做(宏定義占用 FLASH 較多),通過 LCD_RS
來標記是寫入命令(LCD_RS=0)還是數(shù)據(jù)(LCD_RS=1)。該函數(shù)代碼如下:
//寫寄存器函數(shù)

//data:寄存器值
void LCD_WR_REG(u16 data)
{
LCD_RS_CLR;//寫地址
LCD_CS_CLR;
DATAOUT(data);
LCD_WR_CLR;
LCD_WR_SET;
LCD_CS_SET;
}


既然有寫寄存器命令函數(shù),那就有讀寄存器數(shù)據(jù)函數(shù)。接下來介紹 LCD_RD_DATA 函數(shù),
該函數(shù)用來讀取 LCD 控制器的寄存器數(shù)據(jù)(非 GRAM 數(shù)據(jù)),該函數(shù)代碼如下:

//讀LCD數(shù)據(jù)
//返回值:讀到的值
u16 LCD_RD_DATA(void)
{
u16 t;
GPIOB->CRL=0X88888888; //PB0-7 上拉輸入
GPIOB->CRH=0X88888888; //PB8-15 上拉輸入
GPIOB->ODR=0X0000; //全部輸出0


LCD_RS_SET;
LCD_CS_CLR;
//讀取數(shù)據(jù)(讀寄存器時,并不需要讀2次)
LCD_RD_CLR;
if(lcddev.id==0X8989)delay_us(2);//FOR 8989,延時2us
t=DATAIN;
LCD_RD_SET;
LCD_CS_SET;


GPIOB->CRL=0X33333333; //PB0-7 上拉輸出
GPIOB->CRH=0X33333333; //PB8-15 上拉輸出
GPIOB->ODR=0XFFFF; //全部輸出高
return t;
}


以上 4 個函數(shù),用于實現(xiàn) LCD 基本的讀寫操作,接下來,我們介紹 2 個 LCD 寄存器操作
的函數(shù),LCD_WriteReg 和 LCD_ReadReg,這兩個函數(shù)代碼如下:
//寫寄存器

//寫寄存器
//LCD_Reg:寄存器編號
//LCD_RegValue:要寫入的值
void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue)
{
LCD_WR_REG(LCD_Reg);
LCD_WR_DATA(LCD_RegValue);
}


//讀寄存器
//LCD_Reg:寄存器編號
//返回值:讀到的值
u16 LCD_ReadReg(u16 LCD_Reg)
{
LCD_WR_REG(LCD_Reg); //寫入要讀的寄存器號
return LCD_RD_DATA();
}

這兩個函數(shù)函數(shù)十分簡單,LCD_WriteReg 用于向 LCD 指定寄存器寫入指定數(shù)據(jù),而
LCD_ReadReg 則用于讀取指定寄存器的數(shù)據(jù),這兩個函數(shù),都只帶一個參數(shù)/返回值,所以,
在有多個參數(shù)操作(讀取/寫入)的時候,就不適合用這兩個函數(shù)了,得另外實現(xiàn)。
第七個要介紹的函數(shù)是坐標設置函數(shù),該函數(shù)代碼如下:

//設置光標位置
//Xpos:橫坐標
//Ypos:縱坐標
void LCD_SetCursor(u16 Xpos, u16 Ypos)
{
if(lcddev.id==0X9341||lcddev.id==0X5310)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(Xpos>>8);
LCD_WR_DATA(Xpos&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(Ypos>>8);
LCD_WR_DATA(Ypos&0XFF);
}else if(lcddev.id==0X6804)
{
if(lcddev.dir==1)Xpos=lcddev.width-1-Xpos;//橫屏時處理
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(Xpos>>8);
LCD_WR_DATA(Xpos&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(Ypos>>8);
LCD_WR_DATA(Ypos&0XFF);
}else if(lcddev.id==0X5510)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(Xpos>>8);
LCD_WR_REG(lcddev.setxcmd+1);
LCD_WR_DATA(Xpos&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(Ypos>>8);
LCD_WR_REG(lcddev.setycmd+1);
LCD_WR_DATA(Ypos&0XFF);
}else
{
if(lcddev.dir==1) Xpos=lcddev.width-1-Xpos;//橫屏其實就是調轉x,y坐標
LCD_WriteReg(lcddev.setxcmd, Xpos);
LCD_WriteReg(lcddev.setycmd, Ypos);
}
}

該函數(shù)實現(xiàn)將 LCD 的當前操作點設置到指定坐標(x,y)。因為不同 LCD 的設置方式不一定
完全一樣,所以代碼里面有好幾個判斷,對不同的驅動 IC 進行不同的設置。
接下來我們介紹第八個函數(shù):畫點函數(shù)。該函數(shù)實現(xiàn)代碼如下:

//畫點
//x,y:坐標
//POINT_COLOR:此點的顏色
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetCursor(x,y);//設置光標位置
LCD_WriteRAM_Prepare();//開始寫入GRAM
LCD_WR_DATA(POINT_COLOR);
}
該函數(shù)實現(xiàn)比較簡單,就是先設置坐標,然后往坐標寫顏色。其中 POINT_COLOR 是我們
定義的一個全局變量,用于存放畫筆顏色,順帶介紹一下另外一個全局變量: BACK_COLOR,
該變量代表 LCD 的背景色。LCD_DrawPoint 函數(shù)雖然簡單,但是至關重要,其他幾乎所有上
層函數(shù),都是通過調用這個函數(shù)實現(xiàn)的。
有了畫點,當然還需要有讀點的函數(shù),第九個介紹的函數(shù)就是讀點函數(shù),用于讀取 LCD
的 GRAM, 這里說明一下,為什么 OLED 模塊沒做讀 GRAM 的函數(shù),而這里做了。因為 OLED
模塊是單色的,所需要全部 GRAM 也就 1K 個字節(jié),而 TFTLCD 模塊為彩色的,點數(shù)也比 OLED
模塊多很多,以 16 位色計算, 一款 320×240 的液晶,需要 320×240×2 個字節(jié)來存儲顏色值,
也就是也需要 150K 字節(jié),這對任何一款單片機來說,都不是一個小數(shù)目了。而且我們在圖形
疊加的時候,可以先讀回原來的值,然后寫入新的值,在完成疊加后,我們又恢復原來的值。
這樣在做一些簡單菜單的時候,是很有用的。這里我們讀取 TFTLCD 模塊數(shù)據(jù)的函數(shù)為
LCD_ReadPoint,該函數(shù)直接返回讀到的 GRAM 值。該函數(shù)使用之前要先設置讀取的 GRAM
地址,通過 LCD_SetCursor 函數(shù)來實現(xiàn)。LCD_ReadPoint 的代碼如下:

//讀取個某點的顏色值
//x,y:坐標
//返回值:此點的顏色
u16 LCD_ReadPoint(u16 x,u16 y)
{
u16 r,g,b;
if(x>=lcddev.width||y>=lcddev.height)return 0;//超過了范圍,直接返回
LCD_SetCursor(x,y);
if(lcddev.id==0X9341||lcddev.id==0X6804||lcddev.id==0X5310)LCD_WR_REG(0X2E);//9341/6804/5310發(fā)送讀GRAM指令
else if(lcddev.id==0X5510)LCD_WR_REG(0X2E00);//5510 發(fā)送讀GRAM指令
else LCD_WR_REG(R34); //其他IC發(fā)送讀GRAM指令
GPIOB->CRL=0X88888888; //PB0-7 上拉輸入
GPIOB->CRH=0X88888888; //PB8-15 上拉輸入
GPIOB->ODR=0XFFFF; //全部輸出高


LCD_RS_SET;
LCD_CS_CLR;
//讀取數(shù)據(jù)(讀GRAM時,第一次為假讀)
LCD_RD_CLR;
delay_us(1);//延時1us
LCD_RD_SET;
//dummy READ
LCD_RD_CLR;
delay_us(1);//延時1us
r=DATAIN; //實際坐標顏色
LCD_RD_SET;
if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)//9341/NT35310/NT35510要分2次讀出
{
LCD_RD_CLR;
b=DATAIN;//讀取藍色值
LCD_RD_SET;
g=r&0XFF;//對于9341,第一次讀取的是RG的值,R在前,G在后,各占8位
g<<=8;
}else if(lcddev.id==0X6804)
{
LCD_RD_CLR;
LCD_RD_SET;
r=DATAIN;//6804第二次讀取的才是真實值
}
LCD_CS_SET;
GPIOB->CRL=0X33333333;//PB0-7 上拉輸出
GPIOB->CRH=0X33333333;//PB8-15 上拉輸出
GPIOB->ODR=0XFFFF; //全部輸出高
if(lcddev.id==0X9325||lcddev.id==0X4535||lcddev.id==0X4531||lcddev.id==0X8989||lcddev.id==0XB505)

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

在嵌入式開發(fā)中,STM32的時鐘系統(tǒng)因其靈活性和復雜性成為開發(fā)者關注的焦點。然而,看似簡單的時鐘配置背后,隱藏著諸多易被忽視的陷阱,輕則導致系統(tǒng)不穩(wěn)定,重則引發(fā)硬件損壞。本文從時鐘源選擇、PLL配置、總線時鐘分配等關鍵環(huán)...

關鍵字: STM32 時鐘系統(tǒng)

在嵌入式系統(tǒng)開發(fā)中,STM32系列微控制器的內部溫度傳感器因其低成本、高集成度特性,廣泛應用于設備自檢、環(huán)境監(jiān)測等場景。然而,受芯片工藝差異和電源噪聲影響,其原始數(shù)據(jù)存在±1.5℃的固有誤差。本文從硬件配置、校準算法、軟...

關鍵字: STM32 溫度傳感器

在能源效率與智能化需求雙重驅動下,AC-DC轉換器的數(shù)字控制技術正經歷從傳統(tǒng)模擬方案向全數(shù)字架構的深刻變革?;赟TM32微控制器的PFM(脈沖頻率調制)+PWM(脈沖寬度調制)混合調制策略,結合動態(tài)電壓調整(Dynam...

關鍵字: AC-DC STM32

當前智能家居產品需求不斷增長 ,在這一背景下 ,對現(xiàn)有澆花裝置缺陷進行了改進 ,設計出基于STM32單片機的全 自動家用澆花機器人。該設計主要由機械結構和控制系統(tǒng)構成 ,機械結構通過麥克納姆輪底盤與噴灑裝置的結合實現(xiàn)機器...

關鍵字: STM32 麥克納姆輪 安全可靠 通過性強

用c++編程似乎是讓你的Arduino項目起步的障礙嗎?您想要一種更直觀的微控制器編程方式嗎?那你需要了解一下Visuino!這個圖形化編程平臺將復雜電子項目的創(chuàng)建變成了拖動和連接塊的簡單任務。在本文中,我們將帶您完成使...

關鍵字: Visuino Arduino ESP32 STM32

基于STM32與LoRa技術的無線傳感網絡憑借其低功耗、廣覆蓋、抗干擾等特性,成為環(huán)境監(jiān)測、工業(yè)自動化等場景的核心解決方案。然而,如何在復雜電磁環(huán)境中實現(xiàn)高效休眠調度與動態(tài)信道優(yōu)化,成為提升網絡能效與可靠性的關鍵挑戰(zhàn)。本...

關鍵字: STM32 LoRa

在實時控制系統(tǒng)、高速通信協(xié)議處理及高精度數(shù)據(jù)采集等對時間敏感的應用場景中,中斷響應延遲的優(yōu)化直接決定了系統(tǒng)的可靠性與性能上限。STM32系列微控制器憑借其靈活的嵌套向量中斷控制器(NVIC)、多通道直接內存訪問(DMA)...

關鍵字: STM32 DMA

數(shù)字電源技術向高功率密度、高效率與高動態(tài)響應方向加速演進,STM32微控制器憑借其基于DSP庫的算法加速能力與對LLC諧振變換器的精準控制架構,成為優(yōu)化電源動態(tài)性能的核心平臺。相較于傳統(tǒng)模擬控制或通用型數(shù)字控制器,STM...

關鍵字: STM32 數(shù)字電源

STM32微控制器憑借其針對電機控制場景的深度優(yōu)化,成為高精度、高可靠性驅動系統(tǒng)的核心選擇。相較于通用型MCU,STM32在電機控制領域的核心優(yōu)勢集中體現(xiàn)在FOC(磁場定向控制)算法的硬件加速引擎與PWM死區(qū)時間的動態(tài)補...

關鍵字: STM32 電機控制

無線充電技術加速滲透消費電子與汽車電子領域,基于Qi協(xié)議的無線充電發(fā)射端開發(fā)成為智能設備能量補給的核心課題。傳統(tǒng)模擬控制方案存在響應滯后、參數(shù)調整困難等問題,而基于STM32的數(shù)字PID控制結合FOD(Foreign O...

關鍵字: STM32 無線充電
關閉