用户工具

站点工具


icore4t_63

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
icore4t_63 [2020/10/16 17:42]
fmj
icore4t_63 [2022/04/01 10:59] (当前版本)
sean
行 2: 行 2:
 |技术支持电话|**0379-69926675-801**||| |技术支持电话|**0379-69926675-801**|||
 |技术支持邮件|Gingko@vip.163.com||| |技术支持邮件|Gingko@vip.163.com|||
-|技术论坛|http://​www.eeschool.org||| 
 ^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^ ^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^
 |  V1.0  |  2020-10-16 ​ |  gingko ​ |  初次建立 ​ |  |  V1.0  |  2020-10-16 ​ |  gingko ​ |  初次建立 ​ | 
行 71: 行 70:
 \\ \\
 \\ \\
-===== 实验六十:LCD实验驱动4.3寸液晶屏 ​=====+===== 实验六十三:TOUCH实验——电容触摸 ​=====
  
 ==== 一、 实验目的与意义 ==== ==== 一、 实验目的与意义 ====
   - 了解STM32 LTDC结构   - 了解STM32 LTDC结构
   - 了解STM32 LTDC特征   - 了解STM32 LTDC特征
-  - 掌握LCD液晶屏的使用方法 +  - 掌握LTDC液晶屏的使用方法 
-  - 掌握STM32 HAL库中LTDC属性的配置方法+  - 掌握LTDC应用之LCD电容触摸芯片GT911的使用方法
   - 掌握KEIL MDK 集成开发环境使用方法   - 掌握KEIL MDK 集成开发环境使用方法
 ==== 二、 实验设备及平台 ==== ==== 二、 实验设备及平台 ====
   - iCore4T 双核心板   - iCore4T 双核心板
 +  - 转接板和40P的FPC连接线。
   - iCore4T 扩展底板   - iCore4T 扩展底板
   - iCore 4.3寸液晶屏底板   - iCore 4.3寸液晶屏底板
-  - JLINK(或相同功能)仿真器+  - Blaster(或相同功能)仿真器
   - Micro USB线缆   - Micro USB线缆
   - Keil MDK 开发平台   - Keil MDK 开发平台
行 90: 行 90:
 ==== 三、 实验原理 ==== ==== 三、 实验原理 ====
  
-=== LCD-TFT显示控制器(LTDC) 简介 ​=== +=== 1. LTDC基础知识 ​=== 
-LCD-TFT(液晶显示器——薄膜晶体管)显示器控制器提供并行数字 RGB(红色、绿色、 蓝色)以及水平同步、垂直同步、像素时钟和数据使能信号,这些信号直接输出到不同 LCD 和 TFT 面板的接口。STM32H750xx 的 LTDC 主要特性如下: +  * (一)LTDC关键知识点: ​ 
-  * 24 位 RGB 并行像素输出;每像素 8 位数据(RGB888) +  * 1)STM32H7的LTDC最大支持1024*768分辨率,且支持硬件双图层。实际支持的分辨率可能比1024*768要高一点,因为最 ​ 终可以支持的最大分辨率是芯片后期定标的。 
-  * 2 个带有专用 FIFO 的显示层(FIFO 深度 64x64 位) +  * 2)支持32位色,24位色,16位色和8位色。 
-  * 支持查色表 (CLUT),每层高达 256 种颜色(256x24 ​位) +  * 3)可编程窗口位置和大小,可编程行同步,场同步和数据使能信号的极性。 
-  * 可针对不同显示面板编程时序 +  * 4)查色表 (CLUT,Color look-up table),每个图层最高可记录256种24位色。 
-  * 可编程背景色 +  * 5)支持如下8种颜色格式: 
-  * 可编程 HSync、VSync ​和数据使能(DE)信号的极性 +  * **ARGB8888**  
-  * 每层有多达 ​8 种颜色格式可供选择:ARGB8888、RGB888、RGB565、ARGB1555、ARGB4444、L8(8 ​位 Luminance 或 CLUT)、AL44(4 位 alpha+4 ​位 luminance)和 AL88(8 位 alpha+8位 luminance) +  * 32位颜色格式,一个像素点占用4字节,其中低位 3 字节用于颜色分量,高位字节用于 Alpha 混合。红、绿、蓝和 Alpha通道(0x00表示完全透明,0xFF表示完全不透明)都是 ​8 位表示。 
-  * 每通道的低位采用伪随机抖动输出(红色、绿色、蓝色的抖动宽度为 2 位) +  * 普通列表项目颜色格式:AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB。 
-  * 使用 alpha 值(每像素或常数)在两层之间灵活混合 +  * **RGB888**  
-  * 色键(透明颜色) +  * 普通列表项目24位颜色格式,一个像素点占用3字节,分别用于红、绿、蓝。  
-  * 可编程窗口位置和大小 +  * 普通列表项目颜色格式:RRRRRRRRGGGGGGGGBBBBBBBB。 
-  * 支持薄膜晶体管 ​(TFT) 彩色显示器 +  * **RGB565**  
-  * AXI 主接口支持 16 个双字的突发 +  * 16位颜色格式,一个像素点占用2字节,分别用于红、绿、蓝。 ​ 
-  * 高达 ​4 个可编程中断事件 +  * 颜色格式:RRRRRGGGGGGBBBBB。 
-LTDC 控制器主要包含:信号线、图像处理单元、AXI 接口、配置和状态寄存器以及时钟部分,其框图如下所示: +  * **ARGB1555**  
-{{ :​icore4t:​iCore4T_ARM_HAL_60_1.png?​direct |}}+  * 16位颜色格式,一个像素点占用2字节,Alpha通道使用1个位表示,等于0的时候表示完全透明,等于1的时候表示完全不透明。红、绿、蓝都是用5个位表示。  
 +  * 颜色格式:ARRRRRGGGGGBBBBB。 
 +  * **ARGB4444** 
 +  * 16位颜色格式,一个像素点占用2字节,Alpha通道使用2个位表示(0x0表示完全透明,0x3表示完全不透明)。红、绿、蓝都是用4个位表示。 ​ 
 +  * 颜色格式:ARRRRRGGGGGBBBBB。 
 +  * **L8 (8-bit luminance or CLUT)**  
 +  * 8位颜色格式,实际上仅仅是8位索引值,范围0–255,​而每个索引值的具体颜色值在查色表CLUT里面存储。 
 +  * **AL44 (4-bit alpha + 4-bit luminance)** ​ 
 +  * 8位颜色格式,实际上是4位Alpha通道(0x0表示完全透明,0xF表示完全不透明)和4位的索引值,索引范围0–15,​而每个索引值的具体颜色值在查色表CLUT里面存储。 
 +  * **AL88 (8-bit alpha + 8-bit luminance)**  
 +  * 16位颜色格式,实际上是8位Alpha通道(0x00表示完全透明,0xFF表示完全不透明)和8位的索引值,索引范围0–255,​而每个索引值的具体颜色值在查色表CLUT里面存储。
  
