一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

STM32學(xué)習(xí)筆記一一TFTLCD 顯示

 goodwangLib 2018-03-19

1.TFTLCD 簡(jiǎn)介

TFT-LCD 即薄膜晶體管液晶顯示器。TFT-LCD與無(wú)源 TN-LCD、 STN-LCD 的簡(jiǎn)單矩陣不同,它在液晶顯示屏的每一個(gè)象素上都設(shè)置有一個(gè)薄膜晶體管( TFT),可有效地克服非選通時(shí)的串?dāng)_,使顯示液晶屏的靜態(tài)特性與掃描線(xiàn)數(shù)無(wú)關(guān),因此大大提高了圖像質(zhì)量。 TFT-LCD 也被叫做真彩液晶顯示器。ALIENTEK TFTLCD 模塊采用 16 位的并方式與外部連接。

2.80 并口有如下一些信號(hào)線(xiàn):

信號(hào)線(xiàn) 作用
CS TFTLCD 片選信號(hào)
WR 向 TFTLCD 寫(xiě)入數(shù)據(jù)
RD 從 TFTLCD 讀取數(shù)據(jù)
D[15: 0] 16 位雙向數(shù)據(jù)線(xiàn)
RST 硬復(fù)位 TFTLCD
RS 命令/數(shù)據(jù)標(biāo)志( 0,讀寫(xiě)命令; 1,讀寫(xiě)數(shù)據(jù))

注:TFTLCD 模塊的 RST 信號(hào)線(xiàn)是直接接到 STM32 的復(fù)位腳上,并不由軟件控制,這樣可以省下來(lái)一個(gè) IO口。另外我們還需要一個(gè)背光控制線(xiàn)來(lái)控制 TFTLCD 的背光。所以,我們總共需要的 IO 口數(shù)目為 21 個(gè)。

3.ILI9341 控制器介紹

ILI9341 液晶控制器自帶顯存,其顯存總大小為 172800( 240*320*18/8),即 18 位模式( 26萬(wàn)色)下的顯存量。在 16 位模式下, ILI9341 采用 RGB565 格式存儲(chǔ)顏色數(shù)據(jù),此時(shí) ILI9341的 18 位數(shù)據(jù)線(xiàn)與 MCU 的 16 位數(shù)據(jù)線(xiàn)以及 LCD GRAM 的對(duì)應(yīng)關(guān)系如圖:

這里寫(xiě)圖片描述

ILI9341 在 16 位模式下面,數(shù)據(jù)線(xiàn)有用的是: D17~D13 和 D11~D1, D0和 D12 沒(méi)有用到,實(shí)際上在我們 LCD 模塊里面, ILI9341 的 D0 和 D12 壓根就沒(méi)有引出來(lái),這樣, ILI9341 的 D17~D13 和 D11~D1 對(duì)應(yīng) MCU 的 D15~D0。

MCU 的 16 位數(shù)據(jù), 最低 5 位代表藍(lán)色,中間 6 位為綠色,最高 5 位為紅色。數(shù)值越大,表示該顏色越深。 另外,特別注意 ILI9341 所有的指令都是 8 位的(高 8 位無(wú)效),且參數(shù)除了讀寫(xiě) GRAM 的時(shí)候是 16 位,其他操作參數(shù),都是 8 位的。

4.ILI9341 的重要命令

(1)0XD3

這個(gè)是讀 ID4 指令,用于讀取 LCD 控制器的 ID

這里寫(xiě)圖片描述

可以看出, 0XD3 指令后面跟了 4 個(gè)參數(shù),最后 2 個(gè)參數(shù),讀出來(lái)是 0X93 和 0X41,剛好是控制器 ILI9341 的數(shù)字部分,從而,通過(guò)該指令,即可判別所用的 LCD 驅(qū)動(dòng)器是什么型號(hào),這樣,我們的代碼,就可以根據(jù)控制器的型號(hào)去執(zhí)行對(duì)應(yīng)驅(qū)動(dòng) IC 的初始化代碼,從而兼容不同驅(qū)動(dòng) IC 的屏,使得一個(gè)代碼支持多款 LCD。

