OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 31178|回复: 83

【ALIENTEK 战舰STM32开发板例程系列连载+教学】第十八章 TFTLCD显示实验

[复制链接]

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-1-25 17:46:46 | 显示全部楼层 |阅读模式

第十八章 TFTLCD显示实验

上一章我们介绍了OLED模块及其显示,但是该模块只能显示单色/双色,不能显示彩色,而且尺寸也较小。本章我们将介绍ALIENTEK 2.8TFT LCD模块,该模块采用TFTLCD面板,可以显示16位色的真彩图片。在本章中,我们将使用战舰STM32开发板上的LCD接口,来点亮TFTLCD,并实现ASCII字符和彩色的显示等功能,并在串口打印LCD控制器ID,同时在LCD上面显示。本章分为如下几个部分:

18.1 TFTLCD简介

18.2 硬件设计

18.3 软件设计

18.4 下载验证

18.1 TFTLCD&FSMC简介

本章我们将通过STM32FSMC接口来控制TFTLCD的显示,所以本节分为两个部分,分别介绍TFTLCDFSMC

18.1.1 TFTLCD简介

TFT-LCD即薄膜晶体管液晶显示器。其英文全称为:Thin Film Transistor-Liquid Crystal DisplayTFT-LCD与无源TN-LCDSTN-LCD的简单矩阵不同,它在液晶显示屏的每一个象素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。TFT-LCD也被叫做真彩液晶显示器。

上一章介绍了OLED模块,本章,我们给大家介绍ALIENTEK TFTLCD模块,该模块有如下特点:

12.4/2.8/3.53种大小的屏幕可选。

2320×240的分辨率(3.5分辨率为:320*480)。

316位真彩显示。

4,自带触摸屏,可以用来作为控制输入。

本章,我们以2.8寸的ALIENTEK TFTLCD模块为例介绍,该模块支持65K色显示,显示分辨率为320×240,接口为16位的80并口,自带触摸屏。

该模块的外观图如图18.1.1.1所示:


                 18.1.1.1 ALIENTEK 2.8TFTLCD外观图

       模块原理图如图18.1.1.2所示:


18.1.1.2  ALIENTEK 2.8TFTLCD模块原理图

TFTLCD模块采用2*172.54公排针与外部连接,接口定义如图18.1.1.3所示:


18.1.1.3  ALIENTEK 2.8TFTLCD模块接口图

从图18.1.1.3可以看出,ALIENTEK TFTLCD模块采用16位的并方式与外部连接,之所以不采用8位的方式,是因为彩屏的数据量比较大,尤其在显示图片的时候,如果用8位数据线,就会比16位方式慢一倍以上,我们当然希望速度越快越好,所以我们选择16位的接口。图18.1.3还列出了触摸屏芯片的接口,关于触摸屏本章我们不多介绍,后面的章节会有详细的介绍。该模块的80并口有如下一些信号线:

       CSTFTLCD片选信号。

       WR:向TFTLCD写入数据。

       RD:从TFTLCD读取数据。

       D[150]16位双向数据线。

       RST:硬复位TFTLCD

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

80并口在上一节我们已经有详细的介绍了,这里我们就不再介绍,需要说明的是,TFTLCD模块的RST信号线是直接接到STM32的复位脚上,并不由软件控制,这样可以省下来一个IO口。另外我们还需要一个背光控制线来控制TFTLCD的背光。所以,我们总共需要的IO口数目为21个。这里还需要注意,我们标注的DB1~DB8DB10~DB17,是相对于LCD控制IC标注的,实际上大家可以把他们就等同于D0~D15,这样理解起来就比较简单一点。

ALIENTEK提供的2.8TFTLCD模块,其驱动芯片有很多种类型,比如有:ILI9320/ILI9325

/ILI9328/ILI9341/SSD1289/LGDP4531/LGDP4535/R61505/ SPFD5408/ RM68021(具体的型号,大家可以通过下载本章实验代码,通过串口或者LCD显示查看),这里我们仅以ILI9320控制器为例进行介绍,其他的控制基本都类似,我们就不详细阐述了。

ILI9320液晶控制器自带显存,其显存总大小为172820240*320*18/8),即18位模式(26万色)下的显存量。模块的16位数据线与显寸的对应关系为565方式,如图18.1.1.4所示:


18.1.1.4  16位数据与显存对应关系图

最低5位代表蓝色,中间6位为绿色,最高5位为红色。数值越大,表示该颜色越深。

接下来,我们介绍一下ILI9320的几个重要命令,因为ILI9320的命令很多,我们这里不可能一一介绍,有兴趣的大家可以找到ILI9320datasheet看看。里面对这些命令有详细的介绍。这里我们要介绍的命令列表如表18.1.1.1所示:


18.1.1.1 ILI9320常用命令表

R0,这个命令,有两个功能,如果对它写,则最低位为OSC,用于开启或关闭振荡器。而如果对它读操作,则返回的是控制器的型号。这个命令最大的功能就是通过读它可以得到控制器的型号,而我们代码在知道了控制器的型号之后,可以针对不同型号的控制器,进行不同的初始化。因为93xx系列的初始化,其实都比较类似,我们完全可以用一个代码兼容好几个控制器。

R3,入口模式命令。我们重点关注的是I/D0I/D1AM3个位,因为这3个位控制了屏幕的显示方向。

AM:控制GRAM更新方向。当AM=0的时候,地址以行方向更新。当AM=1的时候,地址以列方向更新。

I/D[10]:当更新了一个数据之后,根据这两个位的设置来控制地址计数器自动增加/减少1

其关系如图18.1.1.5所示:

      


18.1.1.5  GRAM显示方向设置图

通过这几个位的设置,我们就可以控制屏幕的显示方向了,这种方法虽然简单,但是不是很通用,比如不同的液晶,可能这里差别就比较大,有的甚至无法通用!比如93419320就完全不通用。

R7,显示控制命令。该命令CL位用来控制是8位彩色,还是26万色。为026万色,为1时八位色。D1D0BASEE这三个位用来控制显示开关与否的。当全部设置为1的时候开启显示,全0是关闭。我们一般通过该命令的设置来开启或关闭显示器,以降低功耗。

R32R33,设置GRAM的行地址和列地址。R32用于设置列地址(X坐标,0~239),R33用于设置行地址(Y坐标,0~319)。当我们要在某个指定点写入一个颜色的时候,先通过这两个命令设置到改点,然后写入颜色值就可以了。

R34,写数据到GRAM命令,当写入了这个命令之后,地址计数器才会自动的增加和减少。该命令是我们要介绍的这一组命令里面唯一的单个操作的命令,只需要写入该值就可以了,其他的都是要先写入命令编号,然后写入操作数。

R80~R83,行列GRAM地址位置设置。这几个命令用于设定你显示区域的大小,我们整个屏的大小为240*320,但是有时候我们只需要在其中的一部分区域写入数据,如果用先写坐标,后写数据这样的方式来实现,则速度大打折扣。此时我们就可以通过这几个命令,在其中开辟一个区域,然后不停的丢数据,地址计数器就会根据R3的设置自动增加/减少,这样就不需要频繁的写地址了,大大提高了刷新的速度。

命令部分,我们就为大家介绍到这里,我们接下来看看要如何才能驱动ALIENTEK TFTLCD模块,这里TFTLCD模块的初始化和我们前面介绍的OLED模块的初始化框图是一样的,只是初始化代码部分不同。接下来我们也是将该模块用来来显示字符和数字。通过以上介绍,我们可以得出TFTLCD显示需要的相关设置步骤如下:

1)设置STM32TFTLCD模块相连接的IO

这一步,先将我们与TFTLCD模块相连的IO口进行初始化,以便驱动LCD。这里我们用到的是FSMCFSMC将在18.1.2节向大家详细介绍。

2)初始化TFTLCD模块。

其实这里就是上和上面OLED模块的初始化过程差不多。通过向TFTLCD写入一系列的设置,来启动TFTLCD的显示。为后续显示字符和数字做准备。

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

这里就是通过我们设计的程序,将要显示的字符送到TFTLCD模块就可以了,这些函数将在软件设计部分向大家介绍。通过以上三步,我们就可以使用ALIENTEK TFTLCD模块来显示字符和数字了, 并且可以显示各种颜色的背景。

18.1.2 FSMC简介

大容量,且引脚数在100脚以上的STM32F103芯片都带有FSMC接口,ALIENTEK战舰STM32开发板的主芯片为STM32F103ZET6,是带有FSMC接口的。

