基础实验例程-3.11 触摸屏读取坐标数据
一、实验目的
本节课主要学习K210通过I2C读取触摸屏的坐标,并打印出来,显示在LCD上。
二、实验准备
1.实验元件
LCD显示屏+触摸板
2.元件特性
K210开发板自带2.0寸触摸屏,其实是LCD显示屏上贴一个触摸板组成,LCD显示屏上一节课已经学过,而触摸板为电容触摸板,与手机上使用的电容屏原理一样,可以直接用手指触摸,而不像电阻屏一样要用指甲按。电容屏具有相应时间短,精确度高,使用寿命长,操作简单方便等特点。触摸板使用的是I2C通讯,能够稳定传输数据,并且支持与其他I2C设备并联到同一个I2C接口上通讯。
3.硬件连接
K210开发板出厂默认已经安装好LCD显示屏和触摸板,其中LCD显示屏的LCD_D0~D7总共八个引脚连接到SPI0_D0~D7上,LCD_CS连接到IO36上,LCD_RST连接到IO37上,LCD_RS连接IO3上,LCD_WR连接IO39上;触摸板的I2C_SCL连接到IO9,I2C_SDA连接到IO10,FT_INT连接到IO12,FT_RST连接到IO37,与LCD显示屏共用使用一个RST接口。
4.SDK中对应API功能
对应的头文件 i2c.h
I2C总线用于和多个外部设备进行通信。多个外部设备可以共用一个I2C总线。
I2C模块具有独立的I2C设备封装外设相关参数,自动处理多设备总线争用的功能。
K210芯片集成电路总线有3个I2C总线接口,都可以作为I2C主机(MASTER)模式或从机(SLAVE)模式来使用。
I2C接口支持标准模式(0到100kb/s),快速模式(<=400kb/s),7位或10位寻址模式,批量传输模式,中断或轮询模式操作。
为用户提供以下接口:
• i2c_init:初始化I2C,配置从机地址、寄存器位宽度和I2C速率。
• i2c_init_as_slave:配置 I²C 为从模式。
• i2c_send_data:I2C写数据。
• i2c_send_data_dma:I2C通过DMA写数据。
• i2c_recv_data:I2C 通过CPU读数据。
• i2c_recv_data_dma:I2C通过dma读数据。
• i2c_handle_data_dma:I2C 使用dma传输数据。
三、实验原理
电容式触摸屏技术是利用人体的电流感应进行工作的。电容式触摸屏是一块四层复合玻璃屏,玻璃屏的内表面和夹层各涂有一层ITO,最外层是一薄层矽土玻璃保护层,夹层ITO涂层作为工作面,四个角上引出四个电极,内层ITO为屏蔽层以保证良好的工作环境。 当手指触摸在金属层上时,由于人体电场,用户和触摸屏表面形成以一个耦合电容,对于高频电流来说,电容是直接导体,于是手指从接触点吸走一个很小的电流。这个电流分别从触摸屏的四角上的电极中流出,并且流经这四个电极的电流与手指到四角的距离成正比,控制器通过对这四个电流比例的精确计算,得出触摸点的位置。
I2C是一种总线式结构,它只需要SCL时钟信号线与SDA数据线,两根线就能将连接与总线上的设备实现数据通信,由于它的简便的构造设计,于是成为一种较为常用的通信方式。由于I2C采用的是主从式通信方式,所以,通信的过程完全由主设备仲裁。在通信之前,必须由主设备发送一个起始信号,决定数据是否可以开始传送,并且在结束通信时,必须再由主设备发送一个结束信号,以表示通信已经结束。
I2C向寄存器写入数据的过程:
I2C从寄存器读取数据的过程:
四、实验过程
1.首先初始化K210的硬件引脚和软件功能使用的是FPIOA映射关系。
2.设置LCD的IO口电平电压为1.8V。
3.由于触摸板需要使用中断来判断屏幕是否有触摸,所有需要初始化中断并使能全局中断。
4.初始化LCD显示屏,并显示图片和字符串欢迎语。
5.初始化触摸板,并通过LCD显示和串口打印触摸提示。
触摸板FT6236的初始化比较简单,分为硬件初始化和软件初始化,软件初始化主要是设置FT6236的寄存器,唤醒FT6236设置触摸灵敏度和扫描周期。
6.硬件引脚初始化,主要是修改触摸板复位引脚的电平,这里与屏幕使用同一个复位引脚,所以不需要再复位操作。再设置FT_INT中断引脚为输入,中断回调函数为ft6236_isr_cb,并在中断函数中修改触摸屏的状态。
7.FT6236通过I2C通讯的方式来读和写数据,以下是触摸板I2C控制的函数:
初始化I2C,设置从机地址,数据位宽度,I2C通讯速率等,
向寄存器reg写入一个数据data ,写入成功返回0,失败则返回非0,
从寄存器reg读取length个数据保存到data_buf,读取成功返回0,失败则返回非0。
8.main函数里最后是一个while(1)循环,读取触摸屏的坐标XY值,然后通过串口打印出来,再显示到LCD显示屏上。每次显示完成后都需要刷新以下显示的位置,否则旧数据会重叠到一起,所以lcd_clear_coord函数就是清除坐标的作用。
9.先使用lcd_set_area函数设定显示坐标的区域,然后再写入白色的值(0XFFFFFFFF),以此来刷新显示的内容。如果背景图片的坐标区域不是空白的,则无法使用此方法来刷新。
10.编译调试,烧录运行
把本课程资料中的touch复制到SDK中的src目录下,然后进入build目录,运行以下命令编译。
cmake .. -DPROJ=touch -G “MinGW Makefiles”
make
编译完成后,在build文件夹下会生成touch.bin文件。
使用type-C数据线连接电脑与K210开发板,打开kflash,选择对应的设备,再将程序固件烧录到K210开发板上。
五、实验现象
烧录完成固件后,系统会弹出一个终端界面,如果没有弹出终端界面的可以打开串口助手显示调试内容。
打开电脑的串口助手,选择对应的K210开发板对应的串口号,波特率设置为115200,然后点击打开串口助手。注意还需要设置一下串口助手的DTR和RTS。在串口助手底部此时的4.DTR和7.RTS默认是红色的,点击4.DTR和7.RTS,都设置为绿色,然后按一下K210开发板的复位键。
LCD屏幕会显示图片,一秒后打印出“Hello Yahboom!” “Nice to meet you!”的欢迎语。然后打印提示触摸语“Please touch the screen to get coord!”同时串口也会打印出“Hi!Please touch the screen to get coordinates!”的提示语。
同时LCD显示屏上也会显示当前触摸的坐标,当松开手时,坐标也会消失。每次移动手指,改变触摸的位置,对应的触摸点坐标也会改变。
六、实验总结
1.K210开发板的触摸屏是电容式触摸屏,可以使用手指直接触摸使用。
2.触摸板使用的是I2C通讯,读取数据后需要转化计算一下才能得到实际的触摸坐标。
3.触摸板的相关寄存器放在项目的README.md文件中,具体寄存器功能请查看硬件相关资料中的触摸屏资料。
附:API对应的头文件 i2c.h
i2c_init
描述
配置 I²C 器件从地址、寄存器位宽度和 I²C 速率。
函数原型
void i2c_init(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width, uint32_t i2c_clk)
参数
参数名称 | 描述 | 输入输出 |
i2c_num | I²C号 | 输入 |
slave_address | I²C 器件从地址 | 输入 |
address_width | I²C 器件寄存器宽度(7或10) | 输入 |
i2c_clk | I²C 速率 (Hz) | 输入 |
返回值
无。
i2c_init_as_slave
描述
配置 I²C 为从模式。
函数原型
void i2c_init_as_slave(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width, const i2c_slave_handler_t *handler)
参数
参数名称 | 描述 | 输入输出 |
i2c_num | I²C号 | 输入 |
slave_address | I²C 从模式的地址 | 输入 |
address_width | I²C 器件寄存器宽度(7或10) | 输入 |
handler | I²C 从模式的中断处理函数 | 输入 |
返回值
无。
i2c_send_data
描述
写数据。
函数原型
int i2c_send_data(i2c_device_number_t i2c_num, const uint8_t *send_buf, size_t send_buf_len)
参数
参数名称 | 描述 | 输入输出 |
i2c_num | I²C号 | 输入 |
send_buf | 待传输数据 | 输入 |
send_buf_len | 待传输数据长度 | 输入 |
返回值
返回值 | 描述 |
0 | 成功 |
非0 | 失败 |
i2c_send_data_dma
描述
通过DMA写数据。
函数原型
void i2c_send_data_dma(dmac_channel_number_t dma_channel_num, i2c_device_number_t i2c_num, const uint8_t *send_buf, size_t send_buf_len)
参数
参数名称 | 描述 | 输入输出 |
dma_channel_num | 使用的dma通道号 | 输入 |
i2c_num | I²C号 | 输入 |
send_buf | 待传输数据 | 输入 |
send_buf_len | 待传输数据长度 | 输入 |
返回值
无
i2c_recv_data
描述
通过CPU读数据。
函数原型
int i2c_recv_data(i2c_device_number_t i2c_num, const uint8_t *send_buf, size_t send_buf_len, uint8_t *receive_buf, size_t receive_buf_len)
参数
参数名称 | 描述 | 输入输出 |
i2c_num | I²C 总线号 | 输入 |
send_buf | 待传输数据,一般情况是i2c外设的寄存器,如果没有设置为NULL | 输入 |
send_buf_len | 待传输数据长度,如果没有则写0 | 输入 |
receive_buf | 接收数据内存 | 输出 |
receive_buf_len | 接收数据的长度 | 输入 |
返回值
返回值 | 描述 |
0 | 成功 |
非0 | 失败 |
i2c_recv_data_dma
描述
通过dma读数据。
函数原型
void i2c_recv_data_dma(dmac_channel_number_t dma_send_channel_num, dmac_channel_number_t dma_receive_channel_num, i2c_device_number_t i2c_num, const uint8_t *send_buf, size_t send_buf_len, uint8_t *receive_buf, size_t receive_buf_len)
参数
参数名称 | 描述 | 输入输出 |
dma_send_channel_num | 发送数据使用的dma通道 | 输入 |
dma_receive_channel_num | 接收数据使用的dma通道 | 输入 |
i2c_num | I²C 总线号 | 输入 |
send_buf | 待传输数据,一般情况是i2c外设的寄存器,如果没有设置为NULL | 输入 |
send_buf_len | 待传输数据长度,如果没有则写0 | 输入 |
receive_buf | 接收数据内存 | 输出 |
receive_buf_len | 接收数据的长度 | 输入 |
返回值
无
i2c_handle_data_dma
描述
I2C 使用dma传输数据。
函数原型
void i2c_handle_data_dma(i2c_device_number_t i2c_num, i2c_data_t data, plic_interrupt_t *cb);
参数
参数名称 | 描述 | 输入输出 |
i2c_num | I²C 总线号 | 输入 |
data | I2C数据相关的参数,详见i2c_data_t说明 | 输入 |
cb | dma中断回调函数,如果设置为NULL则为阻塞模式,直至传输完毕后退出函数 | 输入 |
返回值
无
举例
/* i2c外设地址是0x32, 7位地址,速率200K */i2c_init(I2C_DEVICE_0, 0x32, 7, 200000);uint8_t reg = 0;uint8_t data_buf[2] = {0x00,0x01}data_buf[0] = reg;/* 向0寄存器写0x01 */i2c_send_data(I2C_DEVICE_0, data_buf, 2);i2c_send_data_dma(DMAC_CHANNEL0, I2C_DEVICE_0, data_buf, 4);/* 从0寄存器读取1字节数据 */i2c_receive_data(I2C_DEVICE_0, ®, 1, data_buf, 1);i2c_receive_data_dma(DMAC_CHANNEL0, DMAC_CHANNEL1, I2C_DEVICE_0,®, 1, data_buf, 1);
数据类型
相关数据类型、数据结构定义如下:
· i2c_device_number_t:i2c号。
· i2c_slave_handler_t:i2c从模式的中断处理函数句柄
· i2c_data_t:使用dma传输时数据相关的参数。
· i2c_transfer_mode_t:使用DMA传输数据的模式,发送或接收。
i2c_device_number_t
描述
i2c编号。
定义
typedef enum _i2c_device_number{ I2C_DEVICE_0, I2C_DEVICE_1, I2C_DEVICE_2, I2C_DEVICE_MAX,} i2c_device_number_t;
i2c_slave_handler_t
描述
i2c从模式的中断处理函数句柄。根据不同的中断状态执行相应的函数操作。
定义
typedef struct _i2c_slave_handler{ void(*on_receive)(uint32_t data); uint32_t(*on_transmit)(); void(*on_event)(i2c_event_t event);} i2c_slave_handler_t;
成员
成员名称 | 描述 |
I2C_DEVICE_0 | I2C 0 |
I2C_DEVICE_1 | I2C 1 |
I2C_DEVICE_2 | I2C 2 |
i2c_data_t
描述
使用dma传输时数据相关的参数。
定义
typedef struct _i2c_data_t{ dmac_channel_number_t tx_channel; dmac_channel_number_t rx_channel; uint32_t *tx_buf; size_t tx_len; uint32_t *rx_buf; size_t rx_len; i2c_transfer_mode_t transfer_mode;} i2c_data_t;
成员
成员名称 | 描述 |
tx_channel | 发送时使用的DMA通道号 |
rx_channel | 发送时使用的DMA通道号 |
tx_buf | 发送的数据 |
tx_len | 发送数据的长度 |
rx_buf | 接收的数据 |
rx_len | 接收数据长度 |
transfer_mode | 传输模式,发送或接收 |
i2c_transfer_mode_t
描述
使用DMA传输数据的模式,发送或接收。
定义
typedef enum _i2c_transfer_mode{ I2C_SEND, I2C_RECEIVE,} i2c_transfer_mode_t;
成员
成员名称 | 描述 |
I2C_SEND | 发送 |
I2C_RECEIVE | 接收 |