您当前的位置: 首页 >  fpga开发

正点原子

暂无认证

  • 0浏览

    0关注

    382博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【正点原子FPGA连载】 第二十章 LCD触摸屏实验 -摘自【正点原子】领航者ZYNQ之FPGA开发指南_V2.0

正点原子 发布时间:2022-01-06 12:30:06 ,浏览量:0

1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-301505-1-1.html 4)对正点原子FPGA感兴趣的同学可以加群讨论:994244016 5)关注正点原子公众号,获取最新资料更新 在这里插入图片描述

第二十章 LCD触摸屏实验

触摸屏(Touch Panel)又称为触控屏、触控面板,是一种可接收触头等输入讯号的感应式液晶显示装置,当接触屏幕时,屏幕上的触觉反馈系统可根据预先编程的程式驱动各种连结装置,可用以取代机械式的按钮面板,并借由液晶显示画面制造出生动的影音效果。本节LCD触摸实验将实现手指触碰LCD屏幕,对应触摸点的坐标就会显示在LCD屏幕上的功能。 本章包括以下几个部分: 20.1 简介 20.2 实验任务 20.3 硬件设计 20.4 程序设计 20.5 下载验证 20.1 简介 目前最常用的触摸屏有两种:电阻式触摸屏与电容式触摸屏。下面,我们来分别介绍这两种或触摸屏。 1)电阻式触摸屏 在Iphone面世之前,几乎清一色的都是使用电阻式触摸屏,电阻式触摸屏利用压力感应进行触点检测控制,需要直接应力接触,通过检测电阻来定位触摸位置。 正点原子2.4/2.8/3.5寸LCD模块自带的触摸屏都属于电阻式触摸屏,下面简单介绍下电阻式触摸屏的原理。 电阻触摸屏的主要部分是一块与显示器表面非常配合的电阻薄膜屏,这是一种多层的复合薄膜,它以一层玻璃或硬塑料平板作为基层,表面涂有一层透明氧化金属(透明的导电电阻)导电层,上面再盖有一层外表面硬化处理、光滑防擦的塑料层、它的内表面也涂有一层涂层、在它们之间有许多细小的(小于1/1000英寸)的透明隔离点把两层导电层隔开绝缘。当手指触摸屏幕时,两层导电层在触摸点位置就有了接触,电阻发生变化,在X和Y两个方向上产生信号,然后送达触摸屏控制器。控制器侦测到这一接触并计算出(X,Y)的位置,再根据获得的位置模拟鼠标的方式运作。这就是电阻技术触摸屏的最基本的原理。 电阻触摸屏的优点:精度高、价格便宜、抗干扰能力强、稳定性好。 电阻触摸屏的缺点:容易被划伤、透光性不太好、不支持多点触摸。 从以上介绍可知,触摸屏都需要一个AD转换器,一般来说是需要一个控制器的。正点原子LCD模块选择的是四线电阻式触摸屏,这种触摸屏的控制芯片有很多,包括:ADS7843、ADS7846、TSC2046、XPT2046和AK4182等。这几款芯片的驱动基本上是一样的,也就是你只要写出了ADS7843的驱动,这个驱动对其他几个芯片也是有效的,而且封装也有一样的,完全PIN TO PIN兼容。所以在替换起来,很方便。 正点原子LCD模块自带的触摸屏控制芯片为XPT2046。XPT2046是一款4导线制触摸屏控制器,内含12位分辨率125KHz转换速率逐步逼近型A/D转换器。XPT2046支持从1.5V到5.25V的低电压I/O接口。XPT2046能通过执行两次A/D转换查出被按的屏幕位置,除此之外,还可以测量加在触摸屏上的压力。内部自带2.5V参考电压可以作为辅助输入、温度测量和电池监测模式之用,电池监测的电压范围可以从0V到6V。XPT2046片内集成有一个温度传感器。在2.7V的典型工作状态下,关闭参考电压,功耗可小于0.75mW。XPT2046采用微小的封装形式:TSSOP-16,QFN-16(0.75mm厚度)和VFBGA-48。工作温度范围为-40℃~+85℃。 该芯片完全是兼容ADS7843和ADS7846的,关于这个芯片的详细使用,可以参考这两个芯片的datasheet。 电阻式触摸屏就介绍到这里。 2)电容式触摸屏 现在几乎所有智能手机,包括平板电脑都是采用电容屏作为触摸屏,电容屏是利用人体感应进行触点检测控制,不需要直接接触或只需要轻微接触,通过检测感应电流来定位触摸坐标。 正点原子4.3/7/10.1寸LCD模块自带的触摸屏采用的是电容式触摸屏,下面简单介绍下电容式触摸屏的原理。 电容式触摸屏主要分为两种: 1、表面电容式电容触摸屏。 表面电容式触摸屏技术是利用ITO(铟锡氧化物,一种透明的导电材料)导电膜,通过电场感应方式感测屏幕表面的触摸行为进行。但是表面电容式触摸屏有一些局限性,它只能识别一个手指或者一次触摸。 2、投射式电容触摸屏。 投射电容式触摸屏是传感器利用触摸屏电极发射出静电场线。一般用于投射电容传感技术的电容类型有两种:自我电容和交互电容。 自我电容又称绝对电容,是最广为采用的一种方法,自我电容通常是指扫描电极与地构成的电容。在 玻璃表面有用ITO制成的横向与纵向的扫描电极,这些电极和地之间就构成一个电容的两极。当用手或触摸笔触摸的时候就会并联一个电容到电路中去,从而使在该条扫描线上的总体的电容量有所改变。在扫描的时候,控制IC依次扫描纵向和横向电极,并根据扫描前后的电容变化来确定触摸点坐标位置。笔记本电脑触摸输入板就是采用的这种方式,笔记本电脑的输入板采用XY的传感电极阵列形成一个传感格子,当手指靠近触摸输入板时,在手指和传感电极之间产生一个小量电荷。采用特定的运算法则处理来自行、列传感器的信号,以此确定手指的位置。 交互电容又叫做跨越电容,它是在玻璃表面的横向和纵向的ITO电极的交叉处形成电容。交互电容的扫描方式就是扫描每个交叉处的电容变化,来判定触摸点的位置。当触摸的时候就会影响到相邻电极的耦合,从而改变交叉处的电容量,交互电容的扫面方法可以侦测到每个交叉点的电容值和触摸后电容变化,因而它需要的扫描时间与自我电容的扫描方式相比要长一些,需要扫描检测XY根电极。目前智能手机/平板电脑等的触摸屏,都是采用交互电容技术。 正点原子所选择的电容触摸屏,采用的是投射式电容屏(交互电容类型),所以后面仅以投射式电容屏作为介绍。 透射式电容触摸屏采用纵横两列电极组成感应矩阵来感应触摸。以两个交叉的电极矩阵(X轴电极和Y轴电极)来检测每一格感应单元的电容变化,如下图所示: 在这里插入图片描述