(2)0X36

這是存儲(chǔ)訪(fǎng)問(wèn)控制指令,可以控制 ILI9341 存儲(chǔ)器的讀寫(xiě)方向,簡(jiǎn)單的說(shuō),就是在連續(xù)寫(xiě) GRAM 的時(shí)候,可以控制 GRAM 指針的增長(zhǎng)方向,從而控制顯示方式。(讀 GRAM 也是一樣)。該指令如表:

這里寫(xiě)圖片描述

0X36 指令后面,緊跟一個(gè)參數(shù),主要關(guān)注: MY、 MX、 MV 這三個(gè)位,通過(guò)這三個(gè)位的設(shè)置,可以控制整個(gè) ILI9341 的全部掃描方向。

這里寫(xiě)圖片描述

在利用 ILI9341 顯示內(nèi)容的時(shí)候,就有很大靈活性了,比如顯示 BMP 圖片,BMP 解碼數(shù)據(jù),就是從圖片的左下角開(kāi)始,慢慢顯示到右上角,如果設(shè)置 LCD 掃描方向?yàn)閺淖蟮接?,從下到上,那么我們只需要設(shè)置一次坐標(biāo),然后就不停的往 LCD 填充顏色數(shù)據(jù)即可,這樣可以大大提高顯示速度。

(3)0X2A

這是列地址設(shè)置指令, 在從左到右,從上到下的掃描方式(默認(rèn))下面,該指令用于設(shè)置橫坐標(biāo)( x 坐標(biāo)),該指令如表 :

這里寫(xiě)圖片描述

在默認(rèn)掃描方式時(shí),該指令用于設(shè)置 x 坐標(biāo),該指令帶有 4 個(gè)參數(shù),實(shí)際上是 2 個(gè)坐標(biāo)值:SC 和 EC,即列地址的起始值和結(jié)束值, SC 必須小于等于 EC,且 0≤SC/EC≤239。一般在設(shè)置 x 坐標(biāo)的時(shí)候,我們只需要帶 2 個(gè)參數(shù)即可,也就是設(shè)置 SC 即可,因?yàn)槿绻?EC 沒(méi)有變化,我們只需要設(shè)置一次即可(在初始化 ILI9341 的時(shí)候設(shè)置),從而提高速度。

(4)0X2B

是頁(yè)地址設(shè)置指令, 在從左到右,從上到下的掃描方(默認(rèn))下面,該指令用于設(shè)置縱坐標(biāo)( y 坐標(biāo))。該指令如表:

這里寫(xiě)圖片描述

在默認(rèn)掃描方式時(shí),該指令用于設(shè)置 y 坐標(biāo),該指令帶有 4 個(gè)參數(shù),實(shí)際上是 2 個(gè)坐標(biāo)值:SP 和 EP,即頁(yè)地址的起始值和結(jié)束值, SP 必須小于等于 EP,且 0≤SP/EP≤319。一般在設(shè)置y 坐標(biāo)的時(shí)候,我們只需要帶 2 個(gè)參數(shù)即可,也就是設(shè)置 SP 即可,因?yàn)槿绻?EP 沒(méi)有變化,我們只需要設(shè)置一次即可(在初始化 ILI9341 的時(shí)候設(shè)置),從而提高速度。

(5)0X2C

該指令是寫(xiě) GRAM 指令,在發(fā)送該指令之后,我們便可以往 LCD的 GRAM 里面寫(xiě)入顏色數(shù)據(jù)了,該指令支持連續(xù)寫(xiě),指令描述如表:

這里寫(xiě)圖片描述

在收到指令 0X2C 之后,數(shù)據(jù)有效位寬變?yōu)?16 位,我們可以連續(xù)寫(xiě)入 LCD GRAM 值, 而 GRAM 的地址將根據(jù) MY/MX/MV 設(shè)置的掃描方向進(jìn)行自增。

