CubeMX移植触摸屏
对于触摸屏,看到这篇文章的你想必应该也接触了有个十来年了。早在iphone问世之前,电阻式触摸屏就已经相当普及,不少人应该还有当时从手机边缘拿出配套的触控笔通过写字来手写输入的画面感。这种通过按压使屏幕内电阻改变从而定位的屏幕就是电阻屏。而自从iphone问世以来,对于移动手机而言使用电容屏已经成为了理所当然:多点触控、灵敏感应、屏幕损伤小等优势,无不成为了电容屏后来居上的关键理由。当然,两种技术的适用场合与特点各有风味,并没有绝对的优劣之分,只不过对于智能手机的适用场合而言,电容屏更适合于普通用户的一般使用环境与需求,而对于成本受限、高精度、环境较恶劣的场合,电阻屏则自然也有其无法替代的优势所在。
原理简述
简单来说,电阻屏的原理是通过按压不同位置改变电路在X、Y轴电阻值的方式实现定位的。附上野火在电阻触摸屏章节的一张教程图片:
而电容屏,则是人体触摸时改变触电局部电容实现定位的:
详细内容与解释在教程文档的相关章节都有所提及,网络上也有不少有关这块的学习资料,在这就不细节展开了。
引脚资源
触摸屏引脚
图 31.2.1为触摸屏与 STM32 的连接图,从图中可以看出,T_MISO、T_PEN、T_CS、T_MOSI 和 T_SCK 分别连接在 STM32 的:PF8
、PF10
、 PB2
、PF9
和 PB1
上。
对于电阻屏,正点原子的触摸屏驱动采用的是软件仿真SPI时序,因此实际上看到的T_MISO、T_CS、T_MOSI 和 T_SCK 为模拟的SPI控制信号,而T_PEN作为中断信号,用于扫描触摸屏是否被按下。
IIC引脚
以下摘自正点原子开发指南:
ST 为了规避飞利浦 IIC 专利问题,将 STM32 的硬件 IIC 设计的比较复杂,而且稳定性不怎么好,所以这里我们不推荐使用。有兴趣的读者 可以研究一下 STM32F1 的硬件 IIC。 用软件模拟 IIC,最大的好处就是方便移植,同一个代码兼容所有 MCU,任何一个单片机 只要有 IO 口,就可以很快的移植过去,而且不需要特定的 IO 口。而硬件 IIC,则换一款 MCU, 基本上就得重新搞一次,移植是比较麻烦的,这也是我们推荐使用软件模拟 IIC 的另外一个原因。
因此,实际上正点原子的IIC驱动使用的都是用GPIO口进行软件模拟。因此从开发难易度角度考虑,推荐直接配置GPIO使用软件IIC的方式进行通信。
战舰V2使用到24C02存储触摸定位数据,需要使用IIC通信,管脚放在硬件IIC的对应位置,即PB10
、PB11
的IIC管脚处的GPIO。由于软件IIC的应用场合通常不涉及多主多从下推挽输出所导致的主设备短路可能,因此模式选择普通的推挽输出
即可。
我使用的开发板为战舰V2,24C02连接的位置为内置IIC2的引脚PB10、PB11处,型号较早;对于比较新的战舰V3开发板,24C02连接的是IIC1的引脚PB6、PB7处,因此移植例程时一定注意下配套例程是不是自己的开发板型号,不是的话注意管脚配置要根据实际板子的原理图来进行移植配置。
KEY引脚
按键用于控制清空24C02数据进行强制触摸校准,例程所使用的按键为KEY0(KEY_RIGHT),对应原理图管脚PE4
,由于是按键输入因此模式设为输入。根据原理图,除WK_UP按键接3.3V的VCC电源高电平有效外,KEY0、KEY1、KEY2均接GND低电平有效。由于外部电路中是没有上下拉电阻,因此除WK_UP应设下拉输入使初始为低电平外,其余均为上拉输入
以保证初态无效。
STM32F103(库函数)——按键检测_Xiaomo-CSDN博客
CubeMX配置
配置触摸屏
由于触摸屏通过软件SPI进行通讯,且由MCU控制触摸屏,因此T_MISO
应为上拉输入
,T_SCK
与T_MOSI
应设为上拉推挽输出
。驱动中T_CS
为低电平有效,因此应设为上拉推挽输出
。 T_PEN
用于判断校准按键产生中断,低电平有效,因此设为上拉输入
。由于SPI通讯速度要求,速度均选择高速
。
配置IIC
因为使用GPIO软件模拟IIC,GPIO速度有较高要求,IIC_SCL
和IIC_SDA
选择高速推挽输出
。
配置KEY
例程使用按键为KEY0,由原理图接地因此设为上拉输入
即可。若设为KEY1、KEY2,同样为上拉输入;若为KEY_UP,由于接3.3V的VCC应设为下拉输入。
配置参考
图为我的CubeMX配置,基于战舰V2开发板,请根据自己型号的原理图与引脚资源进行配置。
对于CubeMX配置不熟悉的读者可以参考一下前一篇关于LCD移植的文章,包含一定的基础配置知识。
代码配置
移植TOUCH、IIC、24CXX、KEY文件
文件简析
ALIENTEK 2.4/2.8/3.5 寸 TFTLCD 模块自带的触摸屏都属于电阻式触摸屏,ALIENTEK TFTLCD 模块自带的触摸屏控制芯片为 XPT2046。电容触摸屏一般都需要一个驱动 IC 来检测电容触摸,且一般是通过 IIC 接口输出触摸数据。
TOUCH文件包含TOUCH、ctiic、ott2001a、ft5206、gt9147对应的.c与.h文件。
touch.c 和 touch.h 是电阻触摸屏部分的代码,如软件模拟SPI时序、采集触摸数据,顺带兼电容触摸屏的管理控制根据lcd型号进行电容芯片与触摸屏的驱动判断,管脚初始化。
ctiic为电容触摸芯片IIC驱动,ott2001a、ft5206、gt9147为不同电容芯片IC的驱动。
KEY.c驱动按键,用于手动进行电阻屏校准(电容屏无需校准)。
IIC用于驱动24C02,24CXX驱动24C02的EEPROM,用于存储触摸屏的校准参数。
由野火资料,
XPT2046 芯片控制 4 线电阻触摸屏,STM32 与 XPT2046 采用 SPI 通讯获取采集得的电压,然后
转换成坐标。
XPT2046 是专用在四线电阻屏的触摸屏控制器,STM32 可通过 SPI 接口向它写入控制字,由它
测得 X、Y 方向的触点电压返回给 STM32。
因此,实际上电阻屏所使用的驱动只在TOUCH.c与TOUCH.h文件中,与ctiic、ott2001a、ft5206、gt9147等文件都无关,因此已知自己触摸屏类型为电阻屏时,移植其他文件不需要额外的改动。
对于电容屏而言,正点原子的不同尺寸电容屏采用了不同型号的控制芯片,即上述的ott2001a、ft5206、gt9147,此外还使用了ctiic.c软件模拟IIC作为电容触摸芯片IIC驱动。通过查看正点原子的触摸屏驱动文件,可以发现实际上电阻屏在TP_Init()
触摸屏初始化函数中进行了管脚配置,而电容屏的配置则是在自己对应的驱动文件与芯片IIC驱动中进行相应的配置。在通过CubeMX进行配置后,记得根据自己实际的触摸屏类型与芯片类型注释掉相应的配置代码。
文件修改
TOUCH文件
电阻屏:注释掉TOUCH.c中TP_Init()
引脚配置相关代码,修改TOUCH.h中定义管脚标识符中引脚配置为实际对应的引脚。
电容屏:注释掉ctiic.c中CT_IIC_Init()
引脚配置相关代码,ft5206.c中FT5206_Init()
,gt9147.c中GT9147_Init()
,ott2001a.c中OTT2001A_Init()
相关引脚配置代码,修改以上对应.h文件中定义管脚标识符中引脚配置为实际对应的引脚。
IIC文件
注释掉myiic.c中IIC_Init()
引脚配置相关代码。
KEY文件
注释掉key.c中KEY_Init()
引脚配置相关代码。
Main.c
添加使用到的头文件
/* USER CODE BEGIN Includes */
#include "key.h"
#include "24cxx.h"
#include "touch.h"
/* USER CODE END Includes */
添加调试使用到的相关函数(篇幅原因仅保留函数名,内容省略,代码在开发板对应例程中都有)
/* USER CODE BEGIN 0 */
//清空屏幕并在右上角显示"RST"
void Load_Drow_Dialog(void)
{
···
}
////////////////////////////////////////////////////////////////////////////////
//电容触摸屏专有部分
//画水平线
//x0,y0:坐标
//len:线长度
//color:颜色
void gui_draw_hline(u16 x0,u16 y0,u16 len,u16 color)
{
···
}
//画实心圆
//x0,y0:坐标
//r:半径
//color:颜色
void gui_fill_circle(u16 x0,u16 y0,u16 r,u16 color)
{
···
}
//两个数之差的绝对值
//x1,x2:需取差值的两个数
//返回值:|x1-x2|
u16 my_abs(u16 x1,u16 x2)
{
···
}
//画一条粗线
//(x1,y1),(x2,y2):线条的起始坐标
//size:线条的粗细程度
//color:线条的颜色
void lcd_draw_bline(u16 x1, u16 y1, u16 x2, u16 y2,u8 size,u16 color)
{
···
}
////////////////////////////////////////////////////////////////////////////////
//5个触控点的颜色(电容触摸屏用)
const u16 POINT_COLOR_TBL[5]={RED,GREEN,BLUE,BROWN,GRED};
//电阻触摸屏测试函数
void rtp_test(void)
{
···
}
//电容触摸屏测试函数
void ctp_test(void)
{
···
}
/* USER CODE END 0 */
主函数中调用触摸屏初始化函数
/* USER CODE BEGIN 2 */
tp_dev.init(); //触摸屏初始化
/* USER CODE END 2 */
主函数中添加调试触摸屏相关代码
```c
/* USER CODE BEGIN 3 */
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"WarShip STM32");
LCD_ShowString(30,70,200,16,16,"TOUCH TEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2019/9/19");
if(tp_dev.touchtype!=0XFF)
{
LCD_ShowString(30,130,200,16,16,"Press KEY0 to Adjust");//电阻屏才显示
}
delay_ms(1500);
Load_Drow_Dialog();
if(tp_dev.touchtype&0X80)ctp_test();//电容屏测试
else rtp_test(); //电阻屏测试
/* USER CODE END 3 */
例程中实际上还采用了LED灯珠作为触摸周期的反馈信号之一,作用不是非常大,因此可以不做移植,将例程中LED状态转换部分代码注释即可。
以上,触摸屏的移植部分也就完成了。编译程序下载到板子中,观察一下是否可以进行正常绘图即可知道我们的移植是否成功。下一篇文章不出意外则主要记录有关GUI界面emwin的移植过程。
本文为原创个人开发学习过程的记录总结,难免存在不少错误与疏忽,欢迎留言或通过社交媒体联系我指出问题,也欢迎在评论中留下您的建议与见解,或是贴上中意的优质文章链接。
更好的车轮,更远的里程。
参考资料
STM32F1 开发指南 V1.0 - HAL 库版本 −ALIENTEK 战舰 STM32F103 V3 开发板教程
STM32F1 开发指南 V1.3 - 库函数版本 −ALIENTEK 战舰 STM32F103 V2 开发板教程
STM32 HAL 库开发实战指南 —基于野火 F103 霸道开发板