FSMC,即灵活的静态存储控制器,能够与同步或异步存储器和16PC存储器卡接口,STM32FSMC接口支持包括SRAMNAND FLASHNOR FLASHPSRAM等存储器。FSMC的框图如图18.1.2.1所示:


18.1.2.1 FSMC框图

       从上图我们可以看出,STM32FSMC将外部设备分为3类:NOR/PSRAM设备、NAND设备、PC卡设备。他们共用地址数据总线等信号,他们具有不同的CS以区分不同的设备,比如本章我们用到的TFTLCD就是用的FSMC_NE4做片选,其实就是将TFTLCD当成SRAM来控制。

这里我们介绍下为什么可以把TFTLCD当成SRAM设备用:首先我们了解下外部SRAM的连接,外部SRAM的控制一般有:地址线(如A0~A18)、数据线(如D0~D15)、写信号(WE)、读信号(OE)、片选信号(CS),如果SRAM支持字节控制,那么还有UB/LB信号。而TFTLCD的信号我们在18.1.1节有介绍,包括:RSD0~D15WRRDCSRSTBL等,其中真正在操作LCD的时候需要用到的就只有:RSD0~D15WRRDCS。其操作时序和SRAM的控制完全类似,唯一不同就是TFTLCDRS信号,但是没有地址信号。

TFTLCD通过RS信号来决定传送的数据是数据还是命令,本质上可以理解为一个地址信号,比如我们把RS接在A0上面,那么当FSMC控制器写地址0的时候,会使得A0变为0,对TFTLCD来说,就是写命令。而FSMC写地址1的时候,A0将会变为1,对TFTLCD来说,就是写数据了。这样,就把数据和命令区分开了,他们其实就是对应SRAM操作的两个连续地址。当然RS也可以接在其他地址线上,战舰STM32开发板是把RS连接在A10上面的。

STM32FSMC支持8/16/32位数据宽度,我们这里用到的LCD16位宽度的,所以在设置的时候,选择16位宽就OK了。我们再来看看FSMC的外部设备地址映像,STM32FSMC将外部存储器划分为固定大小为256M字节的四个存储块,如图18.1.2.2所示:


18.1.2.2 FSMC存储块地址映像

       从上图可以看出,FSMC总共管理1GB空间,拥有4个存储块(Bank),本章,我们用到的是块1,所以在本章我们仅讨论块1的相关配置,其他块的配置,请参考《STM32参考手册》第19章(324页)的相关介绍。

       STM32FSMC存储块1Bank1)被分为4个区,每个区管理64M字节空间,每个区都有独立的寄存器对所连接的存储器进行配置。Bank1256M字节空间由28根地址线(HADDR[27:0])寻址。

       这里HADDR是内部AHB地址总线,其中HADDR[25:0]来自外部存储器地址FSMC_A[25:0],而HADDR[26:27]4个区进行寻址。如表18.1.2.1所示:

Bank1所选区

片选信号

地址范围

HADDR

[27:26]

[25:0]

1

FSMC_NE1

0X6000,0000~63FF,FFFF

00

FSMC_A[25:0]

2

FSMC_NE2

0X6400,0000~67FF,FFFF

01

3

FSMC_NE3

0X6800,0000~6BFF,FFFF

10

4

FSMC_NE4

0X6C00,0000~6FFF,FFFF

11

18.1.2.1 Bank1存储区选择表

       18.1.2.1中,我们要特别注意HADDR[25:0]的对应关系:

Bank1接的是16位宽度存储器的时候:HADDR[25:1]à FSMC[24:0]

Bank1接的是8位宽度存储器的时候:HADDR[25:0]à FSMC[25:0]

不论外部接8/16位宽设备,FSMC_A[0]永远接在外部设备地址A[0] 这里,TFTLCD使用的是16位数据宽度,所以HADDR[0]并没有用到,只有HADDR[25:1]是有效的,对应关系变为:HADDR[25:1]à FSMC[24:0],相当于右移了一位,这里请大家特别留意。另外,HADDR[27:26]的设置,是不需要我们干预的,比如:当你选择使用Bank1的第三个区,即使用FSMC_NE3来连接外部设备的时候,即对应了HADDR[27:26]=10,我们要做的就是配置对应第3区的寄存器组,来适应外部设备即可。STM32FSMCBank配置寄存器如表18.1.2.2所示:

内部控制器

存储块

管理的地址范围

支持的设备类型

配置寄存器

NOR FLASH控制器

Bank1

0X6000,0000~
0X6FFF,FFFF

SRAM/ROM
NOR FLASH
PSRAM

FSMC_BCR1/2/3/4
FSMC_BTR1/2/2/3
FSMC_BWTR1/2/3/4

NAND FLASH
/PC CARD
控制器

Bank2

0X7000,0000~
0X7FFF,FFFF

NAND FLASH

FSMC_PCR2/3/4
FSMC_SR2/3/4
FSMC_PMEM2/3/4
FSMC_PATT2/3/4
FSMC_PIO4

Bank3

0X8000,0000~
0X8FFF,FFFF

Bank4

0X9000,0000~
0X9FFF,FFFF

PC Card

18.1.2.2 FSMCBank配置寄存器表

       对于NOR FLASH控制器,主要是通过FSMC_BCRxFSMC_BTRxFSMC_BWTRx寄存器设置(其中x=1~4,对应4个区)。通过这3个寄存器,可以设置FSMC访问外部存储器的时序参数,拓宽了可选用的外部存储器的速度范围。FSMCNOR FLASH控制器支持同步和异步突发两种访问方式。选用同步突发访问方式时,FSMCHCLK(系统时钟)分频后,发送给外部存储器作为同步时钟信号FSMC_CLK。此时需要的设置的时间参数有2个:

  1HCLKFSMC_CLK的分频系数(CLKDIV),可以为216分频;

  2,同步突发访问中获得第1个数据所需要的等待延迟(DATLAT)

对于异步突发访问方式,FSMC主要设置3个时间参数:地址建立时间(ADDSET)、数据建立时间(DATAST)和地址保持时间(ADDHLD)FSMC综合了SRAMROMPSRAMNOR Flash产品的信号特点,定义了4种不同的异步时序模型。选用不同的时序模型时,需要设置不同的时序参数,如表18.1.2.3所列:

时序模型

简单描述

时间参数

异步

Mode1

SRAM/CRAM时序

DATASTADDSET

ModeA

SRAM/CRAM OE选通型时序

DATASTADDSET

Mode2/B

NOR FLASH时序

DATASTADDSET

ModeC

NOR FLASH OE选通型时序

DATASTADDSET

ModeD

延长地址保持时间的异步时序

DATASTADDSETADDHLK

同步突发

根据同步时钟FSMC_CK读取
多个顺序单元的数据

CLKDIVDATLAT

18.1.2.3 NOR FLASH控制器支持的时序模型

在实际扩展时,根据选用存储器的特征确定时序模型,从而确定各时间参数与存储器读/写周期参数指标之间的计算关系;利用该计算关系和存储芯片数据手册中给定的参数指标,可计算出FSMC所需要的各时间参数,从而对时间参数寄存器进行合理的配置。

本章,我们使用异步模式AModeA)方式来控制TFTLCD,模式A的读操作时序如图18.1.2.3所示:


18.1.2.3 模式A读操作时序图

       模式A支持独立的读写时序控制,这个对我们驱动TFTLCD来说非常有用,因为TFTLCD在读的时候,一般比较慢,而在写的时候可以比较快,如果读写用一样的时序,那么只能以读的时序为基准,从而导致写的速度变慢,或者在读数据的时候,重新配置FSMC的延时,在读操作完成的时候,再配置回写的时序,这样虽然也不会降低写的速度,但是频繁配置,比较麻烦。而如果有独立的读写时序控制,那么我们只要初始化的时候配置好,之后就不用再配置,既可以满足速度要求,又不需要频繁改配置。

       模式A的写操作时序如图18.1.2.4所示:


18.1.2.4 模式A写操作时序

       从模式A的读写时序图,我们可以看出,读操作还存在额外的2HCLK周期,用于数据存储,所以同样的配置读操作一般比写操作会慢一点。图18.1.2.3和图18.1.2.4中的ADDSETDATAST,是通过不同的寄存器设置的,接下来我们讲解一下Bank1的几个控制寄存器

       首先,我们介绍SRAM/NOR闪存片选控制寄存器:FSMC_BCRxx=1~4),该寄存器各位描述如图18.1.2.5所示:





18.1.2.5 FSMC_BCRx寄存器各位描述

该寄存器我们在本章用到的设置有:EXTMODWRENMWIDMTYPMBKEN这几个设置,我们将逐个介绍。

EXTMOD:扩展模式使能位,也就是是否允许读写不同的时序,很明显,我们本章需要读写不同的时序,故该位需要设置为1

WREN:写使能位。我们需要向TFTLCD写数据,故该位必须设置为1

       MWID[1:0]:存储器数据总线宽度。00,表示8位数据模式;01表示16位数据模式;1011保留。我们的TFTLCD16位数据线,所以设置WMID[1:0]=01

       MTYP[1:0]:存储器类型。00表示SRAMROM01表示PSRAM10表示NOR FLASH;11保留。前面提到,我们把TFTLCD当成SRAM用,所以需要设置MTYP[1:0]=00

       MBKEN:存储块使能位。这个容易理解,我们需要用到该存储块控制TFTLCD,当然要使能这个存储块了。

       接下来,我们看看SRAM/NOR闪存片选时序寄存器:FSMC_BTRxx=1~4),该寄存器各位描述如图18.1.2.6所示:

 


18.1.2.6 FSMC_BTRx寄存器各位描述

       这个寄存器包含了每个存储器块的控制信息,可以用于SRAMROMNOR闪存存储器。如果FSMC_BCRx寄存器中设置了EXTMOD位,则有两个时序寄存器分别对应读(本寄存器)和写操作(FSMC_BWTRx寄存器)。因为我们要求读写分开时序控制,所以EXTMOD是使能了的,也就是本寄存器是读操作时序寄存器,控制读操作的相关时序。本章我们要用到的设置有:ACCMODDATASTADDSET这三个设置。

       ACCMOD[1:0]:访问模式。00表示访问模式A01表示访问模式B10表示访问模式C11表示访问模式D,本章我们用到模式A,故设置为00

       DATAST[7:0]:数据保持时间。0为保留设置,其他设置则代表保持时间为: (DATAST +1)HCLK时钟周期,最大为256HCLK周期。对ILI9320来说,其实就是RD低电平持续时间,一般为150ns。而一个HCLK时钟周期为13.8ns左右(1/72Mhz),为了兼容其他屏,我们这里设置DATAST15,也就是16HCLK周期,时间大约是234ns(未计算数据存储的2HCLK时间)。

       ADDSET[3:0]:地址建立时间。其建立时间为:(ADDSET+1)个HCLK周期,最大为16HCLK周期。对ILI9320来说,这里相当于RD高电平持续时间,本来这里我们应该设置和DATAST一样,但是由于CS切换延时的存在,我们这里可以设置ADDSET为较小的值,本章我们设置ADDSET1,即2HCLK周期,同样可以正常使用。

最后,我们再来看看SRAM/NOR闪写时序寄存器:FSMC_BWTRxx=1~4),该寄存器各位描述如图18.1.2.7所示:


18.1.2.7 FSMC_BWTRx寄存器各位描述

       该寄存器在本章用作写操作时序控制寄存器,需要用到的设置同样是:ACCMODDATASTADDSET这三个设置。这三个设置的方法同FSMC_BTRx一模一样,只是这里对应的是写操作的时序,ACCMOD设置同FSMC_BTRx一模一样,同样是选择模式A,另外DATASTADDSET则对应低电平和高电平持续时间,对ILI9320来说,这两个时间只需要50ns就够了,比读操作快得多。所以我们这里设置DATAST3,即4HCLK周期,时间约为55ns。同样由于CS切换延时的存在,我们可以设置ADDSET0,即1HCLK周期。

       至此,我们对STM32FSMC介绍就差不多了,通过以上两个小节的了解,我们可以开始写LCD的驱动代码了。不过,这里还要给大家做下科普,在MDK的寄存器定义里面,并没有定义FSMC_BCRxFSMC_BTRxFSMC_BWTRx等这个单独的寄存器,而是将他们进行了一些组合。

       FSMC_BCRxFSMC_BTRx,组合成BTCR[8]寄存器组,他们的对应关系如下:

BTCR[0]对应FSMC_BCR1BTCR[1]对应FSMC_BTR1

BTCR[2]对应FSMC_BCR2BTCR[3]对应FSMC_BTR2

BTCR[4]对应FSMC_BCR3BTCR[5]对应FSMC_BTR3

BTCR[6]对应FSMC_BCR4BTCR[7]对应FSMC_BTR4

FSMC_BWTRx则组合成BWTR[7],他们的对应关系如下:

BWTR[0]对应FSMC_BWTR1BWTR[2]对应FSMC_BWTR2

BWTR[4]对应FSMC_BWTR3BWTR[6]对应FSMC_BWTR4

BWTR[1]BWTR[3]BWTR[5]保留,没有用到。

 

18.2 硬件设计

本实验用到的硬件资源有:

1)  指示灯DS0

2)  TFTLCD模块

TFTLCD模块的电路见图18.1.1.2,这里我们介绍TFTLCD模块与ALIETEK 战舰STM32开发板的连接,战舰STM32开发板底板的LCD接口和ALIENTEK TFTLCD模块直接可以对插,连接关系如图18.2.1所示:


                          18.2.1 TFTLCD与开发板连接示意图

18.2.1中圈出来的部分就是连接TFTLCD模块的接口,板上的接口比液晶模块的插针要多2个口,液晶模块在这里是靠右插的。多出的2个口是给OLED用的,所以OLED模块在接这里的时候,是靠左插的,这个请大家注意一下。

在硬件上,TFTLCD模块与战舰STM32开发板的IO口对应关系如下:

       LCD_BL(背光控制)对应PB0;

       LCD_CS对应PG12FSMC_NE4;

       LCD _RS对应PG0FSMC_A10;

       LCD _WR对应PD5FSMC_NWE;

       LCD _RD对应PD4FSMC_NOE;

       LCD _D[15:0]则直接连接在FSMC_D15~FSMC_D0;

这些线的连接,战舰STM32开发板的内部已经连接好了,我们只需要将TFTLCD模块插上去就好了。实物连接如图18.2.2所示:



18.2.2 TFTLCD与开发板连接实物图

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-1-25 17:49:47 | 显示全部楼层

18.3 软件设计

软件设计我们依旧在之前的工程上面增加,首先在HARDWARE文件夹下新建一个LCD的文件夹。然后打开USER文件夹下的工程,新建一个ILI93xx.c的文件和lcd.h的头文件,保存在LCD文件夹下,并将LCD文件夹加入头文件包含路径。

ILI93xx.c里面要输入的代码比较多,我们这里就不贴出来了,只针对几个重要的函数进行讲解。完整版的代码见光盘à4,程序源码à标准例程à实验13 TFTLCD显示实验的ILI93xx.c文件。

本实验,我们用到FSMC驱动LCD,通过前面的介绍,我们知道TFTLCDRS接在FSMCA10上面,CS接在FSMC_NE4上,并且是16位数据总线。即我们使用的是FSMC存储器1的第4区,我们定义如下LCD操作结构体(在lcd.h里面定义):

//LCD操作结构体

typedef struct

{

       u16 LCD_REG;

       u16 LCD_RAM;

} LCD_TypeDef;

//使用NOR/SRAM Bank1.sector4,地址位HADDR[27,26]=11 A10作为数据命令区分线

//注意16位数据总线时,STM32内部地址会右移一位对齐!        

#define LCD_BASE        ((u32)(0x6C000000 | 0x000007FE))

#define LCD             ((LCD_TypeDef *) LCD_BASE)

其中LCD_BASE,必须根据我们外部电路的连接来确定,我们使用Bank1.sector4就是从地址0X6C000000开始,而0X000007FE,则是A10的偏移量。我们将这个地址强制转换为LCD_TypeDef结构体地址,那么可以得到LCD->LCD_REG的地址就是0X6C00,07FE,对应A10的状态为0(RS=0),而LCD-> LCD_RAM的地址就是0X6C00,0800(结构体地址自增),对应A10的状态为1(即RS=1)。

所以,有了这个定义,当我们要往LCD写命令/数据的时候,可以这样写:

LCD->LCD_REG=CMD;  //写命令

LCD->LCD_RAM=DATA; //写数据

而读的时候反过来操作就可以了,如下所示:

CMD= LCD->LCD_REG;//LCD寄存器

 DATA = LCD->LCD_RAM;//LCD数据

这其中,CSWRRDIO口方向都是由FSMC控制,不需要我们手动设置了。接下来,我们先介绍一下lcd.h里面的另一个重要结构体:

//LCD重要参数集

typedef struct 

{                                                                       

       u16 width;                    //LCD 宽度

       u16 height;                   //LCD 高度

       u16 id;                         //LCD ID

       u8  dir;                       //横屏还是竖屏控制:0,竖屏;1,横屏。    

       u8    wramcmd;             //开始写gram指令

       u8  setxcmd;                //设置x坐标指令

       u8  setycmd;                //设置y坐标指令 

}_lcd_dev;

//LCD参数

extern _lcd_dev lcddev; //管理LCD重要参数

该结构体用于保存一些LCD重要参数信息,比如LCD的长宽、LCD ID(驱动IC型号)、LCD横竖屏状态等,这个结构体虽然占用了10个字节的内存,但是却可以让我们的驱动函数支持不同尺寸的LCD,同时可以实现LCD横竖屏切换等重要功能,所以还是利大于弊的。有了以上了解,下面我们开始介绍ILI93xx.c里面的一些重要函数。

先看6个简单,但是很重要的函数:

//写寄存器函数

//regval:寄存器值

void LCD_WR_REG(u16 regval)

{

       LCD->LCD_REG=regval;//写入要写的寄存器序号  

}

//LCD数据

//data:要写入的值

void LCD_WR_DATA(u16 data)

{                                                                                  

       LCD->LCD_RAM=data;             

}

//LCD数据

//返回值:读到的值

u16 LCD_RD_DATA(void)

{                                                                                  

       return LCD->LCD_RAM;           

}                                   

//写寄存器

//LCD_Reg:寄存器地址

//LCD_RegValue:要写入的数据

void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)

{    

       LCD->LCD_REG = LCD_Reg;            //写入要写的寄存器序号    

       LCD->LCD_RAM = LCD_RegValue;//写入数据                    

}       

//读寄存器

//LCD_Reg:寄存器地址

//返回值:读到的数据

u16 LCD_ReadReg(u8 LCD_Reg)

{                                                                      

       LCD_WR_REG(LCD_Reg);         //写入要读的寄存器序号

       delay_us(5);            

       return LCD_RD_DATA();            //返回读到的值

}  

//开始写GRAM

void LCD_WriteRAM_Prepare(void)

{

      LCD->LCD_REG=lcddev.wramcmd;     

}    

因为FSMC自动控制了WR/RD/CS等这些信号,所以这6个函数实现起来都非常简单,我们就不多说,实现功能见函数前面的备注,通过这几个简单函数的组合,我们就可以对LCD进行各种操作了。

第七个要介绍的函数是坐标设置函数,该函数代码如下:

//设置光标位置

//Xpos:横坐标

//Ypos:纵坐标

void LCD_SetCursor(u16 Xpos, u16 Ypos)

{    

      if(lcddev.id==0X9341)

       {               

              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.dir==1)Xpos=lcddev.width-1-Xpos;//横屏其实就是调转x,y坐标

              LCD_WriteReg(lcddev.setxcmd, Xpos);

              LCD_WriteReg(lcddev.setycmd, Ypos);

       }    

}

该函数实现将LCD的当前操作点设置到指定坐标(x,y)。因为9341的设置同其他屏有些不太一样,所以单独对9341进行了设置。

接下来我们介绍第八个函数:画点函数。该函数实现代码如下:

//画点

//x,y:坐标

//POINT_COLOR:此点的颜色

void LCD_DrawPoint(u16 x,u16 y)

{

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

       LCD_WriteRAM_Prepare();  //开始写入GRAM

       LCD->LCD_RAM=POINT_COLOR;

}

该函数实现比较简单,就是先设置坐标,然后往坐标写颜色。其中POINT_COLOR是我们定义的一个全局变量,用于存放画笔颜色,顺带介绍一下另外一个全局变量:BACK_COLOR,该变量代表LCD的背景色。LCD_DrawPoint函数虽然简单,但是至关重要,其他几乎所有上层函数,都是通过调用这个函数实现的。

有了画点,当然还需要有读点的函数,第九个介绍的函数就是读点函数,用于读取LCDGRAM,这里说明一下,为什么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=0,g=0,b=0;

       if(x>=lcddev.width||y>=lcddev.height)return 0;   //超过了范围,直接返回          

       LCD_SetCursor(x,y);        

       if(lcddev.id==0X9341)LCD_WR_REG(0X2E);          //9341 发送读GRAM指令

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

      if(lcddev.id==0X9320)opt_delay(2);                         //FOR 9320,延时2us        

       if(LCD->LCD_RAM)r=0;                                        //dummy Read         

       opt_delay(2);   

      r=LCD->LCD_RAM;                                            //实际坐标颜色

      if(lcddev.id==0X9341)//9341要分2次读出

      {

              opt_delay(2);   

              b=LCD->LCD_RAM;

              g=r&0XFF;//对于9341,第一次读取的是RG的值,R在前,G在后,各占8

              g<<=8;

       }

//这几种IC直接返回颜色值

if(lcddev.id==0X9325||lcddev.id==0X4535||lcddev.id==0X4531||lcddev.id==0X8989||

lcddev.id==0XB505)return r;     

else if(lcddev.id==0X9341)return (((r>>11)<<11)|((g>>10)<<5)|(b>>11));  

//ILI9341需要公式转换一下

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

}

LCD_ReadPoint函数中,因为我们的代码不止支持一种LCD驱动器,所以,我们根据不同的LCD驱动器((lcddev.id)型号,执行不同的操作,以实现对各个驱动器兼容,提高函数的通用性。

第十个要介绍的是字符显示函数LCD_ShowChar,该函数同前面OLED模块的字符显示函数差不多,但是这里的字符显示函数多了1个功能,就是可以以叠加方式显示,或者以非叠加方式显示。叠加方式显示多用于在显示的图片上再显示字符。非叠加方式一般用于普通的显示。该函数实现代码如下:

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

//x,y:起始坐标

//num:要显示的字符:" "--->"~"

//size:字体大小 12/16

//mode:叠加方式(1)还是非叠加方式(0)

void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)

{                                                

    u8 temp,t1,t;

       u16 y0=y;

       u16 colortemp=POINT_COLOR;                               

       //设置窗口              

       num=num-' ';//得到偏移后的值

       if(!mode) //非叠加方式

       {

           for(t=0;t<size;t++)

           {  

                     if(size==12)temp=asc2_1206[num][t];  //调用1206字体

                     else temp=asc2_1608[num][t];             //调用1608字体                                  

               for(t1=0;t1<8;t1++)

                     {                      

                      if(temp&0x80)POINT_COLOR=colortemp;

                            else POINT_COLOR=BACK_COLOR;

                            LCD_DrawPoint(x,y);  

                            temp<<=1;

                            y++;

                            if(x>=lcddev.height) {POINT_COLOR=colortemp;return;}//超区域了

                            if((y-y0)==size)

                            {

                                   y=y0;

                                   x++;

                                   if(x>=lcddev.width) {POINT_COLOR=colortemp;return;}//超区域了

                                   break;

                            }

                     }     

           }   

       }else//叠加方式

       {

           for(t=0;t<size;t++)

           {  

                     if(size==12)temp=asc2_1206[num][t];  //调用1206字体

                     else temp=asc2_1608[num][t];             //调用1608字体                                  

               for(t1=0;t1<8;t1++)

                     {                      

                      if(temp&0x80)LCD_DrawPoint(x,y);

                            temp<<=1;

                            y++;

                            if(x>=lcddev.height) {POINT_COLOR=colortemp;return;}//超区域了

                            if((y-y0)==size)

                            {

                                   y=y0;

                                   x++;

                                   if(x>=lcddev.width) {POINT_COLOR=colortemp;return;}//超区域了

                                   break;

                            }

                     }     

           }    

       }

       POINT_COLOR=colortemp;                         

} 

LCD_ShowChar函数里面,我们采用画点函数来显示字符,虽然速度不如开辟窗口的方式,但是这样写可以有更好的兼容性,方便在不同LCD之间移植。该代码中我们用到了两个字符集点阵数据数组asc2_1206asc2_1608,这两个字符集的点阵数据的提取方式,同十七章介绍的提取方法是一模一样的。详细请参考第十七章。