图 7.5.13.1 投射式电容屏电极矩阵示意图 示意图中的电极,实际是透明的,这里是为了方便大家理解故填充了颜色。图中,X、Y轴的透明电极电容屏的精度、分辨率与X、Y轴的通道数有关,通道数越多,精度越高。以上就是电容触摸屏的基本原理,接下来看看电容触摸屏的优缺点: 电容触摸屏的优点:手感好、无需校准、支持多点触摸、透光性好。 电容触摸屏的缺点:成本高、精度不高、抗干扰能力差。 这里特别提醒大家电容触摸屏对工作环境的要求是比较高的,在潮湿、多尘、高低温环境下面,都是不适合使用电容屏的。 电容触摸屏一般都需要一个驱动IC来检测电容触摸,且一般是通过IIC接口输出触摸数据的。正点原子7’LCD模块的电容触摸屏,使用FT5206/FT5426做为驱动IC,该IC采用的是1528的驱动结构(15个感应通道,28个驱动通道)。正点原子4.3’LCD模块则使用GT9147作为驱动IC,该IC采用1710的驱动结构(10个感应通道,17个驱动通道)。 这两种不同尺寸的屏幕都只支持最多5点触摸,本例程除CPLD方案的V1版本7寸屏模块不支持外,其他所有正点原子的RGB LCD模块都支持,电容触摸驱动IC,这里只介绍GT9147的驱动,FT5206和FT5426的驱动同GT9147类似,大家可以参考着学习即可。 下面我们简单介绍下GT9147,该芯片是深圳汇顶科技研发的一颗电容触摸屏驱动IC,支持100Hz触点扫描频率,支持5点触摸,支持18*10个检测通道,适合小于4.5寸的电容触摸屏使用。 GT9147与FPGA连接是通过4根线:SDA、SCL、RST和INT。其中:SDA和SCL是IIC通信用的,RST是复位脚(低电平有效),INT是中断输出信号。 GT9147的IIC地址,可以是0X14或者0X5D,当复位结束后的5ms内,如果INT是高电平,则使用0X14作为地址,否则使用0X5D作为地址,具体的设置过程请参考GT9147数据手册.pdf这个文档。本章我们使用0X14作为器件地址(不含最低位,换算成读写命令则是读:0X29,写:0X28)。接下来,介绍一下GT9147的几个重要的寄存器。 1,控制命令寄存器(0X8040) 该寄存器可以写入不同值,实现不同的控制,我们一般使用0和2这两个值,写入2,即可软复位GT9147,在硬复位之后,一般要往该寄存器写2,实行软复位。然后,写入0,即可正常读取坐标数据(并且会结束软复位)。 2,配置寄存器组(0X8047~0X8100) 这里共186个寄存器,用于配置GT9147的各个参数,这些配置一般由厂家提供给我们(一个数组),所以我们只需要将厂家给我们的配置,写入到这些寄存器里面,即可完成GT9147的配置。由于GT9147可以保存配置信息(可写入内部FLASH,从而不需要每次上电都更新配置),这里有几点注意的地方提醒大家:1,0X8047寄存器用于指示配置文件版本号,程序写入的版本号,必须大于等于GT9147本地保存的版本号,才可以更新配置。2,0X80FF寄存器用于存储校验和,使得0X8047~0X80FF之间所有数据之和为0。3,0X8100用于控制是否将配置保存在本地,写0,则不保存配置,写1则保存配置。 3,产品ID寄存器(0X8140~0X8143) 这里总共由 4 个寄存器组成,用于保存产品 ID,对于GT9147,这4个寄存器读出来就是:9,1,4,7四个字符(ASCII码格式)。因此,我们可以通过这4个寄存器的值,来判断驱动IC的型号,从而判断是GT9147还是FT5206,以便执行不同的初始化。 4,状态寄存器(0X814E) 该寄存器各位描述如下表所示: 表 20.1.1 寄存器定义 寄存器 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 0X814E buffer状态 大点 接近有效 按键 有效触点个数 这里,我们仅关心最高位和最低4位,最高位用于表示buffer状态,如果有数据(坐标/按键),buffer就会是1,最低4位用于表示有效触点的个数,范围是:0~5,0表示没有触摸,5表示有5点触摸。最后,该寄存器在每次读取后,如果bit7有效,则必须写0,清除这个位,否则不会输出下一次数据!!这个要特别注意!!! 5,坐标数据寄存器(共 30 个) 这里共分成5组(5个点),每组6个寄存器存储数据,以触点1的坐标数据寄存器组为例,如下表所示: 表 7.5.13.2 触点 1 坐标寄存器组描述 寄存器 bit7~0 寄存器 bit7~0 0X8150 触点1 x坐标低8位 0X8150 触点1 x坐标低8位 0X8150 触点1 x坐标低8位 0X8150 触点1 x坐标低8位 0X8150 触点1触摸尺寸低8位 0X8150 触点1触摸尺寸高8位 我们一般只用到触点的x,y坐标,所以只需要读取0X81500X8153的数据,组合即可得到触点坐标。其他4组分别是:0X8158、0X8160、0X8168和0X8170等开头的16个寄存器组成,分别针对触点24的坐标。GT9147支持寄存器地址自增,我们只需要发送寄存器组的首地址,然后连续读取即可,GT9147会自动地址自增,从而提高读取速度。 GT9147相关寄存器的介绍就介绍到这里,更详细的资料,请参考:GT9147编程指南.pdf这个文档。 GT9147只需要经过简单的初始化就可以正常使用了,初始化流程:硬复位→延时10ms→结束硬复位→设置IIC地址→延时100ms→软复位→更新配置(需要时)→结束软复位。此时GT9147即可正常使用了。 然后,我们不停的查询0X814E寄存器,判断是否有有效触点,如果有,则读取坐标数据寄存器,得到触点坐标,特别注意,如果0X814E读到的值最高位为1,就必须对该位写0,否则无法读到下一次坐标数据。 特别说明:FT5206和FT5426的驱动代码完全一模一样,他们只是版本号读取的时候稍有差异,读坐标数据和配置等操作动完全是一模一样的。所以,这两个电容屏驱动IC,可以共用一个驱动程序。电容式触摸屏部分,就介绍到这里。 20.2 实验任务 本节的实验任务是使用领航者开发板驱动LCD显示屏,用手触摸显示屏,在屏幕上显示触摸点的坐标。 20.3 硬件设计 领航者板载的LCD接口原理图如图 7.5.13.1所示。 在这里插入图片描述

