娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年06月03日(星期二)

2018年06月03日 | STM32控制TFTLCD顯示

發布者:才富五車330 來源: eefocus關鍵字:STM32  TFTLCD顯示 手機看文章 掃描二維碼
隨時隨地手機看文章

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

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

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

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

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

     R\G\B三種顏色各占的位數可以查看數據手冊。

2、TFTLCD的操作分為兩種:

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

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

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

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

RS為低電平狀態下,寫入兩個字節的數據,第一個字節為零,第二個字節為寄存器索引值。

RS為高電平狀態下,讀取兩個字節數據,第一個字節為高八位,第二個字節為低八位。

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

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

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

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

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

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

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

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

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

     橫坐標(x 坐標)。

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

      坐標(y 坐標)。

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

     數據了,該指令支持連續寫,在收到指令 0X2C 之后,數據有效位寬變為 16 位,我們可以連續寫入

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

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



三、軟件編程

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

//LCD重要參數集
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參數
extern _lcd_dev lcddev; //管理LCD重要參數


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

//寫數據函數
#define LCD_WR_DATA(data){\
LCD_RS_SET;\
LCD_CS_CLR;\
DATAOUT(data);\
LCD_WR_CLR;\
LCD_WR_SET;\
LCD_CS_SET;\


//寫數據函數
//可以替代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 函數,該函數是通過 8080 并口向 LCD 模塊寫入寄存器命令,因
為該函數使用頻率不是很高,我們不采用宏定義來做(宏定義占用 FLASH 較多),通過 LCD_RS
來標記是寫入命令(LCD_RS=0)還是數據(LCD_RS=1)。該函數代碼如下:
//寫寄存器函數

//data:寄存器值
void LCD_WR_REG(u16 data)

LCD_RS_CLR;//寫地址  
LCD_CS_CLR; 
DATAOUT(data); 
LCD_WR_CLR; 
LCD_WR_SET; 
  LCD_CS_SET;   
}


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

//讀LCD數據
//返回值:讀到的值
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;
//讀取數據(讀寄存器時,并不需要讀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 個函數,用于實現 LCD 基本的讀寫操作,接下來,我們介紹 2 個 LCD 寄存器操作
的函數,LCD_WriteReg 和 LCD_ReadReg,這兩個函數代碼如下:
//寫寄存器 

//寫寄存器
//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(); 

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

//設置光標位置
//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);

}

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

//畫點
//x,y:坐標
//POINT_COLOR:此點的顏色
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetCursor(x,y);//設置光標位置 
LCD_WriteRAM_Prepare();//開始寫入GRAM
LCD_WR_DATA(POINT_COLOR); 

該函數實現比較簡單,就是先設置坐標,然后往坐標寫顏色。其中 POINT_COLOR 是我們
定義的一個全局變量,用于存放畫筆顏色,順帶介紹一下另外一個全局變量: BACK_COLOR,
該變量代表 LCD 的背景色。LCD_DrawPoint 函數雖然簡單,但是至關重要,其他幾乎所有上
層函數,都是通過調用這個函數實現的。
有了畫點,當然還需要有讀點的函數,第九個介紹的函數就是讀點函數,用于讀取 LCD
的 GRAM, 這里說明一下,為什么 OLED 模塊沒做讀 GRAM 的函數,而這里做了。因為 OLED
模塊是單色的,所需要全部 GRAM 也就 1K 個字節,而 TFTLCD 模塊為彩色的,點數也比 OLED
模塊多很多,以 16 位色計算, 一款 320×240 的液晶,需要 320×240×2 個字節來存儲顏色值,
也就是也需要 150K 字節,這對任何一款單片機來說,都不是一個小數目了。而且我們在圖形
疊加的時候,可以先讀回原來的值,然后寫入新的值,在完成疊加后,我們又恢復原來的值。
這樣在做一些簡單菜單的時候,是很有用的。這里我們讀取 TFTLCD 模塊數據的函數為
LCD_ReadPoint,該函數直接返回讀到的 GRAM 值。該函數使用之前要先設置讀取的 GRAM
地址,通過 LCD_SetCursor 函數來實現。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發送讀GRAM指令
else if(lcddev.id==0X5510)LCD_WR_REG(0X2E00);//5510 發送讀GRAM指令
else LCD_WR_REG(R34);      //其他IC發送讀GRAM指令
GPIOB->CRL=0X88888888; //PB0-7  上拉輸入
GPIOB->CRH=0X88888888; //PB8-15 上拉輸入
GPIOB->ODR=0XFFFF;     //全部輸出高


