本实验的源码工程在开发板光盘资料的:i.MX6UL终结者光盘资料\04_裸机例程源码\17_touchscreen 目录下。我们在Ubuntu系统下使用命令“mkdir 17_touchscreen”建立“17_touchscreen”文件夹,如图 1所示:
然后使用“cd 17_touchscreen”命令进入到17_touchscreen文件夹,如图 2所示:
然后使用命令“cp -r …/16_i2c/* ./”将上一章试验中的所有内容拷贝到刚刚新建的“17_touchscreen”里面,如图 3所示:
然后在drivers目录下建立touchscreen文件夹,用来保存触摸的驱动文件,然后在“drivers/touchscreen”目录中新建ft5xx6.c.h和ft5xx6.c.c两个文件,然后在ft5xx6.c.h文件输入下面的代码:
1 #ifndef _FT5XX6_H
2 #define _FT5XX6_H
3
4 #include "imx6ul.h"
5 #include "gpio.h"
6
7 /* 宏定义 */
8 #define FT5426_ADDR 0X38 /* FT5426设备地址 */
9
10 #define FT5426_DEVICE_MODE 0X00 /* 模式寄存器 */
11 #define FT5426_IDGLIB_VERSION 0XA1 /* 固件版本寄存器 */
12 #define FT5426_IDG_MODE 0XA4 /* 中断模式 */
13 #define FT5426_TD_STATUS 0X02 /* 触摸状态寄存器 */
14 #define FT5426_TOUCH1_XH 0X03 /* 触摸点坐标寄存器,
15 * 一个触摸点用4个寄存器存
储坐标数据*/
16
17 #define FT5426_XYCOORDREG_NUM 30 /* 触摸点坐标寄存器数量 */
18 #define FT5426_INIT_FINISHED 1 /* 触摸屏初始化完成 */
19 #define FT5426_INIT_NOTFINISHED 0 /* 触摸屏初始化未完成 */
20
21 #define FT5426_TOUCH_EVENT_DOWN 0x00 /* 按下 */
22 #define FT5426_TOUCH_EVENT_UP 0x01 /* 释放 */
23 #define FT5426_TOUCH_EVENT_ON 0x02 /* 接触 */
24 #define FT5426_TOUCH_EVENT_RESERVED 0x03 /* 没有事件 */
25
26 /* 触摸屏结构体 */
27 struct ft5426_dev_struc
28 {
29 unsigned char initfalg; /* 触摸屏初始化状态 */
30 unsigned char intflag; /* 标记中断有没有发生 */
31 unsigned char point_num; /* 触摸点 */
32 unsigned short x[5]; /* X轴坐标 */
33 unsigned short y[5]; /* Y轴坐标 */
34
35 };
36
37 extern struct ft5426_dev_struc ft5426_dev;
38
39 /* 函数声明 */
40 void ft5426_init(void);
41 ^Mvoid gpio1_io9_irqhandler(void);
42 unsigned char ft5426_write_byte(unsigned char addr,
43 unsigned char reg,
44 unsigned char data);
45 unsigned char ft5426_read_byte(unsigned char addr,
46 unsigned char reg);
47 void ft5426_read_len(unsigned char addr,
48 unsigned char reg,
49 unsigned char len,
50 unsigned char *buf);
51 void ft5426_read_tpnum(void);
52 void ft5426_read_tpcoord(void);
53
54 #endif
该文件主要定义了一些宏用来表示FT5426的I2C地址,寄存器,以及一些操作状态,然后在27行定义了一个保存触摸信息的结构体,最后声明了一些FT5426操作的函数。
接下来我们打开ft5xx6.c
1 #include "ft5xx6.h"
2 #include "i2c.h"
3 #include "int.h"
4 #include "delay.h"
5 #include "stdio.h"
6
7 struct ft5426_dev_struc ft5426_dev;
8
9 /*
10 * @description : 初始化触摸屏,其实就是初始化FT5426
11 * @param : 无
12 * @return : 无
13 */
14 void ft5426_init(void)
15 {
16 unsigned char reg_value[2];
17
18 ft5426_dev.initfalg = FT5426_INIT_NOTFINISHED;
19
20 /* 1、初始化IIC2 IO
21 * I2C2_SCL -> UART5_TXD
22 * I2C2_SDA -> UART5_RXD
23 */
24 IOMUXC_SetPinMux(IOMUXC_UART5_TX_DATA_I2C2_SCL,1);
25 IOMUXC_SetPinMux(IOMUXC_UART5_RX_DATA_I2C2_SDA,1);
26
27 /* 配置I2C2 IO属性
28 *bit 16:0 HYS关闭
29 *bit [15:14]: 1 默认47K上拉
30 *bit [13]: 1 pull功能
31 *bit [12]: 1 pull/keeper使能
32 *bit [11]: 0 关闭开路输出
33 *bit [7:6]: 10 速度100Mhz
34 *bit [5:3]: 110 驱动能力为R0/6
35 *bit [0]: 1 高转换率
36 */
37 IOMUXC_SetPinConfig(IOMUXC_UART5_TX_DATA_I2C2_SCL,0x70B0);
38 IOMUXC_SetPinConfig(IOMUXC_UART5_RX_DATA_I2C2_SDA,0X70B0);
39
40 /* 2、初始化触摸屏中断IO和复位IO */
41 gpio_pin_config_t ctintpin_config;
42
43 IOMUXC_SetPinMux(IOMUXC_GPIO1_IO09_GPIO1_IO09,0); /* 复用为GPIO1_IO9 */
44 IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09,0);/* 复用为GPIO5_IO9 */
45
46 IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO09_GPIO1_IO09,0xF080);
47 IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09,0X10B0);
48
49 /* 中断IO初始化 */
50 ctintpin_config.direction = kGPIO_DigitalInput;
51 ctintpin_config.interruptMode = kGPIO_IntRisingOrFallingEdge;
52 gpio_init(GPIO1, 9, &ctintpin_config);
53
54 GIC_EnableIRQ(GPIO1_Combined_0_15_IRQn); /* 使能GIC中对应的中断 */
55 system_register_irqhandler(GPIO1_Combined_0_15_IRQn,
56 (system_irq_handler_t)gpio1_io9_irqhandler,
57 NULL); /* 注册中断服务函数 */
58 gpio_enableint(GPIO1, 9); /* 使能GPIO1_IO18的中断功能 */
59
60 /* 复位IO初始化 */
61 ctintpin_config.direction=kGPIO_DigitalOutput;
62 ctintpin_config.interruptMode=kGPIO_NoIntmode;
63 ctintpin_config.outputLogic=1;
64 gpio_init(GPIO5, 9, &ctintpin_config);
65
66 /* 3、初始化I2C */
67 i2c_init(I2C2);
68
69 /* 4、初始化FT5426 */
70 gpio_pinwrite(GPIO5, 9, 0); /* 复位FT5426 */
71 delayms(20);
72 gpio_pinwrite(GPIO5, 9, 1); /* 停止复位FT5426 */
73 delayms(20);
74
75 ft5426_write_byte(FT5426_ADDR, FT5426_DEVICE_MODE, 0); /*正常模式 */
76 ft5426_write_byte(FT5426_ADDR, FT5426_IDG_MODE, 1); /* 中断模式 */
77
78
79 ft5426_read_len(FT5426_ADDR,
80 FT5426_IDGLIB_VERSION,
81 2, reg_value);
82 printf("Touch Frimware Version:%#X\r\n",
83 ((unsigned short)reg_value[0] << 8) + reg_value[1]);
84
85 ft5426_dev.initfalg = FT5426_INIT_FINISHED;/* 标记FT5426初始化完成 */
86 ft5426_dev.intflag = 0;
87 }
88
89 /*
90 * @description : GPIO1_IO9最终的中断处理函数
91 * @param : 无
92 * @return : 无
93 */
94 void gpio1_io9_irqhandler(void)
95 {
96 if(ft5426_dev.initfalg == FT5426_INIT_FINISHED)
97 {
98 //ft5426_dev.intflag = 1;
99 ft5426_read_tpcoord();
100 }
101 gpio_clearintflags(GPIO1, 9); /* 清除中断标志位 */
102 }
103
104
105 /*
106 * @description : 向FT5429写入数据
107 * @param - addr: 设备地址
108 * @param - reg : 要写入的寄存器
109 * @param - data: 要写入的数据
110 * @return : 操作结果
111 */
112 unsigned char ft5426_write_byte(unsigned char addr,
113 unsigned char reg,
114 unsigned char data)
115 {
116 unsigned char status=0;
117 unsigned char writedata=data;
118 struct i2c_transfer masterXfer;
119
120 /* 配置I2C xfer结构体 */
121 masterXfer.slaveAddress = addr; /* 设备地址 */
122 masterXfer.direction = kI2C_Write; /* 写入数据 */
123 masterXfer.subaddress = reg; /* 要写入的寄存器地址 */
124 masterXfer.subaddressSize = 1; /* 地址长度一个字节 */
125 masterXfer.data = &writedata; /* 要写入的数据 */
126 masterXfer.dataSize = 1; /* 写入数据长度1个字节*/
127
128 if(i2c_master_transfer(I2C2, &masterXfer))
129 status=1;
130
131 return status;
132 }
133
134 /*
135 * @description : 从FT5426读取一个字节的数据
136 * @param - addr: 设备地址
137 * @param - reg : 要读取的寄存器
138 * @return : 读取到的数据。
139 */
140 unsigned char ft5426_read_byte(unsigned char addr,
141 unsigned char reg)
142 {
143 unsigned char val=0;
144
145 struct i2c_transfer masterXfer;
146 masterXfer.slaveAddress = addr; /* 设备地址 */
147 masterXfer.direction = kI2C_Read; /* 读取数据 */
148 masterXfer.subaddress = reg; /* 要读取的寄存器地址 */
149 masterXfer.subaddressSize = 1; /* 地址长度一个字节 */
150 masterXfer.data = &val; /* 接收数据缓冲区 */
151 masterXfer.dataSize = 1; /* 读取数据长度1个字节 */
152 i2c_master_transfer(I2C2, &masterXfer);
153
154 return val;
155 }
156
157 /*
158 * @description : 从FT5429读取多个字节的数据
159 * @param - addr: 设备地址
160 * @param - reg : 要读取的开始寄存器地址
161 * @param - len : 要读取的数据长度.
162 * @param - buf : 读取到的数据缓冲区
163 * @return : 无
164 */
165 void ft5426_read_len(unsigned char addr,
166 unsigned char reg,
167 unsigned char len,
168 unsigned char *buf)
169 {
170 struct i2c_transfer masterXfer;
171
172 masterXfer.slaveAddress = addr; /* 设备地址 */
173 masterXfer.direction = kI2C_Read; /* 读取数据 */
174 masterXfer.subaddress = reg; /* 要读取的寄存器地址 */
175 masterXfer.subaddressSize = 1; /* 地址长度一个字节 */
176 masterXfer.data = buf; /* 接收数据缓冲区 */
177 masterXfer.dataSize = len; /* 读取数据长度1个字节*/
178 i2c_master_transfer(I2C2, &masterXfer);
179 }
180
181 /*
182 * @description : 读取当前触摸点个数
183 * @param : 无
184 * @return : 无
185 */
186 void ft5426_read_tpnum(void)
187 {
188 ft5426_dev.point_num = ft5426_read_byte(FT5426_ADDR,
189 FT5426_TD_STATUS);
190 }
191
192 /*
193 * @description : 读取当前所有触摸点的坐标
194 * @param : 无
195 * @return : 无
196 */
197 void ft5426_read_tpcoord(void)
198 {
199 unsigned char i = 0;
200 unsigned char type = 0;
201 //unsigned char id = 0;
202 unsigned char pointbuf[FT5426_XYCOORDREG_NUM];
203
204 ft5426_dev.point_num = ft5426_read_byte(FT5426_ADDR,
205 FT5426_TD_STATUS);
206
207 /*
208 *从寄存FT5426_TOUCH1_XH开始连续读取30个寄存器的值这30个寄存器
209 * 保存着5个点的触摸值,每个点占用6个寄存器。
210 */
211 ft5426_read_len(FT5426_ADDR,
212 FT5426_TOUCH1_XH,
213 FT5426_XYCOORDREG_NUM, pointbuf);
214
215 for(i = 0; i < ft5426_dev.point_num ; i++)
216 {
217 unsigned char *buf = &pointbuf[i * 6];
218 /*以第一个触摸点为例寄存TOUCH1_XH(地址0X03),各位描述如下:
219 * bit7:6 Event flag 0:按下 1:释放 2:接触 3:没有事件
220 * bit5:4 保留
221 * bit3:0 X轴触摸点的11~8位。
222 */
223 ft5426_dev.x[i] = ((buf[2] << 8) | buf[3]) & 0x0fff;
224 ft5426_dev.y[i] = ((buf[0] << 8) | buf[1]) & 0x0fff;
225
226 type = buf[0] >> 6;/* 获取触摸类型 */^M
227
228 /*以第一个触摸点为例寄存TOUCH1_YH(地址0X05),各位描述如下:
229 * bit7:4 Touch ID 触摸ID,表示是哪个触摸点
230 * bit3:0 Y轴触摸点的11~8位。
231 */
232 //id = (buf[2] >> 4) & 0x0f;
233
234 if(type == FT5426_TOUCH_EVENT_DOWN
235 || type == FT5426_TOUCH_EVENT_ON )/* 按下 */
236 {
237
238 } else { /* 释放 */
239
240 }
241 }
242 }
ft5426_init函数完成触摸的初始化功能,此函数先初始化FT5426使用的I2C2的IO引脚,复位引脚和中断引脚,然后使能了中断,注册了中断处理函数,最后完成了I2C2和FT5426的初始化。
gpio1_io9_irqhandler函数是中断处理函数,在该函数中会调用ft5426_read_tpcoord函数读取触摸点的坐标信息。
ft5426_write_byte函数用于向FT5426写入一个字节数据。
ft5426_read_byte函数用于从FT5426读取一个字节的数据。
ft5426_read_len函数用于从FT5426读取一串数据。
ft5426_read_tpnum函数用于读取当前触摸点个数。
ft5426_read_tpcoord函数用于读取当前所有触摸点的坐标数据。
然后打开main.c文件,在里面输入下面的内容:
1 #include "clk.h"
2 #include "delay.h"
3 #include "led.h"
4 #include "beep.h"
5 #include "key.h"
6 #include "int.h"
7 #include "uart.h"
8 #include "lcd.h"
9 #include "lcdapi.h"
10 #include "rtc.h"
11 #include "ft5xx6.h"
12 #include "gt9147.h"
13 #include "stdio.h"
14
15 /*
16 * @description : 使能I.MX6U的硬件NEON和FPU
17 * @param : 无
18 * @return : 无
19 */
20 void imx6ul_hardfpu_enable(void)
21 {
22 uint32_t cpacr;
23 uint32_t fpexc;
24
25 /* 使能NEON和FPU */
26 cpacr = __get_CPACR();
27 cpacr = (cpacr & ~(CPACR_ASEDIS_Msk | CPACR_D32DIS_Msk))
28 | (3UL << CPACR_cp10_Pos) | (3UL << CPACR_cp11_Pos);
29 __set_CPACR(cpacr);
30 fpexc = __get_FPEXC();
31 fpexc |= 0x40000000UL;
32 __set_FPEXC(fpexc);
33 }
34
35 /*
36 * @description : main函数
37 * @param : 无
38 * @return : 无
39 */
40 int main(void)
41 {
42 unsigned char i = 0;
43 unsigned char state = OFF;
44
45 imx6ul_hardfpu_enable();/* 使能I.MX6U的硬件浮点 */
46 int_init(); /* 初始化中断(一定要最先调用!) */
47 imx6u_clkinit(); /* 初始化系统时钟 */
48 delay_init(); /* 初始化延时 */
49 clk_enable(); /* 使能所有的时钟 */
50 led_init(); /* 初始化led */
51 beep_init(); /* 初始化beep */
52 uart_init(); /* 初始化串口,波特率115200 */
53 lcd_init(); /* 初始化LCD */
54
55 /* 初始化触摸屏 */
56 ft5426_init();
57 //gt9147_init();
58
59 tftlcd_dev.forecolor = LCD_RED;
60 lcd_show_string(50, 10, 400, 24, 24, (char*)"i.MX6ULL TOUCH SCREEN TEST");
61
62 lcd_show_string(50, 110, 400, 16, 16, (char*)"TP Num :");
63 lcd_show_string(50, 130, 200, 16, 16, (char*)"Point0 X:");
64 lcd_show_string(50, 150, 200, 16, 16, (char*)"Point0 Y:");
65 lcd_show_string(50, 170, 200, 16, 16, (char*)"Point1 X:");
66 lcd_show_string(50, 190, 200, 16, 16, (char*)"Point1 Y:");
67 lcd_show_string(50, 210, 200, 16, 16, (char*)"Point2 X:");
68 lcd_show_string(50, 230, 200, 16, 16, (char*)"Point2 Y:");
69 lcd_show_string(50, 250, 200, 16, 16, (char*)"Point3 X:");
70 lcd_show_string(50, 270, 200, 16, 16, (char*)"Point3 Y:");
71 lcd_show_string(50, 290, 200, 16, 16, (char*)"Point4 X:");
72 lcd_show_string(50, 310, 200, 16, 16, (char*)"Point4 Y:");
73 tftlcd_dev.forecolor = LCD_BLUE;
74
75 while(1)
76 {
77 lcd_shownum(50 + 72, 110, ft5426_dev.point_num , 1, 16);
78 lcd_shownum(50 + 72, 130, ft5426_dev.x[0], 5, 16);
79 lcd_shownum(50 + 72, 150, ft5426_dev.y[0], 5, 16);
80 lcd_shownum(50 + 72, 170, ft5426_dev.x[1], 5, 16);
81 lcd_shownum(50 + 72, 190, ft5426_dev.y[1], 5, 16);
82 lcd_shownum(50 + 72, 210, ft5426_dev.x[2], 5, 16);
83 lcd_shownum(50 + 72, 230, ft5426_dev.y[2], 5, 16);
84 lcd_shownum(50 + 72, 250, ft5426_dev.x[3], 5, 16);
85 lcd_shownum(50 + 72, 270, ft5426_dev.y[3], 5, 16);
86 lcd_shownum(50 + 72, 290, ft5426_dev.x[4], 5, 16);
87 lcd_shownum(50 + 72, 310, ft5426_dev.y[4], 5, 16);
88
89 delayms(10);
90 i++;
91
92 if(i == 50)
93 {
94 i = 0;
95 state = !state;
96 led_switch(LED0,state);
97 }
98 }
99 return 0;
100 }
第56行调用ft5426_init初始化触摸屏,最后在while主循环里面每隔10毫秒就会更新获取到的触摸信息,以及对应的坐标信息,我们在本例程中使用的是中断获取触摸信息的方式,所以在main.c中并没有调用ft5426的获取触摸信息的函数。