图 7.5.13.1 LCD接口原理图 上图中的关于LCD显示部分的引脚就不再介绍了,这里我们主要看下CT_RST、IIC2_SDA、IIC2_SCL、CT_INT四个引脚,这四个引脚分别连接到了GT9147的RST、SDA、SCL和INT四根引脚,我们在代码中通过控制这四个引脚来初始化GT9147芯片或者和GT9147进行数据交互。 本实验中,各端口信号的管脚分配(由于引脚比较多,这里只给出了GT9147的控制引脚,详细引脚请参考例程提供的XDC文件)如下表所示: 表 20.3.1 触摸显示实验管脚分配 信号名 方向 管脚 端口说明 电平标准 touch_scl output R19 IIC通信引脚 LVCMOS33 touch_sda inout P20 IIC通信引脚 LVCMOS33 touch_int inout U19 中断引脚 LVCMOS33 touch_rst output M19 WM8960的数据线 LVCMOS33 对应的约束语句(GT9147的引脚约束语句)如下所示:

set_property -dict {PACKAGE_PIN R19 IOSTANDARD LVCMOS33} [get_ports touch_scl]
set_property -dict {PACKAGE_PIN P20 IOSTANDARD LVCMOS33} [get_ports touch_sda]
set_property -dict {PACKAGE_PIN U19 IOSTANDARD LVCMOS33} [get_ports touch_int]
set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS33} [get_ports touch_rst]