(6)0X2E

該指令是讀 GRAM 指令,用于讀取 ILI9341 的顯存( GRAM),輸出情況如表:

這里寫(xiě)圖片描述

該指令用于讀取 GRAM,如表 所示,ILI9341在收到該指令后,第一次輸出的是 dummy數(shù)據(jù),也就是無(wú)效的數(shù)據(jù),第二次開(kāi)始,讀取到的才是有效的 GRAM 數(shù)據(jù)(從坐標(biāo): SC, SP開(kāi)始),輸出規(guī)律為:每個(gè)顏色分量占 8 個(gè)位,一次輸出 2 個(gè)顏色分量。

比如:

第一次輸出是R1G1,隨后的規(guī)律為:B1R2?G2B2?R3G3?B3R4?G4B4?R5G5… 以此類(lèi)推。如果我們只需要讀取一個(gè)點(diǎn)的顏色值,那么只需要接收到參數(shù) 3 即可,如果要連續(xù)讀?。ɡ?GRAM 地址自增),那么就按照上述規(guī)律去接收顏色數(shù)據(jù)。

5.TFTLCD 模塊的使用流程

這里寫(xiě)圖片描述

任何 LCD,使用流程都可以簡(jiǎn)單的用以上流程圖表示。其中硬復(fù)位和初始化序列,只需要執(zhí)行一次即可。而畫(huà)點(diǎn)流程就是:設(shè)置坐標(biāo) -> 寫(xiě) GRAM 指令 -> 寫(xiě)入顏色數(shù)據(jù),然后在 LCD 上面,我們就可以看到對(duì)應(yīng)的點(diǎn)顯示我們寫(xiě)入的顏色了。讀點(diǎn)流程為:設(shè)置坐標(biāo) -> 讀 GRAM 指令 -> 讀取顏色數(shù)據(jù),這樣就可以獲取到對(duì)應(yīng)點(diǎn)的顏色數(shù)據(jù)了。

1) 設(shè)置 STM32 與 TFTLCD 模塊相連接的 IO。

先將我們與 TFTLCD 模塊相連的 IO 口進(jìn)行初始化,以便驅(qū)動(dòng) LCD。 這里需要根據(jù)連接電路以及 TFTLCD 模塊的設(shè)置來(lái)確定。

2) 初始化 TFTLCD 模塊。

即上圖的初始化序列,這里我們沒(méi)有硬復(fù)位 LCD,因?yàn)?MiniSTM32 開(kāi)發(fā)板的 LCD 接口,將 TFTLCD 的 RST 同 STM32 的 RESET 連接在一起了,只要按下開(kāi)發(fā)板的 RESET 鍵,就會(huì)對(duì) LCD 進(jìn)行硬復(fù)位。

初始化序列,就是向 LCD 控制器寫(xiě)入一系列的設(shè)置值(比如伽馬校準(zhǔn)),這些初始化序列一般 LCD 供應(yīng)商會(huì)提供給客戶(hù),我們直接使用這些序列即可,不需要深入研究。在初始化之后, LCD 才可以正常使用。

3) 通過(guò)函數(shù)將字符和數(shù)字顯示到 TFTLCD 模塊上。

這一步則通過(guò)上圖 左側(cè)的流程,即:設(shè)置坐標(biāo)->寫(xiě) GRAM 指令->寫(xiě) GRAM 來(lái)實(shí)現(xiàn),但是這個(gè)步驟,只是一個(gè)點(diǎn)的處理,我們要顯示字符/數(shù)字,就必須要多次使用這個(gè)步驟,從而達(dá)到顯示字符/數(shù)字的目標(biāo),所以需要設(shè)計(jì)一個(gè)函數(shù)來(lái)實(shí)現(xiàn)數(shù)字/字符的顯示,之后調(diào)用該函數(shù),就可以實(shí)現(xiàn)數(shù)字/字符的顯示了。

