STM32使用电容屏,从查询改为中断
之前玩arm都是电阻屏,但是电容屏更加通用,这次拿ALIENTEK 4.3’LCD进行学习,里面有GT9147驱动IC(相当于控制触摸屏的一个小芯片)
把源码进行修改,从官方给的查询模式触发,变成中断触发,源码可下载,另带找到的芯片手册
找到的资源,和编写好的中断代码
关于电容屏
有自我电容和交互电容
我们一般用的是投射电容式触摸屏里面的交互电容
原理
自我电容:
在玻璃表面有用 ITO 制成的横向与纵向的扫描电极,这些电极和地之间就构成一个电
容的两极。当用手或触摸笔触摸的时候就会并联一个电容到电路中去,从而使在该条扫描线上
的总体的电容量有所改变,就能检测出来什么地方电容改变
用在笔记本电脑上的触摸屏上
交互电容:
交互电容又叫做跨越电容,它是在玻璃表面的横向和纵向的 ITO 电极的交叉处形成电容。
交互电容的扫描方式就是扫描每个交叉处的电容变化,来判定触摸点的位置。
用在平板电脑和手机上
所以电容屏和电阻屏相比电容屏
优点:手感好、无需校准、支持多点触摸、透光性好。
缺点:成本高、精度不高、抗干扰能力差(要在良好的环境下才能工作)。
操控电容屏
我们用MCU通过四根线进行IIC的数据传输来对驱动IC进行读取,可以得到此时触摸屏上返回的数据
四条线 :SDA、SCL、RST 和 INT
SDA 和 SCL 作为 IIC通信
RST复位引脚(低电平有效)
INT中断输出信号
硬件连接
PH7 = INT , PI8 =RST , PI3=SDA ,
找到电容屏地址
我们的IIC传输数据是八位的,所以在datasheet里面找到地址说明,个人推断地址线应该要照着上面进行连接
所以我们要对电容屏进行地址设置
用这段代码确定地址
u8 temp[5]; RCC->AHB1ENR|=1<<7; //使能PORTH时钟 RCC->AHB1ENR|=1<<8; //使能PORTI时钟 GPIO_Set(GPIOH,PIN7,GPIO_MODE_IN,0,0,GPIO_PUPD_PU); //PH7设置为上拉输入GPIO_Set(GPIOI,PIN8,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//PI8设置为推挽输出CT_IIC_Init(); //初始化电容屏的I2C总线 GT_RST=0; //复位delay_ms(10);GT_RST=1; //释放复位 delay_ms(10); GPIO_Set(GPIOH,PIN7,GPIO_MODE_IN,0,0,GPIO_PUPD_NONE);//PH7设置为浮空输入delay_ms(100);
对电容屏进行数据读取
读就复杂点:start信号–>电容屏地址写信号–>寄存器地址高八位–>寄存器地址低八位
–>start信号–>电容屏地址读信号–>一直读就返回ACK,不读返回NACK
reg:起始寄存器地址
buf:数据缓缓存区
len:读数据长度
void GT9147_RD_Reg(u16 reg,u8 *buf,u8 len)
{u8 i; CT_IIC_Start(); CT_IIC_Send_Byte(GT_CMD_WR); //发送写命令 CT_IIC_Wait_Ack();CT_IIC_Send_Byte(reg>>8); //发送高8位地址CT_IIC_Wait_Ack(); CT_IIC_Send_Byte(reg&0XFF); //发送低8位地址CT_IIC_Wait_Ack(); CT_IIC_Start(); CT_IIC_Send_Byte(GT_CMD_RD); //发送读命令 CT_IIC_Wait_Ack(); for(i=0;i<len;i++){ buf[i]=CT_IIC_Read_Byte(i==(len-1)?0:1); //发数据 } CT_IIC_Stop();//产生一个停止条件
}
对电容屏进行数据写入
start信号–>带写信号的电容屏地址–>寄存器地址高位—>寄存器地址低位–>多个数据
reg:起始寄存器地址
buf:数据缓缓存区
len:写数据长度
u8 GT9147_WR_Reg(u16 reg,u8 *buf,u8 len)
{u8 i;u8 ret=0;CT_IIC_Start(); CT_IIC_Send_Byte(GT_CMD_WR); //发送写命令 CT_IIC_Wait_Ack();CT_IIC_Send_Byte(reg>>8); //发送高8位地址CT_IIC_Wait_Ack(); CT_IIC_Send_Byte(reg&0XFF); //发送低8位地址CT_IIC_Wait_Ack(); for(i=0;i<len;i++){ CT_IIC_Send_Byte(buf[i]); //发数据ret=CT_IIC_Wait_Ack();if(ret)break; }CT_IIC_Stop(); //产生一个停止条件 return ret;
}
使用电容屏
更新配置
从寄存器里面读取版本号 看看我们的有没有更新信息
当发现版本较低时,开始我们的更新,好像就是把新的序列码写上去(厂家提供,说实话找了半天也不知道哪来的)
对我们的电容屏进行跟新前版本号检验
for(i=0;i<sizeof(GT9147_CFG_TBL);i++)buf[0]+=GT9147_CFG_TBL[i];//计算校验和
把之前厂家提供的序列码依次写入个个寄存器,让厂家帮配置,把所有的补码进行校验,并且配置更新标记
这样我们的电容屏也就初始化好啦
使用查询方式知道有无按下触摸屏
我们电容屏只支持最高5点触碰,所以number of touch points 要小于6 ,并且buffer status为1,表明有触碰
用mode保存数据,清空寄存器,方便下一次读取
假如有3点按下 sta = 0xFF07|0x80|0x40 =0xFFC7 这个很精妙,是源码里给的结构体
对按下的点进行记录和判断
从寄存器里读取数值保存进buf里
并且对数据进行判断,看是否超出了lcd的数值
开始进行划线
//电容触摸屏测试函数
void ctp_test(void)
{u8 t=0;u8 i=0; u16 lastpos[10][2]; //最后一次的数据 u8 maxp=5;//最多画5个点if(lcddev.id==0X1018)maxp=10;while(1){tp_dev.scan(0);for(t=0;t<maxp;t++){if((tp_dev.sta)&(1<<t)){if(tp_dev.x[t]<lcddev.width&&tp_dev.y[t]<lcddev.height)//不超出范围{if(lastpos[t][0]==0XFFFF){lastpos[t][0] = tp_dev.x[t];lastpos[t][1] = tp_dev.y[t];}lcd_draw_bline(lastpos[t][0],lastpos[t][1],tp_dev.x[t],tp_dev.y[t],2,POINT_COLOR_TBL[t]);//一个个点连接画线lastpos[t][0]=tp_dev.x[t];lastpos[t][1]=tp_dev.y[t];if(tp_dev.x[t]>(lcddev.width-24)&&tp_dev.y[t]<20){Load_Drow_Dialog();//点击res清屏幕}}}else lastpos[t][0]=0XFFFF;} delay_ms(5);i++;if(i%20==0)LED0=!LED0;}
}
把电容屏从查询模式改为中断模式
重新设置中断引脚INT
GPIO_Initure.Pin=GPIO_PIN_7; //PH7GPIO_Initure.Mode=GPIO_MODE_IT_RISING; //输入GPIO_Initure.Pull=GPIO_PULLDOWN; //不带上下拉,浮空输入GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速HAL_GPIO_Init(GPIOH,&GPIO_Initure); //初始化HAL_NVIC_SetPriority(EXTI9_5_IRQn,2,0); //抢占优先级为2,子优先级为0HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); //使能中断线0
用自带的中断处理函数
void EXTI9_5_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);//调用中断处理公用函数
}
把之前的查询函数改为中断处理函数–>callback函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{u8 mode=0,temp=0,i,buf[4];static u16 lastpos[5][2]; //最后一次的数据 GT9147_RD_Reg(GT_GSTID_REG,&mode,1); //读取触摸点的状态 if(mode&0X80&&((mode&0XF)<6)){temp=0;GT9147_WR_Reg(GT_GSTID_REG,&temp,1);//清标志 } if((mode&0XF)&&((mode&0XF)<6)){for(i=0;i<(mode&0XF);i++){GT9147_RD_Reg(GT9147_TPX_TBL[i],buf,4); //读取XY坐标值tp_dev.x[i]=((u16)buf[1]<<8)+buf[0];tp_dev.y[i]=((u16)buf[3]<<8)+buf[2];if(tp_dev.x[i]<lcddev.width&&tp_dev.y[i]<lcddev.height){ lcd_draw_bline(lastpos[i][0],lastpos[i][1],tp_dev.x[i],tp_dev.y[i],2,POINT_COLOR_TBL[i]);//画线lastpos[i][0]=tp_dev.x[i];lastpos[i][1]=tp_dev.y[i];if(tp_dev.x[i]>(lcddev.width-24)&&tp_dev.y[i]<20){Load_Drow_Dialog();//清除} } } }
}
STM32使用电容屏,从查询改为中断相关推荐
- 单片机设计 游戏_五子棋+黄金矿工+贪吃蛇(STM32、4.3寸电容屏)
单片机设计 游戏_五子棋+黄金矿工+贪吃蛇(STM32.4.3寸电容屏) 想要更多项目私wo!!! 一.电路设计 此电路由STM32F1精英版和4.3寸电容屏TFTLCD组成. 二.运行效果 三.部分 ...
- linux下移植电容屏驱动gt9xx 笔记
# evtest /dev/event0 或者 # hexdump /dev/event0// 分析: \drivers\i2c\busses\I2c-digicolor.c static struc ...
- 嵌入式系统学习——STM32之电容型触摸屏
触摸屏 触摸屏(touch screen)又称为"触控屏"."触控面板",是一种可接收触头等输入讯号的感应式装置.作为一种新型的电脑输入设备,可以用来取代传统的 ...
- android 电容屏(三):驱动调试之驱动程序分析篇
平台信息: 内核:linux3.4.39 系统:android4.4 平台:S5P4418(cortex a9) 作者:瘋耔(欢迎转载,请注明作者) 欢迎指正错误,共同学习.共同进步!! 关注博主新 ...
- S3C2416裸机开发系列十三_电容屏驱动实现
S3C2416裸机开发系列十三 电容屏驱动实现 象棋小子 1048272975 在人机交互系统中,键盘.触摸屏等输入设备是一个不可或缺的部分.对于手机.平板这些消费类电子而言,触摸屏以其非常良好 ...
- android 电容屏驱动调试
一.总体架构 硬件部分:先看一个总体的图吧,其实触摸屏原理也比较简单,触摸屏和主控芯片间的联系,如下主要有三部分: 1.IIC部分,初始化gt8105的数据和传回主控制的坐标位置信息就是通过IIC这条 ...
- gt9xx电容屏驱动分析
电容屏驱动调试先了解Linux电容屏驱动中几个常用的概念: 中断下半部-工作队列: input机制: Linux与Andr ...
- 鸿合一体机触屏没反应怎么办_【干货】嵌入式工控一体机选择电容屏还是电阻屏?...
随着触屏手机和工业触摸一体机在近几年里的不断主流化,触屏的概念已渐渐深入人心,但是你知道吗?我们的触屏是有分电阻屏和电容屏的,那你又知道电阻屏和电容屏有什么区别吗?你的手机又是什么屏的吗?下面我们就来 ...
- FT5X06 如何应用在10寸电容屏(linux-3.5电容屏驱动简析移植10寸电容屏驱动到Android4.2) (by liukun321咕唧咕唧)
这是几个月以前的东西了,在彻底遗忘之前拿出来好好写写.做个笔记,也算是造福后来人了.在做这个项目之前,没有做过电容屏的驱动,印象中的电容触摸屏是不需要校正的.IC支持多大的屏就要配多大的屏.但是拿到需 ...
最新文章
- c语言通讯录打电话,C语言实现简易通讯录 | 术与道的分享
- 确定神经网络层数以及神经元个数
- POJ-1125 Stockbroker Grapevine 最短路
- 分布式事务科普(初识篇)
- 如何从单个服务器扩展到百万用户的系统?
- Android—Retrofit解析
- python渐变色代码_如何在Python中创建颜色渐变?
- makefile编译问题记录
- 使用80percent开发rails程序:gem的了解。(kaminari)
- 是时候使用Markdown写作了
- 系统错误计算机中丢失文件,电脑文件丢失了怎么办?电脑文件丢失原因以及解决方法都在这了!...
- 光盘都无法识别解决方法
- java 最后的异常_关于java:异常处理尝试没有catch,但最后
- 绕口令:《舌头是怎样练成的》
- 栈的实现(C语言版)
- “专精特新”背后的京东动力
- android word分页,控制分页
- (三十九)期权定价的二叉树法
- pcm转mp3_【新】PC语音转文字/音频视频都能转!
- Linux发行版镜像地址