LCD_RS_SET;
LCD_CS_CLR;   
//讀取數據(讀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)

return r;//這幾種IC直接返回顏色值
else if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)

return (((r>>11)<<11)|((g>>10)<<5)|(b>>11));//ILI9341/NT35310/NT35510需要公式轉換一下
else return LCD_BGR2RGB(r);//其他IC
}



在 LCD_ReadPoint 函數中,因為我們的代碼不止支持一種 LCD 驅動器,所以,我們根據
不同的 LCD 驅動器((lcddev.id)型號,執行不同的操作,以實現對各個驅動器兼容,提高函數
的通用性。

第十個要介紹的是字符顯示函數 LCD_ShowChar,該函數同前面 OLED 模塊的字符顯示函
數差不多,但是這里的字符顯示函數多了一個功能,就是可以以疊加方式顯示,或者以非疊加
方式顯示。疊加方式顯示多用于在顯示的圖片上再顯示字符。非疊加方式一般用于普通的顯示。
該函數實現代碼如下: 
//在指定位置顯示一個字符
//x,y:起始坐標
//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);//得到字體一個字符對應點陣集所占的字節數
//設置窗口    
num=num-' ';//得到偏移后的值
for(t=0;t{   
if(size==12)temp=asc2_1206[num][t]; //調用1206字體
else if(size==16)temp=asc2_1608[num][t];//調用1608字體
else if(size==24)temp=asc2_2412[num][t];//調用2412字體
else return;  //沒有的字庫
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;//超區域了
if((y-y0)==size)
{
y=y0;
x++;
if(x>=lcddev.width)return;//超區域了
break;
}
}    
}  
}   


在 LCD_ShowChar 函數里面,我們采用快速畫點函數 LCD_Fast_DrawPoint 來畫點顯示字
符,該函數同 LCD_DrawPoint 一樣,只是帶了顏色參數,且減少了函數調用的時間,詳見本例
程源碼。

最后,我們再介紹一下 TFTLCD 模塊的初始化函數 LCD_Init,該函數先初始化 STM32 與
TFTLCD 連接的 IO 口,并配置 FSMC 控制器,然后讀取 LCD 控制器的型號,根據控制 IC 的
型號執行不同的初始化代碼,其簡化代碼如下: 

void LCD_Init(void)

  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能PORTB,C時鐘和AFIO時鐘
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);//開啟SWD,失能JTAG

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6;  ///PORTC6~10復用推挽輸出
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判斷,因為9341在未被復位的情況下會被讀成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,為方便區分,我們強制設置為5510
}
}
  }  
}
  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);//默認為豎屏
LCD_LED=1;  //點亮背光
LCD_Clear(WHITE);
}


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


//LCD參數
extern _lcd_dev lcddev; //管理LCD重要參數
//LCD的畫筆顏色和背景色   
extern u16  POINT_COLOR;//默認紅色    
extern u16  BACK_COLOR; //背景顏色.默認為白色


////////////////////////////////////////////////////////////////////
//-----------------LCD端口定義---------------- 
#define LCD_LED PCout(10) //LCD背光     PC10 


/*
#define LCD_CS_SET  GPIOC->BSRR=1<<9    //片選端口  PC9
#define LCD_RS_SETGPIOC->BSRR=1<<8    //數據/命令 PC8  
#define LCD_WR_SETGPIOC->BSRR=1<<7    //寫數據 PC7
#define LCD_RD_SETGPIOC->BSRR=1<<6    //讀數據 PC6
   
#define LCD_CS_CLR  GPIOC->BRR=1<<9     //片選端口  PC9
#define LCD_RS_CLRGPIOC->BRR=1<<8     //數據/命令 PC8  
#define LCD_WR_CLRGPIOC->BRR=1<<7     //寫數據 PC7
#define LCD_RD_CLRGPIOC->BRR=1<<6     //讀數據 PC6  
*/