6.實(shí)例學(xué)習(xí)

(1)在硬件上, TFTLCD 模塊與 MiniSTM32 開(kāi)發(fā)板的 IO口對(duì)應(yīng)關(guān)系如下:

功能 IO
LCD_LED PC10
LCD_CS PC9
LCD _RS PC8
LCD _WR PC7
LCD _RD PC6
LCD _D[17:1] PB[15:0]

(2)時(shí)序

模塊的8080并口讀/寫(xiě)的過(guò)程為:

先根據(jù)要寫(xiě)入/讀取的數(shù)據(jù)的類(lèi)型,設(shè)置RS為高(數(shù)據(jù))/低(命令),然后拉低片選,選中ILI9341,接著我們根據(jù)是讀數(shù)據(jù),還是要寫(xiě)數(shù)據(jù)置RD/WR為低。

1.讀數(shù)據(jù):在RD的上升沿, 讀取數(shù)據(jù)線(xiàn)上的數(shù)據(jù)(D[15:0]);

這里寫(xiě)圖片描述

2.寫(xiě)數(shù)據(jù):在WR的上升沿,使數(shù)據(jù)寫(xiě)入到ILI9341里面

這里寫(xiě)圖片描述

3.例程分析

//LCD重要參數(shù)集
typedef struct  
{                                           
    u16 width;          //LCD 寬度
    u16 height;         //LCD 高度
    u16 id;             //LCD ID
    u8  dir;            //橫屏還是豎屏控制:0,豎屏;1,橫屏。   
    u16 wramcmd;        //開(kāi)始寫(xiě)gram指令
    u16 setxcmd;        //設(shè)置x坐標(biāo)指令
    u16  setycmd;       //設(shè)置y坐標(biāo)指令    
}_lcd_dev; 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

/*寫(xiě)數(shù)據(jù)函數(shù):通過(guò) 80 并口向 LCD 模塊寫(xiě)入一個(gè) 16 位的數(shù)據(jù),宏定義的方式,以提高速度。*/
 #define LCD_WR_DATA(data){    LCD_RS_SET;    LCD_CS_CLR;    DATAOUT(data);    LCD_WR_CLR;    LCD_WR_SET;    LCD_CS_SET;}   

void LCD_WR_DATAX(u16 data)
{
    LCD_RS_SET;
    LCD_CS_CLR;
    DATAOUT(data);
    LCD_WR_CLR;
    LCD_WR_SET;
    LCD_CS_SET;
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

/*通過(guò) 8080 并口向 LCD 模塊寫(xiě)入寄存器命令*/
//寫(xiě)寄存器函數(shù)
//data:寄存器值
void LCD_WR_REG(u16 data)
{
    LCD_RS_CLR;//寫(xiě)地址
    LCD_CS_CLR;
    DATAOUT(data);
    LCD_WR_CLR;
    LCD_WR_SET;
    LCD_CS_SET;
}

/*讀取 LCD 控制器的寄存器數(shù)據(jù)(非 GRAM 數(shù)據(jù))*/
//讀 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;
    LCD_RD_CLR; //讀取數(shù)據(jù)(讀寄存器時(shí),并不需要讀 2 次)
    if(lcddev.id==0X8989)delay_us(2);//FOR 8989,延時(shí) 2us
    t=DATAIN;
    LCD_RD_SET;
    LCD_CS_SET;
    GPIOB->CRL=0X33333333; //PB0-7 上拉輸出
    GPIOB->CRH=0X33333333; //PB8-15 上拉輸出
    GPIOB->ODR=0XFFFF; //全部輸出高
    return t;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

/*LCD 寄存器操作*/
//寫(xiě)寄存器:用于向 LCD 指定寄存器寫(xiě)入指定數(shù)據(jù)
//LCD_Reg:寄存器編號(hào)
//LCD_RegValue:要寫(xiě)入的值
void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue)
{
    LCD_WR_REG(LCD_Reg);
    LCD_WR_DATA(LCD_RegValue);
}