20.4 程序设计 根据实验任务我们画出了如下的程序框图: 在这里插入图片描述

图 7.5.13.1 LCD触摸实验程序框图 从上图的程序框架中可以看出本次实验的软件工程主要分成两个大模块:一个是GT9147配置模块(本节实验文档是以GT9147为例的,其他触摸芯片的配置和GT9147基本雷同),这个模块当中包含了IIC通信协议模块,触摸控制模块和信号切换模块,其主要作用就是配置触摸芯片,并和触摸芯片进行数据交互;另一个模块就是LCD显示模块了,这个模块大家应该很熟悉了,在前面LCD显示相关的实验中已经和大家讲解过了,在此就不再重复赘述了。下面我们来一起分析一下本节实验的代码。 本次LCD触摸实验的代码可以分成三个大模块:顶层例化模块(LCD_Touch_top)、触摸配置顶层模块(top_touch)、LCD屏幕显示顶层模块(lcd_rgb_char)。 其中顶层例化模块(LCD_Touch_top)模块代码如下:

1  module LCD_Touch_top(
2  
3     //时钟和复位接口
4      input                clk_50m,     //晶振时钟
5      input                rst_n,       //按键复位
6     //SDRAM 接口
7      inout                touch_sda,
8      output               touch_scl,
9      inout                touch_int,
10     output               touch_rst,    
11      //RGB LCD接口
12     output               lcd_de,      //LCD 数据使能信号
13     output               lcd_hs,      //LCD 行同步信号
14     output               lcd_vs,      //LCD 场同步信号
15     output               lcd_bl,      //LCD 背光控制信号
16     output               lcd_rst_n,
17     output               lcd_clk,     //LCD 像素时钟
18     inout        [23:0]  lcd_rgb      //LCD RGB888颜色数据
19 );
20 
21 //wire define
22 wire        clk_100m        ;
23 wire        clk_50m_pll     ;
24 wire        locked          ;
25 wire        sys_rst_n       ;
26 wire        touch_valid     ;
27 wire [15:0] lcd_id          ;
28 wire [31:0] tp1_xy          ;    
29 wire [31:0] data            ;
30 wire        tft_sda_i       ;
31 wire        tft_sda_o       ;
32 wire        tft_sda_t       ;
33 //*****************************************************
34 //**                    main code
35 //*****************************************************
36 
37 assign sys_rst_n = rst_n & locked;
38 assign data = {tp1_xy[31:16],tp1_xy[15:0]}; 
39 assign lcd_rst_n = 1'b1;
40 assign touch_sda = tft_sda_t  ?  tft_sda_o  :  1'bz;
41 assign tft_sda_i = touch_sda;
42 
43 //例化锁相环模块
44  clk_wiz_0 instance_name
45    (
46     // Clock out ports
47     .clk_out1(clk_50m_pll), // output clk_out1
48     .clk_out2(clk_100m),    // output clk_out2
49     // Status and control signals
50     .reset(!rst_n),         // input reset
51     .locked(locked),        // output locked
52    // Clock in ports
53     .clk_in1(clk_50m));     // input clk_in1
54 
55 //触摸驱动
56 top_touch u_top_touch(
57     .sys_clk                            (clk_100m),
58     .sys_rst_n                          (sys_rst_n),      
59     .lcd_init_done                      (1),       
60     .lcd_id                             (lcd_id),               //LCD ID 
61     
62    .tft_sda_i                           (tft_sda_i),
63    .tft_sda_o                           (tft_sda_o),
64    .tft_sda_t                           (tft_sda_t),
65    .tft_scl                             (touch_scl),
66    .tft_tcs                             (touch_rst), 
67    .tp1_xy                              (tp1_xy),
68    .touch_valid                         (touch_valid),              
69    .tp_num                              ()
70     );
71 
72 //例化LCD显示模块
73 lcd_rgb_char  u_lcd_rgb_char
74 (
75    .sys_clk                             (clk_50m_pll),
76    .sys_rst_n                           (sys_rst_n),
77    .data                                (data),
78    //RGB LCD接口 
79    .lcd_id                              (lcd_id),
80    .lcd_hs                              (lcd_hs),       //LCD 行同步信号
81    .lcd_vs                              (lcd_vs),       //LCD 场同步信号
82    .lcd_de                              (lcd_de),       //LCD 数据输入使能
83    .lcd_rgb                             (lcd_rgb),      //LCD RGB888颜色数据
84    .lcd_bl                              (lcd_bl),       //LCD 背光控制信号
85    .lcd_clk                             (lcd_clk)       //LCD 采样时钟
86 );  
87 
88 endmodule 