#define LCD_CS_SET  GPIO_SetBits(GPIOC,GPIO_Pin_9)    //片選端口  PC9
#define LCD_RS_SETGPIO_SetBits(GPIOC,GPIO_Pin_8)    //數據/命令 PC8  
#define LCD_WR_SETGPIO_SetBits(GPIOC,GPIO_Pin_7)   //寫數據  PC7
#define LCD_RD_SETGPIO_SetBits(GPIOC,GPIO_Pin_6)   //讀數據  PC6
   
#define LCD_CS_CLR  GPIO_ResetBits(GPIOC,GPIO_Pin_9)    //片選端口  PC9
#define LCD_RS_CLRGPIO_ResetBits(GPIOC,GPIO_Pin_8)     //數據/命令PC8   
#define LCD_WR_CLRGPIO_ResetBits(GPIOC,GPIO_Pin_7)     //寫數據  PC7
#define LCD_RD_CLRGPIO_ResetBits(GPIOC,GPIO_Pin_6)    //讀數據  PC6  






//PB0~15,作為數據線
//#define DATAOUT(x) GPIOB->ODR=x; //數據輸出
//#define DATAIN     GPIOB->IDR;   //數據輸入


#define DATAOUT(x) GPIO_Write(GPIOB,x);
#define DATAIN   GPIO_ReadInputData(GPIOB)
 
//////////////////////////////////////////////////////////////////////
//掃描方向定義
#define L2R_U2D  0 //從左到右,從上到下
#define L2R_D2U  1 //從左到右,從下到上
#define R2L_U2D  2 //從右到左,從上到下
#define R2L_D2U  3 //從右到左,從下到上


#define U2D_L2R  4 //從上到下,從左到右
#define U2D_R2L  5 //從上到下,從右到左
#define D2U_L2R  6 //從下到上,從左到右
#define D2U_R2L  7 //從下到上,從右到左


#define DFT_SCAN_DIR  L2R_U2D  //默認的掃描方向
 
//掃描方向定義
#define L2R_U2D  0 //從左到右,從上到下
#define L2R_D2U  1 //從左到右,從下到上
#define R2L_U2D  2 //從右到左,從上到下
#define R2L_D2U  3 //從右到左,從下到上


#define U2D_L2R  4 //從上到下,從左到右
#define U2D_R2L  5 //從上到下,從右到左
#define D2U_L2R  6 //從下到上,從左到右
#define D2U_R2L  7 //從下到上,從右到左  


#define DFT_SCAN_DIR  L2R_U2D  //默認的掃描方向


//畫筆顏色
#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 //灰色
//GUI顏色


#define DARKBLUE       0X01CF//深藍色
#define LIGHTBLUE       0X7D7C//淺藍色  
#define GRAYBLUE       0X5458 //灰藍色
//以上三色為PANEL的顏色 
 
#define LIGHTGREEN     0X841F //淺綠色 
#define LGRAY 0XC618 //淺灰色(PANNEL),窗體背景色


#define LGRAYBLUE        0XA651 //淺灰藍色(中間層顏色)
#define LBBLUE           0X2B12 //淺棕藍色(選擇條目的反色)
     
void LCD_Init(void);   //初始化
void LCD_DisplayOn(void); //開顯示
void LCD_DisplayOff(void); //關顯示
void LCD_Clear(u16 Color); //清屏
void LCD_SetCursor(u16 Xpos, u16 Ypos); //設置光標
void LCD_DrawPoint(u16 x,u16 y); //畫點
void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color);  //快速畫點
u16  LCD_ReadPoint(u16 x,u16 y); //讀點 
void LCD_Draw_Circle(u16 x0,u16 y0,u8 r);    //畫圓
void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2);  //畫線
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2);  //畫矩形
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color);  //填充單色
void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color);//填充指定顏色
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode);//顯示一個字符
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size);  //顯示一個數字
void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode);//顯示 數字
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p);//顯示一個字符串,12/16字體


void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue);
u16 LCD_ReadReg(u16 LCD_Reg);
void LCD_WriteRAM_Prepare(void);
void LCD_WriteRAM(u16 RGB_Code);  
void LCD_Scan_Dir(u8 dir); //設置屏掃描方向
void LCD_Display_Dir(u8 dir); //設置屏幕顯示方向
void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height);//設置窗口