//讀寄存器:用于讀取指定寄存器的數(shù)據(jù)
//LCD_Reg:寄存器編號(hào)
//返回值:讀到的值
u16 LCD_ReadReg(u16 LCD_Reg)
{
    LCD_WR_REG(LCD_Reg); //寫(xiě)入要讀的寄存器號(hào)
    return LCD_RD_DATA();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

/*坐標(biāo)設(shè)置*/
//設(shè)置光標(biāo)位置:將 LCD 的當(dāng)前操作點(diǎn)設(shè)置到指定坐標(biāo)(x,y)
//Xpos:橫坐標(biāo)
//Ypos:縱坐標(biāo)
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;//橫屏其實(shí)就是調(diào)轉(zhuǎn) x,y 坐標(biāo)
    LCD_WriteReg(lcddev.setxcmd, Xpos);
    LCD_WriteReg(lcddev.setycmd, Ypos);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

//畫(huà)點(diǎn)
//x,y:坐標(biāo)
//POINT_COLOR:此點(diǎn)的顏色
void LCD_DrawPoint(u16 x,u16 y)
{
    LCD_SetCursor(x,y); //設(shè)置光標(biāo)位置
    LCD_WriteRAM_Prepare(); //開(kāi)始寫(xiě)入 GRAM
    LCD_WR_DATA(POINT_COLOR);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

//讀取個(gè)某點(diǎn)的顏色值
//x,y:坐標(biāo)
//返回值:此點(diǎn)的顏色
u16 LCD_ReadPoint(u16 x,u16 y)
{
    u16 r,g,b;
    if(x>=lcddev.width||y>=lcddev.height)
        return 0; //超過(guò)了范圍,直接返回
    LCD_SetCursor(x,y);
    if(lcddev.id==0X9341||lcddev.id==0X6804||lcddev.id==0X5310||lcddev.id==0X1963)
    LCD_WR_REG(0X2E);//9341/6804/3510/1963 發(fā)送讀 GRAM 指令
    else if(lcddev.id==0X5510)LCD_WR_REG(0X2E00);//5510 發(fā)送讀 GRAM 指令
    else LCD_WR_REG(0X22); //其他 IC 發(fā)送讀 GRAM 指令
    GPIOB->CRL=0X88888888; //PB0-7 上拉輸入
    GPIOB->CRH=0X88888888; //PB8-15 上拉輸入
    GPIOB->ODR=0XFFFF; //全部輸出高
    LCD_RS_SET;
    LCD_CS_CLR;
    LCD_RD_CLR; //讀取數(shù)據(jù)(讀 GRAM 時(shí),第一次為假讀)
    opt_delay(2); //延時(shí)
    r=DATAIN; //實(shí)際坐標(biāo)顏色
    LCD_RD_SET;
    if(lcddev.id==0X1963)
    {
    LCD_CS_SET;
    GPIOB->CRL=0X33333333; //PB0-7 上拉輸出
    GPIOB->CRH=0X33333333; //PB8-15 上拉輸出
    GPIOB->ODR=0XFFFF; //全部輸出高
    return r; //1963 直接讀就可以
    }
    LCD_RD_CLR; //dummy READ
    opt_delay(2); //延時(shí)
    r=DATAIN; //實(shí)際坐標(biāo)顏色
    LCD_RD_SET;
    if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)//這幾個(gè) IC 要分 2 次讀出
    {
    LCD_RD_CLR;
    opt_delay(2);//延時(shí)
    b=DATAIN;//讀取藍(lán)色值
    LCD_RD_SET;
    g=r&0XFF;//對(duì)于 9341,第一次讀取的是 RG 的值,R 在前,G 在后,各占 8 位
    g<<=8;
    }else if(lcddev.id==0X6804)
    {
    LCD_RD_CLR;
    LCD_RD_SET;
    r=DATAIN;//6804 第二次讀取的才是真實(shí)值
    }
    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)return r; //這幾種 IC 直接返回顏色值
    else if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)
    return (((r>>11)<<11)|((g>>10)<<5)|(b>>11));//這幾個(gè) IC 需要公式轉(zhuǎn)換一下
    else return LCD_BGR2RGB(r); //其他 IC
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

