datasheet

STM32学习笔记一一TFTLCD 显示

2019-01-09来源: eefocus关键字:STM32  TFTLCD  显示

1.TFTLCD 简介


TFT-LCD 即薄膜晶体管液晶显示器。TFT-LCD与无源 TN-LCD、 STN-LCD 的简单矩阵不同,它在液晶显示屏的每一个象素上都设置有一个薄膜晶体管( TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。 TFT-LCD 也被叫做真彩液晶显示器。ALIENTEK TFTLCD 模块采用 16 位的并方式与外部连接。


2.80 并口有如下一些信号线:


信号线 作用

CS TFTLCD 片选信号

WR 向 TFTLCD 写入数据

RD 从 TFTLCD 读取数据

D[15: 0] 16 位双向数据线

RST 硬复位 TFTLCD

RS 命令/数据标志( 0,读写命令; 1,读写数据)

注:TFTLCD 模块的 RST 信号线是直接接到 STM32 的复位脚上,并不由软件控制,这样可以省下来一个 IO口。另外我们还需要一个背光控制线来控制 TFTLCD 的背光。所以,我们总共需要的 IO 口数目为 21 个。


3.ILI9341 控制器介绍


ILI9341 液晶控制器自带显存,其显存总大小为 172800( 240*320*18/8),即 18 位模式( 26万色)下的显存量。在 16 位模式下, ILI9341 采用 RGB565 格式存储颜色数据,此时 ILI9341的 18 位数据线与 MCU 的 16 位数据线以及 LCD GRAM 的对应关系如图:


这里写图片描述


ILI9341 在 16 位模式下面,数据线有用的是: D17~D13 和 D11~D1, D0和 D12 没有用到,实际上在我们 LCD 模块里面, ILI9341 的 D0 和 D12 压根就没有引出来,这样, ILI9341 的 D17~D13 和 D11~D1 对应 MCU 的 D15~D0。


MCU 的 16 位数据, 最低 5 位代表蓝色,中间 6 位为绿色,最高 5 位为红色。数值越大,表示该颜色越深。 另外,特别注意 ILI9341 所有的指令都是 8 位的(高 8 位无效),且参数除了读写 GRAM 的时候是 16 位,其他操作参数,都是 8 位的。


4.ILI9341 的重要命令


(1)0XD3


这个是读 ID4 指令,用于读取 LCD 控制器的 ID


这里写图片描述


可以看出, 0XD3 指令后面跟了 4 个参数,最后 2 个参数,读出来是 0X93 和 0X41,刚好是控制器 ILI9341 的数字部分,从而,通过该指令,即可判别所用的 LCD 驱动器是什么型号,这样,我们的代码,就可以根据控制器的型号去执行对应驱动 IC 的初始化代码,从而兼容不同驱动 IC 的屏,使得一个代码支持多款 LCD。


(2)0X36


这是存储访问控制指令,可以控制 ILI9341 存储器的读写方向,简单的说,就是在连续写 GRAM 的时候,可以控制 GRAM 指针的增长方向,从而控制显示方式。(读 GRAM 也是一样)。该指令如表:


这里写图片描述

0X36 指令后面,紧跟一个参数,主要关注: MY、 MX、 MV 这三个位,通过这三个位的设置,可以控制整个 ILI9341 的全部扫描方向。


这里写图片描述


在利用 ILI9341 显示内容的时候,就有很大灵活性了,比如显示 BMP 图片,BMP 解码数据,就是从图片的左下角开始,慢慢显示到右上角,如果设置 LCD 扫描方向为从左到右,从下到上,那么我们只需要设置一次坐标,然后就不停的往 LCD 填充颜色数据即可,这样可以大大提高显示速度。


(3)0X2A


这是列地址设置指令, 在从左到右,从上到下的扫描方式(默认)下面,该指令用于设置横坐标( x 坐标),该指令如表 :


这里写图片描述


在默认扫描方式时,该指令用于设置 x 坐标,该指令带有 4 个参数,实际上是 2 个坐标值:SC 和 EC,即列地址的起始值和结束值, SC 必须小于等于 EC,且 0≤SC/EC≤239。一般在设置 x 坐标的时候,我们只需要带 2 个参数即可,也就是设置 SC 即可,因为如果 EC 没有变化,我们只需要设置一次即可(在初始化 ILI9341 的时候设置),从而提高速度。


(4)0X2B


是页地址设置指令, 在从左到右,从上到下的扫描方(默认)下面,该指令用于设置纵坐标( y 坐标)。该指令如表:


这里写图片描述


在默认扫描方式时,该指令用于设置 y 坐标,该指令带有 4 个参数,实际上是 2 个坐标值:SP 和 EP,即页地址的起始值和结束值, SP 必须小于等于 EP,且 0≤SP/EP≤319。一般在设置y 坐标的时候,我们只需要带 2 个参数即可,也就是设置 SP 即可,因为如果 EP 没有变化,我们只需要设置一次即可(在初始化 ILI9341 的时候设置),从而提高速度。


(5)0X2C


该指令是写 GRAM 指令,在发送该指令之后,我们便可以往 LCD的 GRAM 里面写入颜色数据了,该指令支持连续写,指令描述如表:


这里写图片描述

在收到指令 0X2C 之后,数据有效位宽变为 16 位,我们可以连续写入 LCD GRAM 值, 而 GRAM 的地址将根据 MY/MX/MV 设置的扫描方向进行自增。


(6)0X2E


该指令是读 GRAM 指令,用于读取 ILI9341 的显存( GRAM),输出情况如表:


这里写图片描述


该指令用于读取 GRAM,如表 所示,ILI9341在收到该指令后,第一次输出的是 dummy数据,也就是无效的数据,第二次开始,读取到的才是有效的 GRAM 数据(从坐标: SC, SP开始),输出规律为:每个颜色分量占 8 个位,一次输出 2 个颜色分量。


比如:


第一次输出是R1G1,随后的规律为:B1R2G2B2R3G3B3R4G4B4R5G5… 以此类推。如果我们只需要读取一个点的颜色值,那么只需要接收到参数 3 即可,如果要连续读取(利用 GRAM 地址自增),那么就按照上述规律去接收颜色数据。


5.TFTLCD 模块的使用流程


这里写图片描述


任何 LCD,使用流程都可以简单的用以上流程图表示。其中硬复位和初始化序列,只需要执行一次即可。而画点流程就是:设置坐标 -> 写 GRAM 指令 -> 写入颜色数据,然后在 LCD 上面,我们就可以看到对应的点显示我们写入的颜色了。读点流程为:设置坐标 -> 读 GRAM 指令 -> 读取颜色数据,这样就可以获取到对应点的颜色数据了。


1) 设置 STM32 与 TFTLCD 模块相连接的 IO。