顶层代码比较简单主要就是例化锁相环(clk_wiz_0)模块、触摸配置顶层模块(top_touch)和LCD屏幕显示顶层模块(lcd_rgb_char),需要注意的一点就是代码第40和41行做了一个双向的判断,因为IIC协议不仅仅是主机(FPGA)对从机(GT9147)写数据,还要接收从机反馈的数据,因此touch_sda信号什么时候作为输入什么时候作为输出必须给出一个判断条件(tft_sda_t)来判断,这个判断条件是由IIC驱动模块(i2c_dri_m)发出的;还有一个GT9147自身中断控制信号(touch_int)也是双向信号,它是在触摸控制模块做的处理。 接下来我们继续分析顶层模块(LCD_Touch_top)所例化的子模块代码,首先看一下锁相环(clk_wiz_0)模块,它主要是用来生成一路50M时钟(clk_50m_pll)和一路100M(clk_100m)时钟。可能有人会疑惑系统时钟不就是50M时钟,为什么还要重新生成一次50M时钟?其实将系统时钟过一遍锁相环是常用的一种消除时钟抖动、扭斜的方法,并且锁相环还输出了一个locked信号,这个信号拉高代表时钟稳定,此时再去执行逻辑语句会使整个工程的时序更加稳定。 看完锁相环(clk_wiz_0)模块后我们继续分析触摸配置顶层模块(top_touch),顾名思义配置顶层模块是整个触摸操作的顶层模块,它同样例化了2个子模块,分别是寄存器配置模块(touch_gt_cfg)和触摸控制模块(touch_ctrl),下面给出触摸配置顶层模块(top_touch)的代码:

1   module top_touch(
2       //module clock
3       input                  sys_clk,          // 系统时钟信号
4       input                  sys_rst_n,        // 复位信号(低有效)
5   
6       //tft interface
7      // inout                  tft_sda,
8       input                  tft_sda_i,
9       output                 tft_sda_o,
10      output                 tft_sda_t,
11      output                 tft_scl,
12      inout                  tft_int,
13      output   reg           tft_tcs,
14  
15      //touch lcd interface    
16      output   reg           touch_valid,      // 连续触摸标志
17      output        [ 2:0]    tp_num,
18      
19      input                  lcd_init_done,
20      input         [15:0]   lcd_id,
21      output  reg   [31:0]   tp1_xy
22  );
23  
24  //parameter define
25  parameter   WIDTH = 5'd8;
26  //reg define
27  reg                       bigger_en ;        //电容屏使能信号
28  //wire define
29  wire                      sda_out   ;
30  wire                      sda_dir   ;
31  wire                      ack;
32  wire                      i2c_exec  ;
33  wire                      i2c_rh_wl ;
34  wire    [15:0]            i2c_addr  ;
35  wire    [ 7:0]            i2c_data_w;
36  wire    [WIDTH-1'b1:0]    reg_num   ;
37  wire    [ 7:0]            i2c_data_r;
38  wire                      i2c_done  ;
39  wire                      once_done ;
40  wire                      bit_ctrl  ;
41  wire                      clk       ;
42  wire                      cfg_done  ;
43  wire                      cfg_switch;
44  wire                      gf_cs     ;
45  wire                      gf_done   ;
46  wire                      gf_valid  ;
47  wire    [31:0]            gf_xy     ;
48  
49  //*****************************************************
50  //**                    main code
51  //*****************************************************
52  
53  assign tft_sda_o=sda_out;
54  assign tft_sda_t=sda_dir;
55  
56  always @(*) begin
57      if(!lcd_init_done) begin     
58          bigger_en = 1'b0;
59      end    
60          else begin           
61              bigger_en   = 1'b1;
62              tft_tcs     = gf_cs;          
63              touch_valid = gf_valid;
64              tp1_xy      = gf_xy;
65          end
66      end
67  
68  touch_gt_cfg #(.WIDTH(4'd8)) u_touch_gt_cfg(
69      //module clock
70      .clk                (sys_clk   ),         // 时钟信号
71      .rst_n              (sys_rst_n ),         // 复位信号
72      //port interface
73      .scl                (tft_scl    ),          // 时钟线scl
74      .sda_in             (tft_sda_i ),          // 数据线sda
75      .sda_out            (sda_out),
76      .sda_dir            (sda_dir),  
77      //I2C interface
78      .ack                (ack       ),
79      .i2c_exec           (i2c_exec  ),          // i2c触发控制
80      .i2c_rh_wl          (i2c_rh_wl ),          // i2c读写控制
81      .i2c_addr           (i2c_addr  ),          // i2c操作地址
82      .i2c_data_w         (i2c_data_w),          // i2c写入的数据
83      .reg_num            (reg_num   ),
84      .i2c_data_r         (i2c_data_r),          // i2c读出的数据
85      .i2c_done           (i2c_done  ),          // i2c操作结束标志
86      .once_done          (once_done ),          // 一次读写操作完成
87      .bit_ctrl           (bit_ctrl  ),
88      .clk_i2c            (clk       ),          // I2C操作时钟
89      .cfg_done           (cfg_done  ),          // 寄存器配置完成标志
90      //user interfacd
91      .cfg_switch         (cfg_switch),
92      .lcd_id             (lcd_id    )           //LCD ID
93  );
94  
95  touch_ctrl
96      #(.WIDTH(4'd8))                           // 一次读写寄存器的个数的位宽
97  u_touch_ctrl(
98      //module clock
99      .sys_clk            (sys_clk  ),
100     .clk                (clk      ),           // 时钟信号
101     .rst_n              (sys_rst_n),           // 复位信号(低有效)
102     .cfg_done           (cfg_done ),            // 配置完成标志
103     .tft_tcs            (gf_cs    ),
104     .tft_int            (tft_int  ),
105 
106     //I2C interface
107     .ack                (ack       ),
108     .i2c_exec           (i2c_exec  ),          // i2c触发控制
109     .i2c_rh_wl          (i2c_rh_wl ),          // i2c读写控制
110     .i2c_addr           (i2c_addr  ),          // i2c操作地址
111     .i2c_data_w         (i2c_data_w),          // i2c写入的数据
112     .i2c_data_r         (i2c_data_r),          // i2c读出的数据
113     .once_done          (once_done ),          // 一次读写操作完成
114     .i2c_done           (i2c_done  ),          // i2c操作结束标志
115     .bit_ctrl           (bit_ctrl  ),
116     .reg_num            (reg_num   ),          // 一次读写寄存器的个数
117 
118     //touch lcd interface   
119     .touch_valid        (gf_valid),
120     .tp_num             (tp_num),
121     .tp1_xy             (gf_xy),
122     .tp2_xy             (),
123     .tp3_xy             (),
124     .tp4_xy             (),
125     .tp5_xy             (),
126 
127     //user interface
128     .cfg_switch         (cfg_switch),
129     .lcd_id             (lcd_id    ),      //LCD ID
130     .bigger_en          (bigger_en )
131 );
132 
133 endmodule

触摸配置顶层模块(top_touch)的代码很容易理解,它就是单纯的作为一个顶层模块去例化寄存器配置模块(touch_gt_cfg)和触摸控制模块(touch_ctrl),下面我们来重点分析这两个子模块。 首先给出触摸控制模块(touch_ctrl)的代码(由于这个模块的代码太长我们一段一段的分析):

87  assign tft_int = int_dir ? int_out : 1'bz;
88  
89  always @(*) begin
90      if(lcd_id[15:8] == 8'h70 ) begin    // 7寸屏的FT系列触摸芯片
91              bit_ctrl     = 1'b0 ;   
92              CTRL_REG     = 8'h00;        // 控制寄存器地址
93              GTCH_REG     = 8'h02;        // 检测到的当前触摸情况
94              TP1_REG      = 8'h03;        // 第一个触摸点数据地址
95              TP2_REG      = 8'h09;        // 第二个触摸点数据地址
96              TP3_REG      = 8'h0f;        // 第三个触摸点数据地址
97              TP4_REG      = 8'h15;        // 第四个触摸点数据地址
98              TP5_REG      = 8'h1b;        // 第五个触摸点数据地址
99      end 
100     else begin
101             bit_ctrl     = 1'b1    ;
102             CTRL_REG     = 16'h8040;     // 控制寄存器地址
103             GTCH_REG     = 16'h814e;     // 检测到的当前触摸情况
104             TP1_REG      = 16'h8150;     // 第一个触摸点数据地址
105             TP2_REG      = 16'h8158;     // 第二个触摸点数据地址
106             TP3_REG      = 16'h8160;     // 第三个触摸点数据地址
107             TP4_REG      = 16'h8168;     // 第四个触摸点数据地址
108             TP5_REG      = 16'h8170;     // 第五个触摸点数据地址
109     end
110 end
111 
112 //计时控制
113 always @(posedge clk or negedge rst_n) begin
114     if(!rst_n) begin
115        cnt_1us_cnt             
关注
打赏
1665308814
查看更多评论
0.0481s