-=== 2.LCD的DE同步模式和HV同步模式 === 
  
-通常,STM32H7都是用SDRAM作为LCD的显存,LTDC控制器会从SDRAM读取数据刷新到LCD显示屏上。刷新模式有DE同步模式和HV同步模式两种。一般大分辨率显示屏用DE同步模式,小分辨率的显示屏用HV同步模式。+  * (二)LTDC 硬件框图:  
 +{{ :​icore4t:​iCore4T_ARM_HAL_63_1.png?​direct |}} 
 +  * ltdc_aclk :为LTDC寄存器提供时钟,时钟来自AXI时钟域。  
 +  * ltdc_pclk :LTDC寄存器接口时钟。 ​  
 +  * ltdc_ker_ck :用于生成LCD_CLK(像素时钟输出)的LTDC内核时钟。  
 +  * ltdc_li_it :LTDC行中断,用于触发MDMA。 
 +  * ltdc_it :LTDC全局中断请求。  
 +  * ltdc_err_it :LTDC全局错误中断请求。  
 +  * 下面是LCD接口引脚,用于外接显示屏:  
 +  * LCD_CLK :像素时钟输出。  
 +  * LCD_HSYNC :水平同步信号。  
 +  * LCD_VSYN :垂直同步信号。  
 +  * LCD_DE :数据使能信号。  
 +  * LCD_R[7:0] :8位红色数据。  
 +  * LCD_G[7:0] :8 位绿色数据。  
 +  * LCD_B[7:0] :8位蓝色数据。
  
-  ​* DE同步模式+=== 2.电阻触摸、电容触摸相关知识=== 
 +  ​* 有了TFT裸屏后还要配套电阻触摸板或者电容触摸板才可以获取触摸信息。触摸板是贴到TFT屏上面的,然后再通过电阻触摸芯片就可以获取电阻触摸板的信息,通过电容触摸芯片采集电容触摸板的信息。目前市面上常用的电阻触摸IC是STMPE811,电容触摸IC是GT811、GT911和FT5X06。其中,电阻触摸和电容触摸两者的区别如下: 
 +  * 电阻触摸芯片STMPE811其实就是ADC,返回的是ADC数值,而电容触摸芯片GT811、GT911和FT5X06返回的是显示屏实际的坐标值。 
 +  * 使用电阻触摸芯片STMPE811需要做触摸校准,而使用电容触摸芯片GT811、GT911和FT5X06是自动校准的,无需手动校准。
  