先将我们与 TFTLCD 模块相连的 IO 口进行初始化,以便驱动 LCD。 这里需要根据连接电路以及 TFTLCD 模块的设置来确定。


2) 初始化 TFTLCD 模块。


即上图的初始化序列,这里我们没有硬复位 LCD,因为 MiniSTM32 开发板的 LCD 接口,将 TFTLCD 的 RST 同 STM32 的 RESET 连接在一起了,只要按下开发板的 RESET 键,就会对 LCD 进行硬复位。


初始化序列,就是向 LCD 控制器写入一系列的设置值(比如伽马校准),这些初始化序列一般 LCD 供应商会提供给客户,我们直接使用这些序列即可,不需要深入研究。在初始化之后, LCD 才可以正常使用。


3) 通过函数将字符和数字显示到 TFTLCD 模块上。


这一步则通过上图 左侧的流程,即:设置坐标->写 GRAM 指令->写 GRAM 来实现,但是这个步骤,只是一个点的处理,我们要显示字符/数字,就必须要多次使用这个步骤,从而达到显示字符/数字的目标,所以需要设计一个函数来实现数字/字符的显示,之后调用该函数,就可以实现数字/字符的显示了。


6.实例学习


(1)在硬件上, TFTLCD 模块与 MiniSTM32 开发板的 IO口对应关系如下:


功能 IO

LCD_LED PC10

LCD_CS PC9

LCD _RS PC8

LCD _WR PC7

LCD _RD PC6

LCD _D[17:1] PB[15:0]

(2)时序


模块的8080并口读/写的过程为:


先根据要写入/读取的数据的类型,设置RS为高(数据)/低(命令),然后拉低片选,选中ILI9341,接着我们根据是读数据,还是要写数据置RD/WR为低。


1.读数据:在RD的上升沿, 读取数据线上的数据(D[15:0]);


这里写图片描述


2.写数据:在WR的上升沿,使数据写入到ILI9341里面


这里写图片描述


3.例程分析


//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; 


/*写数据函数:通过 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;\

}   


void LCD_WR_DATAX(u16 data)

{

    LCD_RS_SET;

    LCD_CS_CLR;

    DATAOUT(data);

    LCD_WR_CLR;

    LCD_WR_SET;

    LCD_CS_SET;


/*通过 8080 并口向 LCD 模块写入寄存器命令*/

//写寄存器函数

//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 控制器的寄存器数据(非 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;

    LCD_RD_CLR; //读取数据(读寄存器时,并不需要读 2 次)

    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;

}


/*LCD 寄存器操作*/

//写寄存器:用于向 LCD 指定寄存器写入指定数据

//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 的当前操作点设置到指定坐标(x,y)

//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);

    }

}


//画点

//x,y:坐标

//POINT_COLOR:此点的颜色

void LCD_DrawPoint(u16 x,u16 y)

{

    LCD_SetCursor(x,y); //设置光标位置

    LCD_WriteRAM_Prepare(); //开始写入 GRAM

    LCD_WR_DATA(POINT_COLOR);

}


//读取个某点的颜色值