最后,我们再介绍一下TFTLCD模块的初始化函数LCD_Init,该函数先初始化STM32TFTLCD连接的IO口,并配置FSMC控制器,然后读取LCD控制器的型号,根据控制IC的型号执行不同的初始化代码,其简化代码如下:

//初始化lcd

//该初始化函数可以初始化各种ILI93XX液晶,但是其他函数是基于ILI9320!!!

//在其他型号的驱动芯片上没有测试!

void LCD_Init(void)

{                                                                      

       RCC->AHBENR|=1<<8;       //使能FSMC时钟    

      RCC->APB2ENR|=1<<3;      //使能PORTB时钟

       RCC->APB2ENR|=1<<5;      //使能PORTD时钟

       RCC->APB2ENR|=1<<6;      //使能PORTE时钟

      RCC->APB2ENR|=1<<8;      //使能PORTG时钟

       RCC->APB2ENR|=1<<0;      //使能AFIO时钟   

       GPIOB->CRL&=0XFFFFFFF0;//PB0推挽输出 背光

       GPIOB->CRL|=0X00000003;         

       //PORTD复用推挽输出      

       GPIOD->CRH&=0X00FFF000;

       GPIOD->CRH|=0XBB000BBB;

       GPIOD->CRL&=0XFF00FF00;

       GPIOD->CRL|=0X00BB00BB;          

       //PORTE复用推挽输出      

       GPIOE->CRH&=0X00000000;

       GPIOE->CRH|=0XBBBBBBBB;

       GPIOE->CRL&=0X0FFFFFFF;

       GPIOE->CRL|=0XB0000000;                                                                                

       //PORTG12复用推挽输出 A0                                                                                 

       GPIOG->CRH&=0XFFF0FFFF;

       GPIOG->CRH|=0X000B0000;

       GPIOG->CRL&=0XFFFFFFF0;//PG0->RS

       GPIOG->CRL|=0X0000000B;

       //寄存器清零

       //bank1NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。

       //这里我们使用NE4 ,也就对应BTCR[6],[7]                             

       FSMC_Bank1->BTCR[6]=0X00000000;

       FSMC_Bank1->BTCR[7]=0X00000000;

       FSMC_Bank1E->BWTR[6]=0X00000000;

       //操作BCR寄存器       使用异步模式

       FSMC_Bank1->BTCR[6]|=1<<12;              //存储器写使能

       FSMC_Bank1->BTCR[6]|=1<<14;              //读写使用不同的时序

       FSMC_Bank1->BTCR[6]|=1<<4;              //存储器数据宽度为16bit       

       //操作BTR寄存器

       //读时序控制寄存器                                                  

       FSMC_Bank1->BTCR[7]|=0<<28;       //模式A                                                               

       FSMC_Bank1->BTCR[7]|=1<<0;       //地址建立时间(ADDSET)为2HCLK

       //因为液晶驱动IC的读数据的时候,速度不能太快,尤其对1289这个IC

       FSMC_Bank1->BTCR[7]|=0XF<<8;  //数据保存时间为16HCLK          

       //写时序控制寄存器 

       FSMC_Bank1E->BWTR[6]|=0<<28;  //模式A                                                            

       FSMC_Bank1E->BWTR[6]|=0<<0;     //地址建立时间(ADDSET)为1HCLK

//4HCLKHCLK=72M)因为液晶驱动IC的写信号脉宽,

//最少也得50ns72M/4=24M=55ns          

       FSMC_Bank1E->BWTR[6]|=3<<8;    //数据保存时间为4HCLK     

       //使能BANK1,区域4

       FSMC_Bank1->BTCR[6]|=1<<0;         //使能BANK1,区域4  

                      

       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)//读到ID不正确

       {    

              //尝试9341ID读取 

              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                             

      }

      printf(" LCD ID:%x\r\n",lcddev.id);     //打印LCD ID 

       if(lcddev.id==0X9341)                       //9341初始化

       {

              ……//9341初始化代码

       }else if(lcddev.id==0x9325)//9325

       {

              ……//9325初始化代码

}else if(lcddev.id==0x9328)                //ILI9328   OK 

       {

              ……//9328初始化代码

       }else if(lcddev.id==0x9320||lcddev.id==0x9300)//未测试.

       {

              ……//9300初始化代码

       }else if(lcddev.id==0X9331)                

       {

              ……//9331初始化代码

       }else if(lcddev.id==0x5408)

       {

              ……//5408初始化代码

       }    

       else if(lcddev.id==0x1505)//OK

       {

              ……//1505初始化代码

       }else if(lcddev.id==0xB505)

       {

              ……//B505初始化代码      

       }else if(lcddev.id==0xC505)

       {

              ……//C505初始化代码      

       }else if(lcddev.id==0x8989)

       {       

              ……//8989初始化代码              

       }else if(lcddev.id==0x4531)

       {

              ……//4531初始化代码

       }else if(lcddev.id==0x4535)

       {                        

              ……//4535初始化代码

       }           

       LCD_Display_Dir(0);                //默认为竖屏显示

       LCD_LED=1;                             //点亮背光

       LCD_Clear(WHITE);

}

该函数先对FSMC相关IO进行初始化,然后是FSMC的初始化,这个我们在前面都有介绍,最后根据读到的LCD ID,对不同的驱动器执行不同的初始化代码,从上面的代码可以看出,这个初始化函数可以针对13款不同的驱动IC执行初始化操作,这样大大提高了整个程序的通用性。大家在以后的学习中应该多使用这样的方式,以提高程序的通用性、兼容性。

特别注意:本函数使用了printf来打印LCD ID,所以,如果你在主函数里面没有初始化串口,那么将导致程序死在printf里面!!如果不想用printf,那么请注释掉它。

保存ILI93xx.c,并将该代码加入到HARDWARE组下。在介绍完了ILI93xx.c的内容之后,然后我们在lcd.h里面输入如下内容:

#ifndef __LCD_H

#define __LCD_H        

#include "sys.h"    

#include "stdlib.h"

//LCD重要参数集

typedef struct 

{                                                                       

       u16 width;                    //LCD 宽度

       u16 height;                   //LCD 高度

       u16 id;                         //LCD ID

       u8  dir;                       //横屏还是竖屏控制:0,竖屏;1,横屏。    

       u8    wramcmd;             //开始写gram指令

       u8  setxcmd;         //设置x坐标指令

       u8  setycmd;         //设置y坐标指令 

}_lcd_dev;       

//LCD参数

extern _lcd_dev lcddev; //管理LCD重要参数

//LCD的画笔颜色和背景色   

extern u16 POINT_COLOR;//默认红色   

extern u16 BACK_COLOR; //背景颜色.默认为白色

////////////////////////////////////////////////////////////////////////////////// 

//-----------------LCD端口定义----------------

#define    LCD_LED PBout(0) //LCD背光              PB0          

//LCD地址结构体

typedef struct

{

       u16 LCD_REG;

       u16 LCD_RAM;

} LCD_TypeDef;

//使用NOR/SRAM BANK 4,地址位HADDR[27,26]=11 A10作为数据命令区分线

//注意设置时STM32内部会右移一位对其! 111110=0X3E                       

#define LCD_BASE        ((u32)(0x6C000000 | 0x000007FE))

#define LCD             ((LCD_TypeDef *) LCD_BASE)

//////////////////////////////////////////////////////////////////////////////////

//扫描方向定义

#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 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);                                               //画点

u16 LCD_ReadPoint(u16 x,u16 y);                                             //读点

void 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(u8 LCD_Reg, u16 LCD_RegValue);

u16 LCD_ReadReg(u8 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);                                       //设置屏幕显示方向           

//9320/9325 LCD寄存器 

#define R0             0x00

……//省略部分

#define R229           0xE5                                                           

#endif

这段代码的两个重要结构体定义,我们都在前面有介绍,其他的相对就比较简单了。另外这段代码对颜色和驱动器的寄存器进行了很多宏定义,限于篇幅考虑,我们没有完全贴出来,省略了其中绝大部分。此部分我们就不多说了。接下来,我们在test.c里面修改main函数如下:

int main(void)