//寫數據函數
#define LCD_WR_DATA(data){\
LCD_RS_SET;\
LCD_CS_CLR;\
DATAOUT(data);\
LCD_WR_CLR;\
LCD_WR_SET;\
LCD_CS_SET;\

     
//9320/9325 LCD寄存器  
#define R0             0x00
#define R1             0x01
#define R2             0x02
#define R3             0x03
#define R4             0x04
#define R5             0x05
#define R6             0x06
#define R7             0x07
#define R8             0x08
#define R9             0x09
#define R10            0x0A
#define R12            0x0C
#define R13            0x0D
#define R14            0x0E
#define R15            0x0F
#define R16            0x10
#define R17            0x11
#define R18            0x12
#define R19            0x13
#define R20            0x14
#define R21            0x15
#define R22            0x16
#define R23            0x17
#define R24            0x18
#define R25            0x19
#define R26            0x1A
#define R27            0x1B
#define R28            0x1C
#define R29            0x1D
#define R30            0x1E
#define R31            0x1F
#define R32            0x20
#define R33            0x21
#define R34            0x22
#define R36            0x24
#define R37            0x25
#define R40            0x28
#define R41            0x29
#define R43            0x2B
#define R45            0x2D
#define R48            0x30
#define R49            0x31
#define R50            0x32
#define R51            0x33
#define R52            0x34
#define R53            0x35
#define R54            0x36
#define R55            0x37
#define R56            0x38
#define R57            0x39
#define R59            0x3B
#define R60            0x3C
#define R61            0x3D
#define R62            0x3E
#define R63            0x3F
#define R64            0x40
#define R65            0x41
#define R66            0x42
#define R67            0x43
#define R68            0x44
#define R69            0x45
#define R70            0x46
#define R71            0x47
#define R72            0x48
#define R73            0x49
#define R74            0x4A
#define R75            0x4B
#define R76            0x4C
#define R77            0x4D
#define R78            0x4E
#define R79            0x4F
#define R80            0x50
#define R81            0x51
#define R82            0x52
#define R83            0x53
#define R96            0x60
#define R97            0x61
#define R106           0x6A
#define R118           0x76
#define R128           0x80
#define R129           0x81
#define R130           0x82
#define R131           0x83
#define R132           0x84
#define R133           0x85
#define R134           0x86
#define R135           0x87
#define R136           0x88
#define R137           0x89
#define R139           0x8B
#define R140           0x8C
#define R141           0x8D
#define R143           0x8F
#define R144           0x90
#define R145           0x91
#define R146           0x92
#define R147           0x93
#define R148           0x94
#define R149           0x95
#define R150           0x96
#define R151           0x97
#define R152           0x98
#define R153           0x99
#define R154           0x9A
#define R157           0x9D
#define R192           0xC0
#define R193           0xC1
#define R229           0xE5   
#endif


關鍵字:STM32  TFTLCD顯示 引用地址:STM32控制TFTLCD顯示

上一篇:FSMC驅動TFTLCD原理,時序和寄存器介紹
下一篇:stm32_19264液晶LCD驅動程序

推薦閱讀

針對,SDRAM作為Framdbuffer時的幾點優化。1.盡量增加SDRAM帶寬(使能突發訪問,增加突發訪問的長度,增加數據總線寬度)。2.framebuffer的行長度64字節對齊,因為LTDC突發訪問長度為64字節。3.分時復用FSMC的總線,DMA2D、CPU、LTDC、DMA等Master同時訪問設備時帶來總線仲裁時間,造成帶寬降低。4.多個framebuffer時放在不同的SDRAM bank里面,顯示buffe...
從汽車進入普通民眾的消費視線起直到數年前,無論是商家的宣傳、街頭巷尾的議論還是各類媒體的文章,關注的參數一直集中于硬件層面,如車的動力、空間、油耗、外形等,汽車這一物件似乎天然帶有“機械”和“工具”兩個標簽。而如今,隨著科技的發展,一輛汽車的軟件實力所占的比重越來越大,人工智能、OTA等軟件上的概念在汽車話語體系中紛紛崛起。這無疑...
日前,華盛頓州立大學(WSU)和太平洋西北國家實驗室(PNNL)的研究人員研制出一種鈉離子電池,這種電池的儲能能力和一些商用鋰離子電池的化學性能相當,這使得利用豐富而廉價的材料開發出一種可能可行的電池技術成為可能。該團隊報告了迄今為止鈉離子電池的最佳結果之一。它能夠提供類似于某些鋰離子電池的容量,并能在1000次循環充電后仍能保持80%以上...
集微網消息,6月2日晚,華為正式發布HarmonyOS 2及多款搭載HarmonyOS 2的新產品。據新華社報道,這也意味著“搭載HarmonyOS(鴻蒙)的手機”已經變成面向市場的正式產品。此前華為表示,HarmonyOS 是新一代的智能終端操作系統,為不同設備的智能化、互聯與協同提供了統一的語言。帶來簡捷、流暢、連續、安全可靠的全場景交互體驗。