//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||lcddev.id==0X1963)

    LCD_WR_REG(0X2E);//9341/6804/3510/1963 发送读 GRAM 指令

    else if(lcddev.id==0X5510)LCD_WR_REG(0X2E00);//5510 发送读 GRAM 指令

    else LCD_WR_REG(0X22); //其他 IC 发送读 GRAM 指令

    GPIOB->CRL=0X88888888; //PB0-7 上拉输入

    GPIOB->CRH=0X88888888; //PB8-15 上拉输入

    GPIOB->ODR=0XFFFF; //全部输出高

    LCD_RS_SET;

    LCD_CS_CLR;

    LCD_RD_CLR; //读取数据(读 GRAM 时,第一次为假读)

    opt_delay(2); //延时

    r=DATAIN; //实际坐标颜色

    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); //延时

    r=DATAIN; //实际坐标颜色

    LCD_RD_SET;

    if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)//这几个 IC 要分 2 次读出

    {

    LCD_RD_CLR;

    opt_delay(2);//延时

    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)<

    else return LCD_BGR2RGB(r); //其他 IC


//在指定位置显示一个字符

//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;

            }

        }

    }

}


//该初始化函数可以初始化各种 ALIENTEK 出品的 LCD 液晶屏

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

                    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,为方便区分,我们强制设置为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);         //默认为竖屏

    LCD_LED=1;                  //点亮背光

    LCD_Clear(WHITE);

}       


注:此处仅为9341 的初始化

关键字:STM32  TFTLCD  显示

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/2019/ic-news010942858.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32学习笔记一一ADC
下一篇:STM32学习笔记一一窗口看门狗

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32堆栈设置

1.堆和栈大小 定义大小在startup_stm32f2xx.sStack_Size      EQU     0x00000400                AREA    STACK, NOINIT, READWRITE, ALIGN=3Stack_Mem      
发表于 2019-04-16
STM32堆栈设置

STM32堆和栈(Heap & Stack)的资料理解

源起:在移植cjson的过程中,解析json包的时候发现动态内存分配不足而导致解析失败,为解决这一问题,而深入了解stm32的堆和栈。stm32的存储器结构。Flash,SRAM寄存器和输入输出端口被组织在同一个4GB的线性地址空间内。可访问的存储器空间被分成8个主要块,每个块为512MB。FLASH存储下载的程序。SRAM是存储运行程序中的数据。而SRAM一般分这几个部分:静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率
发表于 2019-04-16
STM32堆和栈(Heap & Stack)的资料理解

STM32定义堆栈地址到ram区顶部

本设置针对stm32f103rbt6的设置,该芯片RAM大小为20kB,故RAM区地址范围为0x20000000—0x20005000,芯片信息如下图所示;第一步:设置.sct文件;;*************************************************************; *** Scatter-Loading Description Filegenerated by uVision ***; *************************************************************LR_IROM1 0x08000000 0x00020000  
发表于 2019-04-16
STM32定义堆栈地址到ram区顶部

STM32之程序如何防止堆栈溢出

近日为某个项目写了个草稿程序,即非正式程序,后来发现老是进入hardfaulthandler,原来是堆栈溢出,后仔细查看发现函数调用纵深太深,最多的时候可保持7个函数在堆栈中调用。因此有心得如下:一、函数调用不要纵深太深,即以下模式:main(){   fun1();}fun1(){  fun2();}fun2(){   fun3();}fun3(){  fun4();}fun4(){  fun5();}fun5(){  fun6();}fun6(){   fun7();}这样子main函数要调用fun1函数完成某个功能,则要一直调到
发表于 2019-04-16

stm32之堆栈

stm32中的堆栈设置keil编译完成时存储情况当编译成功时,会出现: BUILD://Program Size: Code=340 RO-data=252 RW-data=0 ZI-data=1632Code:程序代码部分RO-data: 程序定义的常量const tempRW-data:已初始化的全局变量ZI-data:未初始化的全局变量片中的:flash=Code+RO-data+RW-dataRAM=RW-data+ZI-data通过上面的BUILD可以看出,这个程序已经用了1600多的RAM,为什么会出用到这么多的RAM呢?在startup_stm32f10x_md.s文件中存在:St
发表于 2019-04-16

说说STM32的堆栈与内存

1.概念这里所说的堆栈,是针对单片机所说的“堆”与“栈”,指的是内存中一片特殊用途的区域。而不是数据结构中的堆栈(虽然其实规则一样)。这里所说的内存,是指RAM,RAM包括SRAM,DRAM等。而不是什么手机内存卡之类。这里所说的flash,指的是用作为ROM的存储器,保存代码与常量数据。而不是动画制作。。。栈的生长方向:指的是入栈方向,从高地址向低地址生长叫做向下生长,或逆向生长;反过来就叫向上生长,或正向生长。STM32的栈是向下生长。2.内存中的堆栈安排确切地说,是keil mdk根据STM32的特性,对stm32的RAM甚至flash进行部署。编译工程后,在生成的.map文件里可以看到具体的安排。双击工程界面的工程根目录
发表于 2019-04-16
说说STM32的堆栈与内存

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved