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

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

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

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

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

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

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

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

2、TFTLCD的操作分為兩種:

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

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

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

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

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

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

二、實驗平臺STM32F103RCT6與ILI9341 TFTLCD驅(qū)動模塊

硬件采用 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:硬復(fù)位 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,這是列地址設(shè)置指令,在從左到右,從上到下的掃描方式(默認)下面,該指令用于設(shè)置

橫坐標(x 坐標)。

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

坐標(y 坐標)。

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

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

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

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



三、軟件編程

lcd.h 里面的一個重要結(jié)構(gòu)體:

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

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


該結(jié)構(gòu)體用于保存一些 LCD 重要參數(shù)信息,比如 LCD 的長寬、LCD ID(驅(qū)動 IC 型號)、
LCD 橫豎屏狀態(tài)等,這個結(jié)構(gòu)體雖然占用了 14 個字節(jié)的內(nèi)存,但是卻可以讓我們的驅(qū)動函數(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ù),該函數(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;//橫屏?xí)r處理
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;//橫屏其實就是調(diào)轉(zhuǎn)x,y坐標
LCD_WriteReg(lcddev.setxcmd, Xpos);
LCD_WriteReg(lcddev.setycmd, Ypos);
}
}

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

//畫點
//x,y:坐標
//POINT_COLOR:此點的顏色
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetCursor(x,y);//設(shè)置光標位置
LCD_WriteRAM_Prepare();//開始寫入GRAM
LCD_WR_DATA(POINT_COLOR);
}
該函數(shù)實現(xiàn)比較簡單,就是先設(shè)置坐標,然后往坐標寫顏色。其中 POINT_COLOR 是我們
定義的一個全局變量,用于存放畫筆顏色,順帶介紹一下另外一個全局變量: BACK_COLOR,
該變量代表 LCD 的背景色。LCD_DrawPoint 函數(shù)雖然簡單,但是至關(guān)重要,其他幾乎所有上
層函數(shù),都是通過調(diào)用這個函數(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ù)目了。而且我們在圖形
疊加的時候,可以先讀回原來的值,然后寫入新的值,在完成疊加后,我們又恢復(fù)原來的值。
這樣在做一些簡單菜單的時候,是很有用的。這里我們讀取 TFTLCD 模塊數(shù)據(jù)的函數(shù)為
LCD_ReadPoint,該函數(shù)直接返回讀到的 GRAM 值。該函數(shù)使用之前要先設(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)

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

在工業(yè)控制、音頻處理等高性能嵌入式場景中,某電機驅(qū)動項目通過混合使用寄存器操作與CMSIS-DSP庫,將PID控制周期從120μs縮短至38μs,系統(tǒng)響應(yīng)速度提升3倍。本文將揭秘這種"底層+高層"混合編程模式的核心技巧。

關(guān)鍵字: HAL STM32 寄存器

嵌入式系統(tǒng)開發(fā)手勢識別作為非接觸式人機交互的核心技術(shù),正從實驗室走向消費級應(yīng)用。然而,傳感器采集的原始信號常因電磁干擾、電源噪聲或機械抖動產(chǎn)生失真,導(dǎo)致識別準確率下降。本文以STM32微控制器與PAJ7620手勢識別傳感...

關(guān)鍵字: STM32 手勢識別 噪聲

在物聯(lián)網(wǎng)設(shè)備開發(fā)中,快速實現(xiàn)穩(wěn)定可靠的網(wǎng)絡(luò)通信是項目成功的關(guān)鍵。W5500作為一款集成硬件TCP/IP協(xié)議棧的以太網(wǎng)控制器,憑借其"開箱即用"的特性,可大幅縮短STM32平臺的網(wǎng)絡(luò)功能開發(fā)周期。本文通...

關(guān)鍵字: STM32 W5500

工業(yè)物聯(lián)網(wǎng)設(shè)備開發(fā)中,某智能電表項目曾因ADC采樣中斷響應(yīng)延遲導(dǎo)致數(shù)據(jù)丟失率高達15%。技術(shù)人員通過重構(gòu)DMA驅(qū)動架構(gòu),將數(shù)據(jù)搬運效率提升12倍,CPU占用率從38%降至3%,成功解決高速采樣場景下的實時性難題。這一案例...

關(guān)鍵字: STM32 DMA

工業(yè)機器人關(guān)節(jié)控制系統(tǒng)中,一個典型的伺服驅(qū)動器需要在100μs周期內(nèi)完成電流采樣、位置反饋、PID計算和PWM輸出等12項關(guān)鍵任務(wù)。當傳統(tǒng)固定優(yōu)先級調(diào)度導(dǎo)致機械臂出現(xiàn)0.3°的位置抖動時,某運動控制廠商通過引入混合排序算...

關(guān)鍵字: 電機控制 STM32

在STM32嵌入式系統(tǒng)開發(fā)中,排序算法的效率直接影響傳感器數(shù)據(jù)處理、通信協(xié)議解析等核心任務(wù)的實時性。傳統(tǒng)快速排序在部分有序數(shù)據(jù)場景下易退化為O(n2)時間復(fù)雜度,而單純依賴三數(shù)取中法優(yōu)化基準值選擇仍存在小規(guī)模數(shù)據(jù)效率不足...

關(guān)鍵字: STM32 傳感器

在智慧農(nóng)業(yè)的廣闊田野里,部署著數(shù)百個土壤濕度傳感器節(jié)點。這些節(jié)點通過LoRa模塊將數(shù)據(jù)傳輸至網(wǎng)關(guān),再由網(wǎng)關(guān)上傳至云端進行分析。然而,當暴雨來臨前,土壤濕度驟增的緊急數(shù)據(jù)若淹沒在常規(guī)監(jiān)測數(shù)據(jù)的洪流中,可能導(dǎo)致灌溉系統(tǒng)未能及...

關(guān)鍵字: STM32 無線通信 LoRa

在電池管理系統(tǒng)(BMS)中,電壓均衡是保障電池組性能與壽命的核心技術(shù)。由于電池單體存在制造差異,串聯(lián)使用過程中易出現(xiàn)電壓不一致現(xiàn)象,導(dǎo)致部分電池過充/過放,加速老化。傳統(tǒng)被動均衡通過能耗電阻消耗高電壓單體的能量,但存在效...

關(guān)鍵字: BMS系統(tǒng) STM32

在嵌入式系統(tǒng)中,模數(shù)轉(zhuǎn)換器(ADC)是連接物理世界與數(shù)字處理的核心橋梁。STM32系列微控制器內(nèi)置的ADC采用逐次逼近型(SAR)架構(gòu),通過精密的硬件電路實現(xiàn)模擬信號到數(shù)字信號的轉(zhuǎn)換。

關(guān)鍵字: ADC STM32

STM32系列微控制器因其高性能和豐富的外設(shè)接口被廣泛應(yīng)用于各類場景。當涉及USB高速(HS)與全速(FS)接口設(shè)計時,開發(fā)者常因?qū)π盘柾暾?、ESD防護及電源管理的理解不足而陷入調(diào)試困境。本文將從原理出發(fā),結(jié)合實際案例...

關(guān)鍵字: STM32 USB
關(guān)閉