{

                                                                      

      u8 x=0;

       u8 lcd_id[12];               //存放LCD ID字符串

      Stm32_Clock_Init(9);    //系统时钟设置

       uart_init(72,9600);      //串口初始化为9600

       delay_init(72);                  //延时初始化

       LED_Init();                       //初始化与LED连接的硬件接口

      LCD_Init();

       POINT_COLOR=RED;

       sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//LCD ID打印到lcd_id数组       

      while(1)

       {           

              switch(x)

              {

                     case 0CD_Clear(WHITE);break;

                     case 1CD_Clear(BLACK);break;

                     case 2CD_Clear(BLUE);break;

                     case 3CD_Clear(RED);break;

                     case 4CD_Clear(MAGENTA);break;

                     case 5CD_Clear(GREEN);break;

                     case 6CD_Clear(CYAN);break;

case 7CD_Clear(YELLOW);break;

                     case 8CD_Clear(BRRED);break;

                     case 9CD_Clear(GRAY);break;

                     case 10:LCD_Clear(LGRAY);break;

                     case 11:LCD_Clear(BROWN);break;

              }

              POINT_COLOR=RED;   

              LCD_ShowString(30,50,200,16,16,"WarShip STM32 ^_^");    

              LCD_ShowString(30,70,200,16,16,"TFTLCD TEST");     

              LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");

             LCD_ShowString(30,110,200,16,16,lcd_id);              //显示LCD ID                                                 LCD_ShowString(30,130,200,16,16,"2012/9/5");          

           x++;

              if(x==12)x=0;

              LED0=!LED0;                                  

              delay_ms(1000);   

       }

}

该部分代码将显示一些固定的字符,同时显示LCD驱动IC的型号,然后不停的切换背景颜色,每1s切换一次。而LED0也会不停的闪烁,指示程序已经在运行了。其中我们用到一个sprintf的函数,该函数用法同printf,只是sprintf把打印内容输出到指定的内存区间上,sprintf的详细用法,请百度。

在编译通过之后,我们开始下载验证代码。

 

18.4 下载验证

将程序下载到战舰STM32后,可以看到DS0不停的闪烁,提示程序已经在运行了。同时可以看到TFTLCD模块的显示如图18.4.1所示:


18.4.1 TFTLCD显示效果图

我们可以看到屏幕的背景是不停切换的,同时DS0不停的闪烁,证明我们的代码被正确的执行了,达到了我们预期的目的。

 

实验13 TFTLCD显示实验.rar

75.89 KB, 下载次数: 1660

《STM32开发指南》第十八章 TFTLCD显示实验.rar

1.4 MB, 下载次数: 2357

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

221

主题

501

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1238
金钱
1238
注册时间
2013-1-9
在线时间
121 小时
发表于 2013-1-25 19:35:40 | 显示全部楼层
正在学习这篇,有两句话看了一天也没理解,请原子指导一下:
当Bank1接的是16位宽度存储器的时候:HADDR[25:1]à FSMC[24:0]。TFTLCD
使用的是 16 位数据宽度,所以 HADDR[0]并没有用到,只有 HADDR[25:1]是有效的,为什么?

当Bank1接的是8位宽度存储器的时候:HADDR[25:0]à FSMC[25:0]。为什么?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-1-25 19:52:04 | 显示全部楼层
回复【3楼】anazel:
---------------------------------
ST数据手册这么写的,具体为什么这么设计,我也不解,呵呵.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

221

主题

501

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1238
金钱
1238
注册时间
2013-1-9
在线时间
121 小时
发表于 2013-1-25 20:51:00 | 显示全部楼层
是这样啊,看来要记下这个规定啦,呵呵
回复 支持 反对

使用道具 举报

221

主题

501

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1238
金钱
1238
注册时间
2013-1-9
在线时间
121 小时
发表于 2013-1-25 21:40:41 | 显示全部楼层
在网上找到篇文章,里面有个LCD寄存器和RAM地址的计算:
选择NOR的第一个存储区,使用FSMC_A16控制LCD的RS脚,则访问LCD显示RAM的基址为0x6002 0000,访问LCD寄存器的地址为:0x6000 0000
我怎么觉得LCD寄存器地址是:0x6001 FFFE呢,发完指令后地址加1,变成0x6002 0000,不就是LCD的显示RAM地址吗
回复 支持 反对

使用道具 举报

8

主题

103

帖子

0

精华

初级会员

Rank: 2

积分
187
金钱
187
注册时间
2012-11-12
在线时间
22 小时
发表于 2013-1-25 22:08:41 | 显示全部楼层
回复【6楼】anazel:
---------------------------------
其实两种写法都是对的吧,关键是看你的CS连在哪个引脚上。原子大哥的写法,发完指令后自动加1这个好啊,方便。
没人看你努力的过程,只看最后的结果。
回复 支持 反对

使用道具 举报

221

主题

501

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1238
金钱
1238
注册时间
2013-1-9
在线时间
121 小时
发表于 2013-1-26 05:23:22 | 显示全部楼层
建议原子以后能不能补上一个利用单片机引脚模拟信号波形驱动TFT的实例呢,当然在网上有其他的教程,不过补充上会更完整,很多人用的到stm32都是不带FSMC的
回复 支持 反对

使用道具 举报

221

主题

501

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1238
金钱
1238
注册时间
2013-1-9
在线时间
121 小时
发表于 2013-1-26 05:38:20 | 显示全部楼层
回复【7楼】黄毛:
---------------------------------
谢谢,明白了,不管用什么方法,只要保证写寄存器的时候RS=0,写RAM的时候RS=1就行了
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-1-26 10:14:16 | 显示全部楼层
回复【8楼】anazel:
---------------------------------
mini板的就是啊.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

221

主题

501

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1238
金钱
1238
注册时间
2013-1-9
在线时间
121 小时
发表于 2013-1-26 11:21:00 | 显示全部楼层
是看那本《例说STM32》吗,我买的是战舰版的
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-1-26 12:28:06 | 显示全部楼层
回复【11楼】anazel:
---------------------------------
是的,也可以看STM32不完全手册.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

221

主题

501

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1238
金钱
1238
注册时间
2013-1-9
在线时间
121 小时
发表于 2013-1-26 14:51:40 | 显示全部楼层
多谢!
回复 支持 反对

使用道具 举报

3

主题

5

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2013-3-15
在线时间
3 小时
发表于 2013-3-20 20:13:27 | 显示全部楼层
回复【12楼】正点原子:
---------------------------------
请问下你用的是什么版本的库呀,有些头文件找不到
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-3-20 21:16:19 | 显示全部楼层
2.0的貌似是.
看看这个帖子:http://www.openedv.com/posts/list/10955.htm
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-3-23 16:23:40 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
#define LCD_BASE        ((u32)(0x6C000000 | 0x000007FE))

#define LCD             ((LCD_TypeDef *) LCD_BASE)


原子哥这里没有参悟啊,指点一下吧,
那么可以得到LCD->LCD_REG的地址就是0X6C00,07FE,对应A10的状态为0(即RS=0),而LCD-> LCD_RAM的地址就是0X6C00,0800(结构体地址自增),对应A10的状态为1(即RS=1)。

这句下面不理解了:
以,有了这个定义,当我们要往LCD写命令/数据的时候,可以这样写:

LCD->LCD_REG=CMD;  //写命令

LCD->LCD_RAM=DATA; //写数据

而读的时候反过来操作就可以了,如下所示:

CMD= LCD->LCD_REG;//读LCD寄存器

 DATA = LCD->LCD_RAM;//读LCD数据

为什么指令或者数据这样写。这样写就是写在D0-D15?好像我对于地址和数据有点概念不清,看寄存器手册也没找明白。
我理解思路是写入指令,D0-D15一个u16大小寄存器,这个寄存器地址为LCD_REG ,这里地址其实是没用的好比一个虚拟的,只要这个地址的第12位是0就可以了,就为了A10输出0,对么。而设置为偏移0X 7FE 是为结构体中自增地址,下一个地址可以是0x800,从而达到A10为1的效果。是么?
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-3-23 16:24:37 | 显示全部楼层
LCD->LCD_REG=CMD;  //写命令
这一句其实达到两个目的,设置A10为0,并且将指令从D0-D15写出去。
是这样理解么?楼主
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-3-23 16:37:36 | 显示全部楼层
回复【16楼】wwjdwy:
---------------------------------
这些是由FSMC自动去控制了。
比如你写:LCD->LCD_REG=CMD;  //写命令 
就是往地址0X6C00,07FE处,写入CMD这个值。
翻译到LCD那里,就是RS=0,然后写1个16位的数据,当然就是写命令了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-3-23 23:59:46 | 显示全部楼层
回复【18楼】正点原子:
---------------------------------
谢谢,往地址0X6C00,07FE处,就是说地址线A0-A15写“0X7FE,16位再右移一位”。所以这时候RS=0.
只要地址里A10为0,写入CMD,就都是OK的对吧?
这个FSMC自动控制就是一下写了地址又写数据啊
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-3-24 00:19:12 | 显示全部楼层
回复【19楼】wwjdwy:
---------------------------------
怎么会又写地址又写数据?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-3-24 00:52:41 | 显示全部楼层
回复【20楼】正点原子:
---------------------------------
说的不太对,就是地址定义,只要地址定义里的,这个地址位置,对应的A10位正确就可以了。其他十多位其实没啥关系是么
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-3-24 10:11:23 | 显示全部楼层
是的
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-3-24 10:33:08 | 显示全部楼层
回复【22楼】正点原子:
---------------------------------
哈哈谢谢,总算参悟一点了嘿嘿
回复 支持 反对