史海拾趣

問答坊 | AI 解惑

負載拉移(Load-Pull)原理在射頻功率放大器設計中的應用.pdf

      近年來由於微波通訊技術的進步,及通訊頻寬與移動性越來越高的需求,使得無線區域網路(Wireless LAN)在人類日常生活中之重要性大幅提昇,進而帶動產學界紛紛投入此系統電路技術及產品之研發?!?

查看全部問答∨

基于at89c51的可燃性氣體語音報警器畢業設計

求助__基于at89c51的可燃性氣體報警器畢業設計…

查看全部問答∨

集成功放應用要點

今市面上常見的Hi-Fi集成功放,主要是以下三家公司的產品:1.美國國家半導體公司(NSC),代表產品有LM1875、LM1876、LM3876、LM3886、LM4766等。2.荷蘭飛利浦公司(PHILIPS),代表產品是TDA15 ...…

查看全部問答∨

有沒有精通TI達芬奇系列DSP芯片的工程師

目前有個項目,需要請一位工程師(業余兼職即可)。 1、熟悉TI 達芬奇系列DSP芯片,有DM64xx上開發,優化經驗。 2、熟悉H264協議或者MPEG4協議,最好在DM64XX上做過相關協議的開發或者優化工作。 詳細可以QQ455247859聯系。 …

查看全部問答∨

關于simulink利用rtw工具箱轉化成C代碼的一些問題

        小弟是DSP初學者,想把simulink的框圖轉化成c代碼,在DSP上跑.我在rtw工具箱的設置是:     Solver:  stop time 選inf             &nb ...…

查看全部問答∨

求按鍵判斷詳解?

如題,下面為按鍵判斷,本人為菜鳥,請大蝦指點下面判斷如何工作, 詳細一點,本人付100分作為獎勵! if((KeyV|0xc3)==0xff) //無鍵按下 return(0);…

查看全部問答∨

弱弱的一問,最大包長度的問題

例如我要傳送一張圖片 大小為100KB,而我的端點最大包長度為1KB,那么我就要傳100次是嗎,對數據的分割時應用層來做還是驅動層自動做的,我大概看了驅動的代碼好像沒有數據分割這么一說,見笑。…

查看全部問答∨

智能電子密碼鎖的設計與仿真

急需!!電子密碼鎖的電路設計圖和c語言設計程序。如果有proteus仿真過程制作和結果就更好了。多謝了,我要好好的謝謝您。別忘了留下聯系方式呀…

查看全部問答∨

不間斷電源UPS問題

沒有接觸過不間斷電源,有幾個問題像大家請教,忘不惜告知,先謝了! 有裝飾用的LED燈,總功率根據項目不同一般在25W~50W之間,12Vdc。之前一直采用開關電源(輸入220,輸出12vdc)直接供電,停電后則滅。 現客戶提出新要求: 要求正常時,LED燈 ...…

查看全部問答∨

usbdemo代碼在flash可以運行,無法在ram里面運行?(問題已經解決)

IAR EWARM 4.41 & JLink & STR912FW44 & Windows 2003我把中斷向量表復制到ram的最高端, 一共64bytes.在flash里面, 中斷都沒有問題. 但是在ram里面不正常.我測試了0x04000000&nb ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 广德县| 铜山县| 武宣县| 图们市| 朝阳区| 昌江| 黑龙江省| 乌海市| 景谷| 保康县| 应城市| 惠州市| 福贡县| 兰州市| 白银市| 诸城市| 将乐县| 井冈山市| 堆龙德庆县| 东乡族自治县| 东莞市| 萨嘎县| 南岸区| 涪陵区| 宿州市| 隆尧县| 芷江| 会理县| 桂阳县| 安福县| 大荔县| 新晃| 大悟县| 酉阳| 宁南县| 祁东县| 梅州市| 柯坪县| 克东县| 江北区| 鸡泽县|