-DE模式需要LCD_DE和LCD_CLK信号来控制刷新。比如一个800x480分辨率的裸屏,在DE有效信号的时候(高电平或低电平),就有800个LCD_CLK输出时钟来确认行中800个点。每个时钟有效的时候,从显存读取一次RGB数据。因为存在回扫信号,所以DE是个方波。一个周期的LCD_DE信号,裸屏就扫描一行。扫描480行后,又从第一行扫描开始。这个规律由裸屏的驱动IC所决定的。+=== 3.电容触摸芯片GT911介绍=== 
 +  * 在本实验中,选用电容触摸芯片GT911来实现电容触摸功能。 
 +  * 电容触摸相比电阻触摸简单,因为电容触摸不需要做触摸校准,而且用的是触摸板和触摸芯片一体的,也不需要做寄存器初始化配置,上电后直接读取参数即可。 
 +  * GT911、GT928、GT9147都属于GT9系列非单层多点触控芯片,他们支持的触控点数不同(GT928支持10个点、GT911支持5个点)、驱动和感应通道也可能不同。可是他们的寄存器和IIC通讯时序是相同的,也就是说驱动程序是兼容的。 
 +  * GT911是专为7”~8”设计的新一代5点电容触控方案,拥有26个驱动通道和14个感应通道,以满足更高的touch精度要求。GT911可同时识别5个触摸点位的实时准确位置,移动轨迹及触摸面积。并可根据主控需要,读取相应点数的触摸信息。 
 +  * 与主机的接口共有6PIN,分别为:VDD、GND、SCL、SDA、INT、RESET。 
 +    * INT、RESET不需要接上下拉电阻,可与主机直连。 
 +    * SCL、SDA需要接上拉电阻4.7K,毕竟400KHz的通信频率,没有上拉可能导致SCL、SDA边沿不够陡峭。 
 +    * RST是复位引脚,拉低100us以上,即可复位。正常工作时,应该保持拉高。 
 +    * INT是GT9xx的触摸信号输出引脚,在正常工作时,主机端要设置为悬浮输入,即不上下拉(GT9xx的驱动能力有限,如果外部上下拉,GT9xx可能驱动不了)。当有触摸发生时,INT引脚会输出上升沿或下降沿(内部寄存器可以配置),主机端可以一直读取INT脚的电平信号,也可以用端口外部中断检测。
  
-  * HV同步模式+=== 4.电容触摸芯片GT911的I2C通讯===
  
-HV模式需要LCD_CLK时钟信号,行同步信号LCD_HSYNC和场同步信号LCD_VSYNC来控制刷新。比如一个480x272分辨率的裸屏,有一个行同步信号LCD_HSYNC产生时(高电平或者低电平脉冲),就有480个LCD_CLK输出时钟来确认行中480个点。每个时钟有效的时候,从显存读取一次RGB数据。再来一个行同步信号LCD_HSYNC产生时(高电平或者低电平脉冲),切换到下一行,继续行同步和时钟输出,扫描272行后,发送一个场同步信号LCD_VSYNC,又重新从第一行扫描开始。+  * GT911提供标准的I2C通讯接口,由SCL和SDA与主CPU进行通讯。在系统中GT911始终作为从设备,所有通讯都是由主CPU发起,建议通讯速度为400Kbps或以下。其支持的I2C硬件电路支持时序如下: 
 +{{ :​icore4t:​iCore4T_ARM_HAL_63_2.png?​direct |}} 
 +  * GT911的I2C从设备地址有两组,分别为0xBA/​0xBB和0x28/​0x29。主控在上电初始化时控制Reset和INT口状态进行设定,设定方法及时序图如下: 
 +  * 上电时序图: 
 +{{ :​icore4t:​iCore4T_ARM_HAL_63_3.png?​direct |}} 
 +{{ :​icore4t:​iCore4T_ARM_HAL_63_4.png?​direct |}}
  
-=== 3.LTDC的时序配置 === +  ​* **1)数据传输(以设备地址为0xBA/0xBB为例)**
-{{ :​icore4t:​iCore4T_ARM_HAL_60_2.png?​direct |}} +
-LTDC的时序控制就是下面几个参数的设置,这几个参数都可以通过寄存器进行配置。 +
-  +
-  ​* HSYNC width水平同步宽度设置,以LCD_CLK的像素时钟输出为单位。 +
-  ​* HBP(horizontal back porch period)水平后沿周期设置,以LCD_CLK的像素时钟输出为单位。 +
-  ​* Active width有效宽度设置,以LCD_CLK的像素时钟输出为单位。以480*272分辨率为例,Active width = 480。 +
-  * HFP(horizontal front porch period)水平前沿周期设置,以LCD_CLK的像素时钟输出为单位。 +
-  * VSYNC width垂直同步宽度设置,以LCD_CLK的像素时钟输出为单位。 +
-  ​* VBP(vertical back porch period)垂直后沿周期设置,以LCD_CLK的像素时钟输出为单位。 +
-  ​* Active height有效高度设置,以LCD_CLK的像素时钟输出为单位。以480*272分辨率为例,Active height = 272。 +
-  * VFP(vertical front porch period)垂直前沿周期设置,以LCD_CLK的像素时钟输出为单位。+
  
-=== 4.窗口 ===+  * 通讯总是由主 CPU 发起,有效的起始信号为:在 SCL 保持为“1”时,SDA 上发生由“1”到“0”的跳变。地址信息或数据流均在起始信号之后传输。 
 +  * 所有连接在I2C总线上的从设备,都要检测总线上起始信号之后所发送的8位地址信息, 
 +  * 并做出正确反应。在收到与自己相匹配的地址信息时,GT911在第9个时钟周期,将SDA改为输出口,并置“0”,作为应答信号。若收到不与自己匹配的地址信息,即非0XBA或0XBB,GT911将保持闲置状态。 
 +  * SDA口上的数据按9个时钟周期串行发送9位数据:8位有效数据+1位接收方发送的应答信号ACK或非应答信号NACK。数据传输在SCL为“1”时有效。 
 +  * 当通讯完成时,由主CPU发送停止信号。停止信号是当SCL为“1”时,SDA状态由“0”到“1”的跳变。
  