//在指定位置顯示一個(gè)字符
//x,y:起始坐標(biāo)
//num:要顯示的字符:" "--->"~"
//size:字體大小 12/16/24
//mode:疊加方式(1)還是非疊加方式(0)
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)
{
    u8 temp,t1,t;
    u16 y0=y;
    u8 csize=(size/8+((size%8)?1:0))*(size/2);//得到字體一個(gè)字符對(duì)應(yīng)點(diǎn)陣集所占字節(jié)數(shù)
    //設(shè)置窗口
    num=num-' ';//得到偏移后的值
    for(t=0;t<csize;t++)
    {
    if(size==12)temp=asc2_1206[num][t]; //調(diào)用 1206 字體
    else if(size==16)temp=asc2_1608[num][t]; //調(diào)用 1608 字體
    else if(size==24)temp=asc2_2412[num][t]; //調(diào)用 2412 字體
    else return; //沒(méi)有的字庫(kù)
    for(t1=0;t1<8;t1++)
    {
    if(temp&0x80)
    LCD_Fast_DrawPoint(x,y,POINT_COLOR);
    else if(mode==0)
    LCD_Fast_DrawPoint(x,y,BACK_COLOR);
    temp<<=1;
    y++;
    if(x>=lcddev.width)return; //超區(qū)域了
    if((y-y0)==size)
    {
    y=y0; x++;
    if(x>=lcddev.width)return; //超區(qū)域了
    break;
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

//該初始化函數(shù)可以初始化各種 ALIENTEK 出品的 LCD 液晶屏
void LCD_Init(void)
{ 
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能PORTB,C時(shí)鐘和AFIO時(shí)鐘
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);//開(kāi)啟SWD,失能JTAG

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6;     ///PORTC6~10復(fù)用推挽輸出
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC  

    GPIO_SetBits(GPIOC,GPIO_Pin_10|GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //  PORTB推挽輸出
    GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB

    GPIO_SetBits(GPIOB,GPIO_Pin_All);

    delay_ms(50); // delay 50 ms 
    LCD_WriteReg(0x0000,0x0001);
    delay_ms(50); // delay 50 ms 
    lcddev.id = LCD_ReadReg(0x0000);   
    if(lcddev.id<0XFF||lcddev.id==0XFFFF||lcddev.id==0X9300)//讀到ID不正確,新增lcddev.id==0X9300判斷,因?yàn)?341在未被復(fù)位的情況下會(huì)被讀成9300
    {   
        //嘗試9341 ID的讀取      
        LCD_WR_REG(0XD3);                  
        LCD_RD_DATA();              //dummy read    
        LCD_RD_DATA();              //讀到0X00
        lcddev.id=LCD_RD_DATA();    //讀取93                                 
        lcddev.id<<=8;
        lcddev.id|=LCD_RD_DATA();   //讀取41                 
        if(lcddev.id!=0X9341)       //非9341,嘗試是不是6804
        {   
            LCD_WR_REG(0XBF);                  
            LCD_RD_DATA();          //dummy read     
            LCD_RD_DATA();          //讀回0X01               
            LCD_RD_DATA();          //讀回0XD0                
            lcddev.id=LCD_RD_DATA();//這里讀回0X68 
            lcddev.id<<=8;
            lcddev.id|=LCD_RD_DATA();//這里讀回0X04   
            if(lcddev.id!=0X6804)   //也不是6804,嘗試看看是不是NT35310
            { 
                LCD_WR_REG(0XD4);                  
                LCD_RD_DATA();              //dummy read  
                LCD_RD_DATA();              //讀回0X01     
                lcddev.id=LCD_RD_DATA();    //讀回0X53    
                lcddev.id<<=8;   
                lcddev.id|=LCD_RD_DATA();   //這里讀回0X10   
                if(lcddev.id!=0X5310)       //也不是NT35310,嘗試看看是不是NT35510
                {
                    LCD_WR_REG(0XDA00); 
                    LCD_RD_DATA();          //讀回0X00     
                    LCD_WR_REG(0XDB00); 
                    lcddev.id=LCD_RD_DATA();//讀回0X80
                    lcddev.id<<=8;  
                    LCD_WR_REG(0XDC00); 
                    lcddev.id|=LCD_RD_DATA();//讀回0X00       
                    if(lcddev.id==0x8000)lcddev.id=0x5510;//NT35510讀回的ID是8000H,為方便區(qū)分,我們強(qiáng)制設(shè)置為5510
                    if(lcddev.id!=0X5510)           //也不是NT5510,嘗試看看是不是SSD1963
                    {
                        LCD_WR_REG(0XA1);
                        lcddev.id=LCD_RD_DATA();
                        lcddev.id=LCD_RD_DATA();    //讀回0X57
                        lcddev.id<<=8;   
                        lcddev.id|=LCD_RD_DATA();   //讀回0X61    
                        if(lcddev.id==0X5761)lcddev.id=0X1963;//SSD1963讀回的ID是5761H,為方便區(qū)分,我們強(qiáng)制設(shè)置為1963
                    }
                }
            }
        }   
    }
    printf(" LCD ID:%x\r\n",lcddev.id); //打印LCD ID  
    if(lcddev.id==0X9341)   //9341初始化
    {    
        LCD_WR_REG(0xCF);  
        LCD_WR_DATAX(0x00); 
        LCD_WR_DATAX(0xC1); 
        LCD_WR_DATAX(0X30); 
        LCD_WR_REG(0xED);  
        LCD_WR_DATAX(0x64); 
        LCD_WR_DATAX(0x03); 
        LCD_WR_DATAX(0X12); 
        LCD_WR_DATAX(0X81); 
        LCD_WR_REG(0xE8);  
        LCD_WR_DATAX(0x85); 
        LCD_WR_DATAX(0x10); 
        LCD_WR_DATAX(0x7A); 
        LCD_WR_REG(0xCB);  
        LCD_WR_DATAX(0x39); 
        LCD_WR_DATAX(0x2C); 
        LCD_WR_DATAX(0x00); 
        LCD_WR_DATAX(0x34); 
        LCD_WR_DATAX(0x02); 
        LCD_WR_REG(0xF7);  
        LCD_WR_DATAX(0x20); 
        LCD_WR_REG(0xEA);  
        LCD_WR_DATAX(0x00); 
        LCD_WR_DATAX(0x00); 
        LCD_WR_REG(0xC0);    //Power control 
        LCD_WR_DATAX(0x1B);   //VRH[5:0] 
        LCD_WR_REG(0xC1);    //Power control 
        LCD_WR_DATAX(0x01);   //SAP[2:0];BT[3:0] 
        LCD_WR_REG(0xC5);    //VCM control 
        LCD_WR_DATAX(0x30);      //3F
        LCD_WR_DATAX(0x30);      //3C
        LCD_WR_REG(0xC7);    //VCM control2 
        LCD_WR_DATAX(0XB7); 
        LCD_WR_REG(0x36);    // Memory Access Control 
        LCD_WR_DATAX(0x48); 
        LCD_WR_REG(0x3A);   
        LCD_WR_DATAX(0x55); 
        LCD_WR_REG(0xB1);   
        LCD_WR_DATAX(0x00);   
        LCD_WR_DATAX(0x1A); 
        LCD_WR_REG(0xB6);    // Display Function Control 
        LCD_WR_DATAX(0x0A); 
        LCD_WR_DATAX(0xA2); 
        LCD_WR_REG(0xF2);    // 3Gamma Function Disable 
        LCD_WR_DATAX(0x00); 
        LCD_WR_REG(0x26);    //Gamma curve selected 
        LCD_WR_DATAX(0x01); 
        LCD_WR_REG(0xE0);    //Set Gamma 
        LCD_WR_DATAX(0x0F); 
        LCD_WR_DATAX(0x2A); 
        LCD_WR_DATAX(0x28); 
        LCD_WR_DATAX(0x08); 
        LCD_WR_DATAX(0x0E); 
        LCD_WR_DATAX(0x08); 
        LCD_WR_DATAX(0x54); 
        LCD_WR_DATAX(0XA9); 
        LCD_WR_DATAX(0x43); 
        LCD_WR_DATAX(0x0A); 
        LCD_WR_DATAX(0x0F); 
        LCD_WR_DATAX(0x00); 
        LCD_WR_DATAX(0x00); 
        LCD_WR_DATAX(0x00); 
        LCD_WR_DATAX(0x00);          
        LCD_WR_REG(0XE1);    //Set Gamma 
        LCD_WR_DATAX(0x00); 
        LCD_WR_DATAX(0x15); 
        LCD_WR_DATAX(0x17); 
        LCD_WR_DATAX(0x07); 
        LCD_WR_DATAX(0x11); 
        LCD_WR_DATAX(0x06); 
        LCD_WR_DATAX(0x2B); 
        LCD_WR_DATAX(0x56); 
        LCD_WR_DATAX(0x3C); 
        LCD_WR_DATAX(0x05); 
        LCD_WR_DATAX(0x10); 
        LCD_WR_DATAX(0x0F); 
        LCD_WR_DATAX(0x3F); 
        LCD_WR_DATAX(0x3F); 
        LCD_WR_DATAX(0x0F); 
        LCD_WR_REG(0x2B); 
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x01);
        LCD_WR_DATAX(0x3f);
        LCD_WR_REG(0x2A); 
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0xef);  
        LCD_WR_REG(0x11); //Exit Sleep
        delay_ms(120);
        LCD_WR_REG(0x29); //display on  
    }   
    LCD_Display_Dir(0);         //默認(rèn)為豎屏
    LCD_LED=1;                  //點(diǎn)亮背光
    LCD_Clear(WHITE);
}       
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172

注:此處僅為9341 的初始化


參考:

原子開(kāi)發(fā)手冊(cè)—–庫(kù)函數(shù)版

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    狠狠干狠狠操在线播放| 丰满人妻一二区二区三区av| 色婷婷人妻av毛片一区二区三区| 国产亚洲不卡一区二区| 国产日韩欧美专区一区| 97人妻精品免费一区二区| 亚洲一区二区三区国产| 欧洲一区二区三区自拍天堂| 国产精品久久熟女吞精| 国产午夜福利片在线观看| 久久精品偷拍视频观看| 国产一区二区精品丝袜| 久久精品免费视看国产成人| 日本亚洲欧美男人的天堂| 亚洲国产另类久久精品| 99久免费精品视频在线观| 亚洲男人天堂网在线视频| 亚洲欧美日韩国产综合在线| 大香蕉久久精品一区二区字幕| 国产在线观看不卡一区二区| 蜜桃av人妻精品一区二区三区 | 久久精品视频就在久久| 久久99亚洲小姐精品综合| 91精品国产综合久久不卡| 久久香蕉综合网精品视频| 成人精品一区二区三区在线| 国产精品二区三区免费播放心| 麻豆一区二区三区精品视频| 国产精品福利精品福利| 日韩一区中文免费视频| 免费观看日韩一级黄色大片 | 国产欧美韩日一区二区三区| av在线免费观看在线免费观看| 日韩精品一区二区毛片| 爽到高潮嗷嗷叫之在现观看| 欧美特色特黄一级大黄片| 国产内射一级一片内射高清视频| 亚洲国产成人久久一区二区三区| 清纯少妇被捅到高潮免费观看| 亚洲熟妇中文字幕五十路| 亚洲国产精品一区二区毛片|