之前玩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使用电容屏,从查询改为中断相关推荐

  1. 单片机设计 游戏_五子棋+黄金矿工+贪吃蛇(STM32、4.3寸电容屏)

    单片机设计 游戏_五子棋+黄金矿工+贪吃蛇(STM32.4.3寸电容屏) 想要更多项目私wo!!! 一.电路设计 此电路由STM32F1精英版和4.3寸电容屏TFTLCD组成. 二.运行效果 三.部分 ...

  2. linux下移植电容屏驱动gt9xx 笔记

    # evtest /dev/event0 或者 # hexdump /dev/event0// 分析: \drivers\i2c\busses\I2c-digicolor.c static struc ...

  3. 嵌入式系统学习——STM32之电容型触摸屏

    触摸屏 触摸屏(touch screen)又称为"触控屏"."触控面板",是一种可接收触头等输入讯号的感应式装置.作为一种新型的电脑输入设备,可以用来取代传统的 ...

  4. android 电容屏(三):驱动调试之驱动程序分析篇

    平台信息: 内核:linux3.4.39 系统:android4.4  平台:S5P4418(cortex a9) 作者:瘋耔(欢迎转载,请注明作者) 欢迎指正错误,共同学习.共同进步!! 关注博主新 ...

  5. S3C2416裸机开发系列十三_电容屏驱动实现

    S3C2416裸机开发系列十三 电容屏驱动实现 象棋小子    1048272975 在人机交互系统中,键盘.触摸屏等输入设备是一个不可或缺的部分.对于手机.平板这些消费类电子而言,触摸屏以其非常良好 ...

  6. android 电容屏驱动调试

    一.总体架构 硬件部分:先看一个总体的图吧,其实触摸屏原理也比较简单,触摸屏和主控芯片间的联系,如下主要有三部分: 1.IIC部分,初始化gt8105的数据和传回主控制的坐标位置信息就是通过IIC这条 ...

  7. gt9xx电容屏驱动分析

    电容屏驱动调试先了解Linux电容屏驱动中几个常用的概念:              中断下半部-工作队列:              input机制:              Linux与Andr ...

  8. 鸿合一体机触屏没反应怎么办_【干货】嵌入式工控一体机选择电容屏还是电阻屏?...

    随着触屏手机和工业触摸一体机在近几年里的不断主流化,触屏的概念已渐渐深入人心,但是你知道吗?我们的触屏是有分电阻屏和电容屏的,那你又知道电阻屏和电容屏有什么区别吗?你的手机又是什么屏的吗?下面我们就来 ...

  9. FT5X06 如何应用在10寸电容屏(linux-3.5电容屏驱动简析移植10寸电容屏驱动到Android4.2) (by liukun321咕唧咕唧)

    这是几个月以前的东西了,在彻底遗忘之前拿出来好好写写.做个笔记,也算是造福后来人了.在做这个项目之前,没有做过电容屏的驱动,印象中的电容触摸屏是不需要校正的.IC支持多大的屏就要配多大的屏.但是拿到需 ...

最新文章

  1. c语言通讯录打电话,C语言实现简易通讯录 | 术与道的分享
  2. 确定神经网络层数以及神经元个数
  3. POJ-1125 Stockbroker Grapevine 最短路
  4. 分布式事务科普(初识篇)
  5. 如何从单个服务器扩展到百万用户的系统?
  6. Android—Retrofit解析
  7. python渐变色代码_如何在Python中创建颜色渐变?
  8. makefile编译问题记录
  9. 使用80percent开发rails程序:gem的了解。(kaminari)
  10. 是时候使用Markdown写作了
  11. 系统错误计算机中丢失文件,电脑文件丢失了怎么办?电脑文件丢失原因以及解决方法都在这了!...
  12. 光盘都无法识别解决方法
  13. java 最后的异常_关于java:异常处理尝试没有catch,但最后
  14. 绕口令:《舌头是怎样练成的》
  15. 栈的实现(C语言版)
  16. “专精特新”背后的京东动力
  17. android word分页,控制分页
  18. (三十九)期权定价的二叉树法
  19. pcm转mp3_【新】PC语音转文字/音频视频都能转!
  20. Linux发行版镜像地址

热门文章

  1. Eureka集群配置
  2. TRIZ系列-创新原理-36-状态转变原理
  3. 【verilog】计数器
  4. 获取百度地图商圈,小区边界
  5. CRM项目记录(五)
  6. php教程适合高中生学吗,高中生请进 - 高一 - 简单学习网论坛_中高考学习交流论坛_中学生学习论坛 - Powered by phpwind...
  7. 点选式图片验证码的一种实现效果
  8. 【Keras-MLP】IMDb
  9. c 连接oracle数据库字符串,C#数据库连接字符串 - 水泛舟的专栏 - CSDN博客
  10. Dictionary I