-可为每个层定位和调整大小,各个层必须位于有效显示区域内。 +  * **2)对GT911写操作(以设备地址为0xBA/​0xBB为例)** 
-窗口位置和大小通过左上和右下的 X/Y 位置以及包含同步、后沿大小和有效数据区域的内部时序发生器配置。 +{{ :​icore4t:​iCore4T_ARM_HAL_63_5.png?​direct |}} 
-可编程层位置和大小定义了一行中的第一个/​最后一个可见像素和窗口中的第一个/​最后一个可见行。它允许显示完整的图像帧,也允许只显示图像帧的一部分。 +  * 上图为主CPU对GT911进行的写操作流程图。首先主CPU产生一个起始信号,然后发送地址信息及读写位信息“0”表示写操作:​0XBA。在收到应答后,主CPU发送寄存器的16位地址,随后是8位要写入到寄存器的数据内容GT911寄存器的地址指针会在写操作后自动加1,所以当主CPU需要对连续地址的寄存器进行写操作时,可以在一次写操作中连续写入。写操作完成,主CPU发送停止信号结束当前写操作。
-  * 层中的第一个和最后一个可见像素通过配置 LTDC_LxWHPCR ​寄存器中WHSTPOS[11:​0] 和WHSPPOS[11:​0] ​进行设置。 +
-  * 层中的第一个和最后一个可见行通过配置 LTDC_LxWVPCR 寄存器中的 WVSTPOS[10:​0] 和 WVSPPOS[10:​0] 进行设置。 +
-{{ :​icore4t:​iCore4T_ARM_HAL_60_3.png?​direct |}}+
  
-=== 5.LTDC层混合 ===+  * **3)对GT911读操作(以设备地址为0xBA/​0xBB为例)** 
 +{{ :​icore4t:​iCore4T_ARM_HAL_63_6.png?direct |}} 
 +  * 上图为主CPU对GT911进行的读操作流程图。首先主CPU产生一个起始信号,然后发送设备地址信息及读写位信息“0”表示写操作:0XBA。在收到应答后,主CPU发送首寄存器的16位地址信息,设置要读取的寄存器地址。在收到应答后,主CPU重新发送一次起始信号,发送读操作:0XBB。收到应答后,主CPU开始读取数据。 
 +  * GT911同样支持连续的读操作,默认为连续读取数据。主CPU在每收到一个Byte数据后需发送一个应答信号表示成功接收。在接收到所需的最后一个Byte数据后,主CPU发送“非应答信号NACK”,然后再发送停止信号结束通讯。
  
-LTDC除了图层1和图层2两个硬件图层以外,还有一个背景层。由于背景层的刷新不需要显存空间,所以可以用这个图层验证LTDC时序配置是否有问题。 +===5.电容触摸芯片GT911功能描述=== 
-{{ :icore4t:iCore4T_ARM_HAL_60_4.png?direct |}}+  * (一)工作模式 
 +{{ :​icore4t:​iCore4T_ARM_HAL_63_7.png?​direct |}} 
 +  * **a)Normal Mode** 
 +  * GT911在Normal Mode时,最快的坐标刷新周期为7ms-10ms间(依赖于配置信息的设定,配置信息可控周期步进长度为1ms)。 
 +  * Normal mode状态下,一段时间无触摸事件发生,GT911将自动转入Green mode,以降低功耗。GT911无触摸自动进入Green mode的时间可通过配置信息设置,范围为0~15s,步进为1s。 
 +  * **b)Green Mode**  
 +  * 在Green mode下,GT911扫描周期约为40ms,若检测到有触摸动作发生,自动进入Normal mode。 
 +  * **c)Sleep Mode**  
 +  * 主CPU通过I2C命令,使GT911进入Sleep mode(需要先将INT脚输出低电平)。当需要GT911退出Sleep mode时,主机输出一个高电平到INT脚(主机打高INT脚2~5ms),唤醒后GT911将进入Normal mode。 
 +{{ :icore4t:iCore4T_ARM_HAL_63_8.png?direct |}}
  
-背景层仅支持单色设置,固定颜色格式RGB888(LTDC_HandleTypeDef hltdc)我们这里将背景设置为白色: +  * (二)中断触发方式 
-hltdc.Init.Backcolor.Blue = 255 +  * 当有触摸时,GT911 每个扫描周期均会通过 INT 脚发出脉冲信号,通知主 CPU 读取坐标信息。主CPU可以通过相关的寄存器位“INT”来设置触发方式。设为“0”表示上升沿触发,即在有用户操作时,GT911会在INT口输出上升沿跳变,通知 CPU;设为“1”表示下降沿触发,即在有用户操作时,GT911会在INT口输出下降沿跳变。
-hltdc.Init.Backcolor.Green = 255 +
-hltdc.Init.Backcolor.Red = 255+
  
-对于图层1和图层2来说,支持如下8种颜色格式: 
- 
-  - ARGB8888 
-  - RGB888 
-  - RGB565 
-  - ARGB1555 
-  - ARGB4444 
-  - L8(8 位 Luminance 或 CLUT) 
-  - AL44(4 位 alpha + 4 位 luminance) 
-  - AL88(8 位 alpha + 8 位 luminance) 
- 
-实现Alpha混合的关键是要有一个变量可以设置各种透明度。对此,STM32H7准备了两个Alpha供使用: 
-  * 一个是常数Alpha(0x00表示完全透明,0xFF表示完全不透明),所有颜色格式都可以使用。 
-  * 另一个是像素Alpha,也就是ARGB8888,ARGB1555,ARGB4444等颜色格式的Alpha通道数值,也就是我们为图层每个位置绘制的实际颜色值。 
- 
-STM32H7的参考手册给出了具体的混合公式: 
-BC  =  BF1  x  C  +  BF2  x  Cs 
-混合后的颜色= 混合系数1 x 当前层颜色 + 混合系数2 x 底层混合后的颜色 
  
 ==== 四、 实验程序 ==== ==== 四、 实验程序 ====
行 178: 行 201:
 int main(void) int main(void)
 { {
-        int i; +FATFS fatfs; 
- HAL_Init();​ +HAL_Init();​ 
- /* Configure the system clock */ +SystemClock_Config();​ 
- SystemClock_Config();​ +    i2c.initialize();​ 
- /* USER CODE BEGIN SysInit */ +    axp152.initialize();​ 
- i2c.initialize(); ​      //​I2C初始化 +    axp152.set_dcdc1(3500);//​[ARM & FPGA BK1/2/6 &​OTHER] 
- axp152.initialize(); ​  //​电源芯片配置 +    axp152.set_dcdc2(1200);//​[FPGA INT & PLL D] 
- axp152.set_dcdc1(3500);//​[ARM & FPGA BK1/2/6 &​OTHER] +    axp152.set_aldo1(2500);//​[FPGA PLL A] 
- axp152.set_dcdc2(1200);//​[FPGA INT & PLL D] +    axp152.set_dcdc4(3300);//​[POWER_OUTPUT] 
- axp152.set_aldo1(2500);//​[FPGA PLL A] +    axp152.set_dcdc3(3300);//​[FPGA BK4][Adjustable] 
- axp152.set_dcdc4(3300);//​[POWER_OUTPUT] +    axp152.set_aldo2(3300);//​[FPGA BK3][Adjustable] 
- axp152.set_dcdc3(3300);//​[FPGA BK4][Adjustable] +    axp152.set_dldo1(3300);//​[FPGA BK7][Adjustable] 
- axp152.set_aldo2(3300);//​[FPGA BK3][Adjustable] +    axp152.set_dldo2(3300);//​[FPGA BK5][Adjustable] 
- axp152.set_dldo1(3300);//​[FPGA BK7][Adjustable] +     MX_GPIO_Init(); 
- axp152.set_dldo2(3300);//​[FPGA BK5][Adjustable] +     MX_CRC_Init();​ 
- HAL_Delay(500); +     MX_LTDC_Init(); 
- /* USER CODE END SysInit */ +     MX_TIM12_Init(); 
- /* Initialize all configured peripherals */ +     ​MX_SDMMC1_SD_Init(); 
- MX_GPIO_Init();    //​GPIO初始化 +     MX_FATFS_Init(); 
- MX_FMC_Init();     //​FMC初始化 +     MX_FMC_Init();
- MX_LTDC_Init();    //​LTDC初始化 +
- MX_TIM12_Init();   //​TIM12初始化 +
- BSP_SDRAM_Init();  //​SDRAM初始化+
  
- HAL_TIM_PWM_Start(&​htim12,​TIM_CHANNEL_1); ​ //​定时器使能,通道1+BSP_SDRAM_Init();​ 
 + lcd.initialize();​ 
 + 
 + HAL_TIM_PWM_Start(&​htim12,​TIM_CHANNEL_1);​
  LED_ON;  LED_ON;
-  + GUI_Init(); 
- //​帧缓冲区地址映射二维数组 + GUI_SetBkColor(GUI_BLACK); 
- for(i = 0;i < LCD_HEIGHT;​i ++)address_sdram[i] = LCD_SDRAM_ADDRESS + (i * LCD_WIDTH) * 2; + GUI_Clear();
-  +
- demo();  //​运行弹球demo+
  LCD_ON;  LCD_ON;
-        while (1) + 
-        { } + frame.process();              //​界面处理 
-}+
 </​code>​ </​code>​
-=== 2.弹球demo函数 ===+===2.LTDC参数初始化结构体LTDC_InitTypeDef ​=== 
 +  * 此结构体用于配置LTDC的基本参数,具体定义如下: 
 <code c> <code c>
-void demo(void){ +typedef struct 
- int bg = WHITE; ​  //​背景色 +{ 
- int colo[7] = {RED,​BLUE,​YELLOW,​GREEN,​0x7BEF,​0x0000,​0x03E0};//​颜色列表 +uint32_t ​           HSPolarity;               ​ 
- int x=35,​y=35,​xs=1,​ys=2;  //​圆心起始坐标,速度的xy分量 +uint32_t ​           VSPolarity;               ​ 
- int oldx,​oldy,​co=0,​i,​j; +uint32_t ​           DEPolarity;                 
- int r=30;           //圆半径 +uint32_t ​           PCPolarity;                 
- clear_screen(bg); +uint32_t ​           HorizontalSync;           
- draw_circle(x,​ y, r, RED, 1); +uint32_tVerticalSync;             ​ 
-   +uint32_t ​           AccumulatedHBP;           ​ 
- while(1){ +uint32_t ​           AccumulatedVBP;           ​ 
- oldx = x; +uint32_t ​           AccumulatedActiveW;       ​ 
- oldy = y; +uint32_t ​           AccumulatedActiveH;         
-         x = x + xs; +uint32_t ​           TotalWidth;                 
- y = y + ys; +uint32_t ​           TotalHeigh;               ​ 
- if((x+r)>​=480 || (x-r)<​=0){ +LTDC_ColorTypeDef ​  ​Backcolor;               ​ 
-         xs=-1*xs;  +} LTDC_InitTypeDef;
-         x = x + 2*xs; +
-         co++; +
-         if(co==7)co=0;​ +
-                } +
- if((y+r)>​=272 || (y-r)<​=0){ +
-         ys=-1*ys; +
-         y = y + 2*ys; +
-         co++; +
-         if(co==7)co=0;​ +
-                ​} +
- draw_circle(x,​ y, r, colo[co], 1);  //​画圆 +
- for(j = oldx-r-2;j < oldx+r+2;j ++){ +
- for(i = oldy-r-2;i < oldy+r+2;i ++){ +
- if(j<​1 || j>479 || i<1 || i>​271)continue;​ +
- if( (int)(x-j)*(x-j) + (int)(y-i)*(y-i) > (int)r*r ​ ){ +
- *(volatile unsigned short int *) (address_sdram[i] + (j << 1)) = bg; +
- }}} +
- HAL_Delay(6); ​ //延时 +
- } +
-}+
  
 </​code>​ </​code>​
  
-=== 3.LTDC驱动配置 ===+ 
 +  * uint32_t HSPolarity 
 +此参数用于设置水平同步信号极性,具体支持的参数如下: 
 +#define LTDC_HSPOLARITY_AL (0x00000000U) 水平同步极性低电平有效 
 +#define LTDC_HSPOLARITY_AH LTDC_GCR_HSPOL 水平同步极性高电平有效 
 +  * uint32_t VSPolarity 
 +此参数用于设置垂直同步信号极性,具体支持的参数如下 
 +#define LTDC_VSPOLARITY_AL (0x00000000U) /* 垂直同步极性低电平有效 
 +#define LTDC_VSPOLARITY_AH LTDC_GCR_VSPOL /* 垂直同步极性高电平有效 
 +  * uint32_t DEPolarity 
 +此参数用于设置数据使能极性,具体支持的参数如下: 
 +#define LTDC_DEPOLARITY_AL (0x00000000U) /* 数据使能极性低电平有效 
 +#define LTDC_DEPOLARITY_AH LTDC_GCR_DEPOL /* 数据使能极性高电平有效 
 +  * uint32_t PCPolarity 
 +此参数用于设置像素时钟极性,具体支持的参数如下: 
 +#define LTDC_PCPOLARITY_IPC (0x00000000U) 像素时钟极性低电平有效 
 +#define LTDC_PCPOLARITY_IIPC LTDC_GCR_PCPOL 像素时钟极性高电平有效 
 +  * uint32_t HorizontalSync 
 +此参数用于设置水平同步宽度,​范围 0 x 000 0xFFF 单位像素时钟个数 。 
 +  * uint32_t VerticalSync 
 +此参数用于设置垂直同步宽度,​范围 0 x 000 0x 7 FF 单位像素时钟个数。 
 +  * uint32_t AccumulatedHBP 
 +此参数用于设置 HSYNC水平同步宽度+ HBP水平后沿之和,范围HSYNC水平同步宽度到0 xFFF,​单位像素时钟个数。 
 +  * uint32_t ​  ​AccumulatedVBP 
 +此参数用于设置VSYNC垂直同步宽度+ VBP垂直后沿之和,范围VSYNC垂直同步宽度到0x7FF,单位像素时钟个数。 
 +  * uint32_t ​  ​AccumulatedActiveW 
 +此参数用于设置HSYNC水平同步宽度+ HBP水平后沿+ 有效宽度之和,范围AccumulatedHBP到0xFFF,单位像素时钟个数。 
 +  * uint32_t ​  ​AccumulatedActiveH 
 +此参数用于设置VSYNC垂直同步宽度+ VBP垂直后沿+ 有效高度之和,范围AccumulatedVBP到0x7FF,单位像素时钟个数。 
 +  * uint32_t ​  ​TotalWidth 
 +此参数用于设置HSYNC水平同步宽度+ HBP水平后沿+ 有效宽度+ HFP水平前沿之和,范围AccumulatedActiveW到0xFFF,单位像素时钟个数。 
 +  * uint32_t ​  ​TotalHeigh 
 +此参数用于设置VSYNC垂直同步宽度+ VBP垂直后沿+ 有效高度+VFP垂直前沿之和,范围AccumulatedActiveH到0x7FF,单位像素时钟个数。 
 +  * LTDC_ColorTypeDef ​  ​Backcolor 
 +此参数用于设置背景层颜色,结构体LTDC_ColorTypeDef的定义如下: 
 <code c> <code c>