使用道具 举报

0

主题

16

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2013-1-29
在线时间
0 小时
发表于 2013-4-9 11:32:14 | 显示全部楼层
回复【22楼】正点原子:
---------------------------------
回复【23楼】wwjdwy:
---------------------------------

原子哥,ww兄,RS的硬件置位我似乎是懂了,可是关于数据的传输还是很困惑:

1. 假设我传一个(u16)data到LCD->LCD_RAM里,RS被置位,可是这个u16的值又是怎么从LCD_RAM里面传递到数据线上的呢?

     FSMC的D[15:0]在硬件上会自动提取这个LCD_RAM里面的16位数据吗?

2. LCD指令也是通过D[15:0]传输的吗?

百思不解…… T_T 请指教!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-4-9 12:24:12 | 显示全部楼层
回复【24楼】tanrui8765:
---------------------------------
这是FSMC自动控制了,看FSMC的时序图。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

16

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2013-1-29
在线时间
0 小时
发表于 2013-4-10 02:07:02 | 显示全部楼层
谢谢原子哥,还想请教一个LCD寄存器初始化的问题:

请问您是在9341的哪个部分找到LCD初始化的操作步骤的? 我对比了一下例程里面的LCD寄存初始化程序与“ILI9341_DS.pdf” 数据手册里面 ‘15.1 Reset - Register’这一节的内容,发现您的配置操作过程并不完全与他要求的一样。

所以我想请教一下是不是我找错位置了?在做产品的时候往往都会遇到不同器件的数据手册,怎么才能快速准确的学习使用呢?我觉得我在技术这方面接受和实现的速度很慢……困惑……

以下是您的初始化程序:

if(lcddev.id==0X9341) //9341初始化
{  
LCD_WR_REG(0xCF);  
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0xC1); 
LCD_WR_DATA(0X30); 
LCD_WR_REG(0xED);  
LCD_WR_DATA(0x64); 
LCD_WR_DATA(0x03); 
LCD_WR_DATA(0X12); 
LCD_WR_DATA(0X81); 
LCD_WR_REG(0xE8);  
LCD_WR_DATA(0x85); 
LCD_WR_DATA(0x10); 
LCD_WR_DATA(0x7A); 
LCD_WR_REG(0xCB);  
LCD_WR_DATA(0x39); 
LCD_WR_DATA(0x2C); 
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0x34); 
LCD_WR_DATA(0x02); 
LCD_WR_REG(0xF7);  
LCD_WR_DATA(0x20); 
LCD_WR_REG(0xEA);  
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0x00); 
LCD_WR_REG(0xC0);    //Power control 
LCD_WR_DATA(0x1B);   //VRH[5:0] 
LCD_WR_REG(0xC1);    //Power control 
LCD_WR_DATA(0x01);   //SAP[2:0];BT[3:0] 
LCD_WR_REG(0xC5);    //VCM control 
LCD_WR_DATA(0x30);   //3F
LCD_WR_DATA(0x30);   //3C
LCD_WR_REG(0xC7);    //VCM control2 
LCD_WR_DATA(0XB7); 
LCD_WR_REG(0x36);    // Memory Access Control 
LCD_WR_DATA(0x48); 
LCD_WR_REG(0x3A);   
LCD_WR_DATA(0x55); 
LCD_WR_REG(0xB1);   
LCD_WR_DATA(0x00);   
LCD_WR_DATA(0x1A); 
LCD_WR_REG(0xB6);    // Display Function Control 
LCD_WR_DATA(0x0A); 
LCD_WR_DATA(0xA2); 
LCD_WR_REG(0xF2);    // 3Gamma Function Disable 
LCD_WR_DATA(0x00); 
LCD_WR_REG(0x26);    //Gamma curve selected 
LCD_WR_DATA(0x01); 
LCD_WR_REG(0xE0);    //Set Gamma 
LCD_WR_DATA(0x0F); 
LCD_WR_DATA(0x2A); 
LCD_WR_DATA(0x28); 
LCD_WR_DATA(0x08); 
LCD_WR_DATA(0x0E); 
LCD_WR_DATA(0x08); 
LCD_WR_DATA(0x54); 
LCD_WR_DATA(0XA9); 
LCD_WR_DATA(0x43); 
LCD_WR_DATA(0x0A); 
LCD_WR_DATA(0x0F); 
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0x00);   
LCD_WR_REG(0XE1);    //Set Gamma 
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0x15); 
LCD_WR_DATA(0x17); 
LCD_WR_DATA(0x07); 
LCD_WR_DATA(0x11); 
LCD_WR_DATA(0x06); 
LCD_WR_DATA(0x2B); 
LCD_WR_DATA(0x56); 
LCD_WR_DATA(0x3C); 
LCD_WR_DATA(0x05); 
LCD_WR_DATA(0x10); 
LCD_WR_DATA(0x0F); 
LCD_WR_DATA(0x3F); 
LCD_WR_DATA(0x3F); 
LCD_WR_DATA(0x0F); 
LCD_WR_REG(0x2B); 
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x01);
LCD_WR_DATA(0x3f);
LCD_WR_REG(0x2A); 
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0xef);  
LCD_WR_REG(0x11); //Exit Sleep
delay_ms(120);
LCD_WR_REG(0x29); //display on
                }
回复 支持 反对

使用道具 举报

12

主题

432

帖子

0

精华

高级会员

Rank: 4

积分
729
金钱
729
注册时间
2012-6-21
在线时间
59 小时
发表于 2013-4-10 08:22:28 | 显示全部楼层
不错。。
回复 支持 反对

使用道具 举报

0

主题

16

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2013-1-29
在线时间
0 小时
发表于 2013-4-11 22:18:49 | 显示全部楼层
回复【25楼】正点原子:
---------------------------------
忘@你了原子哥,哈哈...


谢谢原子哥,还想请教一个LCD寄存器初始化的问题: 

请问您是在9341的哪个部分找到LCD初始化的操作步骤的? 我对比了一下例程里面的LCD寄存初始化程序与“ILI9341_DS.pdf” 数据手册里面 ‘15.1 Reset - Register’这一节的内容,发现您的配置操作过程并不完全与他要求的一样。 

所以我想请教一下是不是我找错位置了?在做产品的时候往往都会遇到不同器件的数据手册,怎么才能快速准确的学习使用呢?我觉得我在技术这方面接受和实现的速度很慢……困惑…… 

以下是您的初始化程序: 