-void MX_LTDC_Init(void)+typedef struct
 { {
- LTDC_LayerCfgTypeDef pLayerCfg = {0}; +uint8_t Blue;                   ​ 
- LTDC_LayerCfgTypeDef pLayerCfg1 = {0}; +uint8_t Green;                   
- hltdc.Instance = LTDC; +uint8_t Red;                     ​ 
- hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL; //​水平同步极性 +uint8_t Reserved;                 
- hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL; //​垂直同步极性 +} LTDC_ColorTypeDef; 
- hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;​ //​数据使能极性 + 
- hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC; ​//​像素时钟极性 +</code> 
- hltdc.Init.HorizontalSync = 0;       //​水平同步宽度 +  * Bule用于设置蓝色值,范围0x00到0xFF。 
- hltdc.Init.VerticalSync = 0;         //​垂直同步宽度 +  * Green用于设置绿色值,范围0x00到0xFF。 
- hltdc.Init.AccumulatedHBP = 20;     //​水平同步后沿宽度 +  * Red用于设置红色值,范围0x00到0xFF。 
- hltdc.Init.AccumulatedVBP = 9;       //​垂直同步后沿高度 + 
- hltdc.Init.AccumulatedActiveW ​= 500;//​有效宽度 +=== 3.进行GUI界面处理 ​=== 
- hltdc.Init.AccumulatedActiveH ​= 281;//​有效高度 +<code c> 
- hltdc.Init.TotalWidth ​= 524;          //​总宽度 +static void frame_process(void) 
- hltdc.Init.TotalHeigh ​= 287;          //​总高度 +{ 
- hltdc.Init.Backcolor.Blue ​= 255;     //​背景RGB数值,白色 +gt911.initialize(); 
- hltdc.Init.Backcolor.Green ​= 255; +GUI_CURSOR_Show(); 
- hltdc.Init.Backcolor.Red = 255; +WM_SetCreateFlags(WM_CF_MEMDEV); 
- if (HAL_LTDC_Init(&​hltdc) != HAL_OK) +  ​GUI_CreateDialogBox(_aDialogCreate,​GUI_COUNTOF(_aDialogCreate),​ _cbDialog, WM_HBKWIN, ​0, 0); 
- {Error_Handler();} +while(1){ 
- pLayerCfg.WindowX0 = 0;    //​屏幕像素宽 + if(systick._20ms_flag ​== 1){ 
- pLayerCfg.WindowX1 = 480; + systick._20ms_flag ​= 0; 
-  ​ pLayerCfg.WindowY0 = 0;    //​屏幕像素高 + GUI_TOUCH_Exec(); 
- pLayerCfg.WindowY1 = 272; + GUI_Exec(); 
- pLayerCfg.PixelFormat ​= LTDC_PIXEL_FORMAT_RGB565;​ //​屏幕格式 + } 
-  pLayerCfg.Alpha ​= 0xff;    //​透明度,不透明 + if(touch_flag ​== 1){ 
- pLayerCfg.Alpha0 ​= 0;      //​默认透明度 + touch_flag ​= 0; 
- pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA; + EDIT_SetValue(h_edit_0,​gt911.x[0]); 
- pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA; + EDIT_SetValue(h_edit_1,​gt911.y[0]); 
- pLayerCfg.FBStartAdress = 0xC0000000; ​ //​帧缓冲区起始地址 + GUI_Exec(); 
- pLayerCfg.ImageWidth ​= 480;  //​图层宽 + } 
- pLayerCfg.ImageHeight ​= 272;  //图层高 + GUI_Exec(); 
- pLayerCfg.Backcolor.Blue ​= 255;    //​图层背景RGB数值,白色 +}
- pLayerCfg.Backcolor.Green = 255; +
- pLayerCfg.Backcolor.Red = 255; +
- if (HAL_LTDC_ConfigLayer(&​hltdc,​ &​pLayerCfg,​ 0) != HAL_OK) +
- { Error_Handler();}+
 } }
  
 </​code>​ </​code>​
-=== 4.画点函数 ===+===4.gui_frame函数实现GUI图形界面坐标设置 ​===
 <code c> <code c>
-int set_pixel(int x, int y, int color) { +static ​int gui_frame(int startx,int starty,int endx,int endy) 
- if(x<0 || x>480 || y<0 || y>272)return 0; +{ 
- *(volatile unsigned short int *) (address_sdram[y] ​+ (x << ​1)) = color; + GUI_SetColor(GUI_GRAY); 
- return ​1;+ GUI_DrawRect(startx,​starty,​endx,​endy); 
 + GUI_SetColor(GUI_WHITE);​ 
 + GUI_DrawHLine(starty ​+ 1,startx + 1,endx - 1); 
 + GUI_DrawHLine(endy + 1,​startx,​endx + 1); 
 + GUI_DrawVLine(startx + 1,starty + 1,endy - 1); 
 + GUI_DrawVLine(endx + 1,​starty,​endy + 1); 
 +  
 + return 0;
 } }
 +
 </​code>​ </​code>​
-=== 5.清屏函数 ===+=== 5.GT911写数据函数 ===
 <code c> <code c>
-void clear_screen(int color)+unsigned char GT911_WR_Reg(unsigned short int reg,​unsigned char *buf,​unsigned char len)
 { {
- int i,j; + unsigned char i; 
- for(j = 0;j < LCD_WIDTH;j ++){ + unsigned char ret=0; 
- for(i = 0;i < LCD_HEIGHT;i ++){ +  
- *(volatile unsigned short int *) (address_sdram[i] + (j << 1)) = color; + i2c_touch.IIC_Start(); 
-}}}+  i2c_touch.IIC_Send_Byte(GT_CMD_WR);​ 
 + i2c_touch.IIC_Wait_Ack();​  
 + i2c_touch.IIC_Send_Byte(reg>>​8);​ 
 + i2c_touch.IIC_Wait_Ack();​ 
 + i2c_touch.IIC_Send_Byte(reg&​0XFF);​ 
 + i2c_touch.IIC_Wait_Ack(); ​  
 + for(i=0;​i<​len;i++) 
 + {     
 + i2c_touch.IIC_Send_Byte(buf[i]); 
 + ret=i2c_touch.IIC_Wait_Ack(); 
 + if(ret)break;   
 + } 
 +  i2c_touch.IIC_Stop(); ​    
 +  
 + return ret;  
 +} 
 </​code>​ </​code>​
-=== 6.画圆函数 ===+=== 6.GT911读数据函数 ===
 <code c> <code c>
-int draw_circle(int x, int y, int r, int color, int fill) { +void GT911_RD_Reg(unsigned short int reg,unsigned char *buf,unsigned char len) 
- int i,j; +{ 
- if(x<0 || x>480 || y<0 || y>272)return 0; + unsigned char i;  
- for(j = x-r;j < x+r;j ++){ +  
- for(i = y-r;i < y+r;i ++){ + i2c_touch.IIC_Start();  
- if(fill == 1){ + ​ i2c_touch.IIC_Send_Byte(GT_CMD_WR);​ 
- if( (int)(x-j)*(x-j) + (int)(y-i)*(y-i) <= (int)r*r  ​){ + i2c_touch.IIC_Wait_Ack();​ 
- *(volatile ​unsigned short int *) (address_sdram[i] + (j << ​1)) = color; + ​ i2c_touch.IIC_Send_Byte(reg>>8); 
- }+ i2c_touch.IIC_Wait_Ack();​  ​     
 + ​ i2c_touch.IIC_Send_Byte(reg&​0XFF);​ 
 + i2c_touch.IIC_Wait_Ack();​  
 +  
 + i2c_touch.IIC_Start();​  ​     
 + i2c_touch.IIC_Send_Byte(GT_CMD_RD);​ 
 + i2c_touch.IIC_Wait_Ack();​ 
 +  
 + for(i=0;i<len;i++) 
 + {     
 +    ​buf[i]=i2c_touch.IIC_Read_Byte(i==(len-1)?0:1); 
 + }  
 +  
 +  i2c_touch.IIC_Stop();​ //​产生一个停止条件 
 +  
 + 
 +</code> 
 + 
 +=== 7.scan函数:实现读取GT911触摸数据功能。 === 
 +  * 芯片GT911返回的就是实际的坐标值,比如显示屏的分辨率是480*272,那么返回的就是在这个分辨率范围内的实际坐标值。 
 +<code c> 
 +int scan(unsigned char mode) 
 +{ 
 + unsigned char buf[4]; 
 + unsigned char i=0; 
 + unsigned char temp; 
 + GT911_RD_Reg(GT_GSTID_REG,&​mode,​1);//​读取触摸点的状态  
 + if(mode&​0X80&&​((mode&​0XF)<​6)) 
 + { 
 + temp=0; 
 + GT911_WR_Reg(GT_GSTID_REG,&​temp,​1);//​清标志  
 + } 
 + if((mode&​0XF)&&((mode&​0XF)<6)) 
 + { 
 + temp=0XFF<<​(mode&​0XF);//​将点的个数转换为1的位数,匹配tp_dev.sta定义 
 + gt911.sta=(~temp); 
 + for(i=0;​i<​5;​i++) 
 + { 
 + if(gt911.sta&​(1<<​i)) 
 + { 
 + GT911_RD_Reg(GT911_TPX_TBL[i],​buf,​4);//​读取XY坐标值 
 + gt911.x[i]=(((unsigned short int)buf[1]<<​8)+buf[0]); 
 + gt911.y[i]=(((unsigned short int)buf[3]<<8)+buf[2]);
  }  }
- else{ + }  
- if( (x-i)*(x-i) + (y-j)*(y-j) >= (r-2)*(r) && (x-i)*(x-i) + (y-j)*(y-j) <= (r+1)*(r) ){ + }else{//​设置XY坐标默认值 
- *(volatile unsigned short int *) (address_sdram[i] + (j << 1)) = color; + gt911.x[0]=480; 
- } + gt911.y[0]=272;​ 
- } + gt911.x[1]=480; 
- }+ gt911.y[1]=272; 
 + gt911.x[2]=480; 
 + gt911.y[2]=272; 
 + gt911.x[3]=480; 
 + gt911.y[3]=272;​ 
 + gt911.x[4]=480;​ 
 + gt911.y[4]=272;​
  }  }
- return ​1;+ return ​0;
 } }
 +
 </​code>​ </​code>​
- 
 ==== 五、 实验步骤 ==== ==== 五、 实验步骤 ====
   - 把仿真器与iCore4T的SWD调试口相连(直接相连或者通过转接器相连);   - 把仿真器与iCore4T的SWD调试口相连(直接相连或者通过转接器相连);
行 349: 行 455:
 ==== 六、 实验现象 ==== ==== 六、 实验现象 ====
  
-有一个小球在屏幕中来回弹,触碰到边界时小球颜色改变。+触摸iCore4T(4.3寸TFT_LCD)液晶屏即显示当前触摸位置的坐标值。
  
icore4t_63.1602841375.txt.gz · 最后更改: 2020/10/16 17:42 由 fmj