if(lcddev.id==0X9341) //9341初始化 
{   
LCD_WR_REG(0xCF);   
LCD_WR_DATA(0x00);  
LCD_WR_DATA(0xC1);  
LCD_WR_DATA(0X30);  
LCD_WR_REG(0xED);   
LCD_WR_DATA(0x64);  
LCD_WR_DATA(0x03);  
LCD_WR_DATA(0X12);  
LCD_WR_DATA(0X81);  
LCD_WR_REG(0xE8);   
LCD_WR_DATA(0x85);  
LCD_WR_DATA(0x10);  
LCD_WR_DATA(0x7A);  
LCD_WR_REG(0xCB);   
LCD_WR_DATA(0x39);  
LCD_WR_DATA(0x2C);  
LCD_WR_DATA(0x00);  
LCD_WR_DATA(0x34);  
LCD_WR_DATA(0x02);  
LCD_WR_REG(0xF7);   
LCD_WR_DATA(0x20);  
LCD_WR_REG(0xEA);   
LCD_WR_DATA(0x00);  
LCD_WR_DATA(0x00);  
LCD_WR_REG(0xC0);    //Power control  
LCD_WR_DATA(0x1B);   //VRH[5:0]  
LCD_WR_REG(0xC1);    //Power control  
LCD_WR_DATA(0x01);   //SAP[2:0];BT[3:0]  
LCD_WR_REG(0xC5);    //VCM control  
LCD_WR_DATA(0x30);   //3F 
LCD_WR_DATA(0x30);   //3C 
LCD_WR_REG(0xC7);    //VCM control2  
LCD_WR_DATA(0XB7);  
LCD_WR_REG(0x36);    // Memory Access Control  
LCD_WR_DATA(0x48);  
LCD_WR_REG(0x3A);    
LCD_WR_DATA(0x55);  
LCD_WR_REG(0xB1);    
LCD_WR_DATA(0x00);    
LCD_WR_DATA(0x1A);  
LCD_WR_REG(0xB6);    // Display Function Control  
LCD_WR_DATA(0x0A);  
LCD_WR_DATA(0xA2);  
LCD_WR_REG(0xF2);    // 3Gamma Function Disable  
LCD_WR_DATA(0x00);  
LCD_WR_REG(0x26);    //Gamma curve selected  
LCD_WR_DATA(0x01);  
LCD_WR_REG(0xE0);    //Set Gamma  
LCD_WR_DATA(0x0F);  
LCD_WR_DATA(0x2A);  
LCD_WR_DATA(0x28);  
LCD_WR_DATA(0x08);  
LCD_WR_DATA(0x0E);  
LCD_WR_DATA(0x08);  
LCD_WR_DATA(0x54);  
LCD_WR_DATA(0XA9);  
LCD_WR_DATA(0x43);  
LCD_WR_DATA(0x0A);  
LCD_WR_DATA(0x0F);  
LCD_WR_DATA(0x00);  
LCD_WR_DATA(0x00);  
LCD_WR_DATA(0x00);  
LCD_WR_DATA(0x00);     
LCD_WR_REG(0XE1);    //Set Gamma  
LCD_WR_DATA(0x00);  
LCD_WR_DATA(0x15);  
LCD_WR_DATA(0x17);  
LCD_WR_DATA(0x07);  
LCD_WR_DATA(0x11);  
LCD_WR_DATA(0x06);  
LCD_WR_DATA(0x2B);  
LCD_WR_DATA(0x56);  
LCD_WR_DATA(0x3C);  
LCD_WR_DATA(0x05);  
LCD_WR_DATA(0x10);  
LCD_WR_DATA(0x0F);  
LCD_WR_DATA(0x3F);  
LCD_WR_DATA(0x3F);  
LCD_WR_DATA(0x0F);  
LCD_WR_REG(0x2B);  
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0x01); 
LCD_WR_DATA(0x3f); 
LCD_WR_REG(0x2A);  
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0x00); 
LCD_WR_DATA(0xef);   
LCD_WR_REG(0x11); //Exit Sleep 
delay_ms(120); 
LCD_WR_REG(0x29); //display on
                }
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-4-11 23:51:35 | 显示全部楼层
回复【28楼】tanrui8765:
---------------------------------
这个我直接没怎么看.
供应商给我什么代码,直接copy完事.
这部分初始化代码,完全没必要深究.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

16

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2013-1-29
在线时间
0 小时
发表于 2013-4-12 12:46:18 | 显示全部楼层
回复【29楼】正点原子:
---------------------------------
好的,谢谢原子哥!
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2013-1-28
在线时间
0 小时
发表于 2013-5-9 22:38:55 | 显示全部楼层
原子哥,请教个问题,我在驱动屏幕的时候发现,屏幕和灯一起隔断时间闪烁,屏幕是白屏,什么都显示不了。会是什么原因呢?谢谢
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-5-10 00:12:43 | 显示全部楼层
回复【31楼】yameths:
---------------------------------
是我们的板子么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2013-1-28
在线时间
0 小时
发表于 2013-5-10 08:53:09 | 显示全部楼层
回复【32楼】正点原子:
--------------------------------
原子哥,你好,我是自学的,买的是奋斗的板子。奋斗的资料都是库,我想先学习寄存器控制,所以学习起来比较吃力,我目前都是以你的资料为准,一步一步学习,现在学习的是TFTLCD,我先研究几天,到时不懂的再咨询您,可以吗?谢谢。当然如果对于我实在有瓶颈了,我会去你的淘宝买个板子。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-5-10 10:39:10 | 显示全部楼层
回复【33楼】yameths:
---------------------------------
我们都有例程,你看我们的例程,移植过去就可以了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-5-14 00:15:59 | 显示全部楼层
显示屏的刷新方向由0X03指令控制对吧。
我是战舰板子,请教下战舰2.8的液晶是哪个驱动器
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-5-14 00:18:32 | 显示全部楼层
晚上搞的有点头晕脑胀了
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2013-7-10 11:15:28 | 显示全部楼层
作用都不一样.无可比性.
我们的是用来设置坐标,不是用来设置窗口的.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

23

主题

292

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2013-9-17
在线时间
17 小时
发表于 2013-11-27 12:13:44 | 显示全部楼层
回复【6楼】anazel:
---------------------------------
我想请问下 寄存器地址和RAM地址 有什么关系 为什么加1 就可以实现从寄存器地址跑到RAM地址
闷鱼闷闷不乐吃焖鱼
回复 支持 反对

使用道具 举报

11

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2014-1-3
在线时间
0 小时
发表于 2014-2-16 22:17:55 | 显示全部楼层
请问下原子哥,屏上的28 29 30 31 33 34 是什么作用呢?不接可以么?
回复 支持 反对

使用道具 举报

11

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2014-1-3
在线时间
0 小时
发表于 2014-2-16 22:21:07 | 显示全部楼层
原子哥,屏上的28引脚接3.3V可以么?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2014-2-16 23:30:55 | 显示全部楼层
回复【42楼】jidian0177:
---------------------------------
可以的
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

11

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2014-1-3
在线时间
0 小时
发表于 2014-2-17 09:28:34 | 显示全部楼层
请问下原子哥,屏上的28 29 30 31 33 34 是什么作用呢?不接可以么?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2014-2-19 00:03:51 | 显示全部楼层
回复【44楼】jidian0177:
---------------------------------
你看下原理图啊。。。
28,29,30,31,33,34,不是接在XPT2046上面了么?
这IC是触摸屏控制IC啊,你不要用触摸屏的话,就可以不接。
要用的话,就得接上。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

11

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2014-1-3
在线时间
0 小时
发表于 2014-2-19 09:10:48 | 显示全部楼层
回复【45楼】正点原子:
---------------------------------
恩,看了,谢谢原子哥
回复 支持 反对

使用道具 举报

11

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2014-1-3
在线时间
0 小时
发表于 2014-3-7 20:33:06 | 显示全部楼层
回复【45楼】正点原子:
---------------------------------
原子哥,我现在用你的3.5寸屏,6804的控制器,想问下,这个可以实现横屏显示了么?
另外,那个背光灯的引脚可以接个放大,来增加屏的亮度么?额定电流可以达到多大?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2014-3-7 21:15:26 | 显示全部楼层
回复【47楼】jidian0177:
---------------------------------
可以,就是只能通过改画点的方式实现。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

11

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2014-1-3
在线时间
0 小时
发表于 2014-3-7 22:45:07 | 显示全部楼层
回复【48楼】正点原子:
---------------------------------
原子哥,能分享下 横屏的例程么?   背光的额定电流是?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
 楼主| 发表于 2014-3-8 20:32:54 | 显示全部楼层
回复【49楼】jidian0177:
---------------------------------
背光电流80ma左右。
横屏的你自己改一下就是了, LCD_Display_Dir(0);                //默认为竖屏显示
改为:
 LCD_Display_Dir(1);
就是横屏
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

11

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2014-1-3
在线时间
0 小时
发表于 2014-3-10 09:30:09 | 显示全部楼层
回复【50楼】正点原子:
---------------------------------
谢谢原子哥
回复 支持 反对

使用道具 举报

3

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2013-7-5
在线时间
6 小时
发表于 2014-3-28 22:29:27 | 显示全部楼层
回复【37楼】hyuhss:
---------------------------------
大哥,请教你,
LCD_WR_DATA(Xpos>>8);  
LCD_WR_DATA(Xpos&0XFF);
这段代码为什么要先右移8位,只取它的高8位呢?
这样怎么设置SC[15:0]与EC[15:0]?
请指教!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-2 19:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表