欢迎来到亿配芯城! | 免费注册
你的位置:JSCJ长晶科技CJ(JCET长电科技)-亿配芯城 > 芯片资讯 > 使用ADC控制4线电阻触摸屏
使用ADC控制4线电阻触摸屏
发布日期:2024-09-01 08:24     点击次数:120

一、触摸屏操作原理 

  电阻触摸屏利用压力感应进行控制。电阻触摸屏的主要部分是一块与显示器表面非常配合的电阻薄膜屏,这是一种多层的复合薄膜,它以一层玻璃或硬塑料平板作为基层,表面涂有一层透明氧化金属(透明的导电电阻)导电层,上面再盖有一层外表面硬化处理、光滑防擦的塑料层,它的内表面也涂有一层涂层,在他们之间有许多细小的(小于1/1000英寸)的透明隔离点把两层导电层隔开绝缘。当手指触摸屏幕时,两层导电层在触摸点位置就有了接触,电阻发生变化,在X和Y两个方向上产生信号,然后送触摸屏控制器。控制器侦测到这一接触并计算出(X,Y)的位置,再根据模拟鼠标的方式运作。这就是广东ic网交易网要说的电阻技术触摸屏的最基本的原理。 

 

二、驱动电阻触摸屏的实现

  MCU的I/O口可以编程配置成带上拉电阻的模式,这个特点可以用来检测有无触摸。MCU的GPIO管脚连接触摸屏的Y+和X- ,连接Y+的管脚配置成内部电阻上拉模式,连接X-的管脚配置成推挽输出低电平。如果Y+为高电平,那么就是没有触摸。如果Y+为低电平,触摸屏被压下。从高到低电平的跳变可以检测触摸,可以用外部中断,在本例程中将使用ADC的单次扫描模式采集X+\Y+电压。    

 

驱动电阻触摸屏的实现

 

三、ADC介绍

  12 位ADC 是逐次逼近式的模拟-数字转换器(SAR A/D 转换器),且ADC转换数据分辨率可设置8-12位有效。

 

  高达1Msps转换速率,有很多用户在计算采样频率设置时会觉得很难理解,在这里将为大家讲一下采样频率计算方法,ADC 的时钟ADCLK 由 PCLK2 分频得到ADC 的输入时钟(不得超过15MHz,它是由PCLK2 经分频产生)。分频系数可通过设置 ADCFG寄存器的ADCPRE 位来确定,即PCLK2/(N+1)/2 分频后作为 ADC 时钟。设置 ADC分辨率为 n 位(n=8,9,10,11,12),每个通道采样时间为 m, Fsample = FADCLK/(m + n + 1.5)。假设分辨率配置为 12bit,每个通道采样时间为 1.5T,则 Fsample =FADCLK/15。

 

例如:设置ADC 分辨率为n =12, 亿配芯城 每个通道采样时间m=1.5个周期,FADCLK=15MHz

 

Fsample = FADCLK/(m + n+ 1.5)=15/(12+1.5+1.5)=1Msps

根据此配置可以得到1Msps转换速率,也就是转换时间为1us,用户可以根据项目的需求配置相对应的转换速率。

 

A/D转换器支持多种工作模式:单次转换、单周期扫描模式和连续转换模式。

- 单次转换模式: A/D 转换在指定通道完成一次转换。

- 单周期扫描模式: A/D 转换在所有指定通道完成一个周期(从低序号通道到高序号通道)转换。

 

- 连续扫描模式: A/D 转换连续执行单周期扫描模式直到软件停止 A/D 转换。

 

  支持DMA传输,单周期扫描和连续扫描时通道转换的值存储在各自通道的数据寄存(ADDRn)中,最近一次转换的结果也会保存在 ADDATA 寄存器中。DMA传输时可以选择传输某个特定通道的数据,或者传输所有扫描通道的结果。

 

  A/D转换的启动方式有软件设定(即在配置相关寄存器时,直接开启采样)、外部引脚触发(例如定时器捕获,EXti线)以及各个定时器启动(Timer1/2/3/4 匹配或者 TRGO信号,在配置电机应用时需要使用定时器触发ADC采样)。

 

  窗口比较器(模拟看门狗)允许应用程序检测输入电压是否超出了用户设定的高/低阀值值,转换结果可和指定的值相比较,当转换值和设定值相匹配时,用户可设定是否产生中断请求。

 

四、用MM32L373读触摸屏参数

  在硬件中使用了MM32L373的ADC单周期扫描功能,使用到的GPIO分别是:PA1\PA3\PA4\PA5,分两步读取X,Y坐标值。

 

//测量X+电压的GPIO配置

voidXP_GPIO_Configuration(void)

{

 GPIO_InitTypeDef GPIO_InitStructure;

 RCC_APB2PeriphclockCmd(RCC_APB2Periph_GPIOA, ENABLE); 

  //将X+配置模拟输入

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

 //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

 GPIO_Init(GPIOA, &GPIO_InitStructure);

  //将X-配置浮空模式

 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;

 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;

 GPIO_Init(GPIOA, &GPIO_InitStructure);

  //将Y+、Y-配置为通用推挽输出

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;

 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

 GPIO_Init(GPIOA, &GPIO_InitStructure);

 GPIO_ResetBits(GPIOA,GPIO_Pin_4);//Y-输出低电平

 GPIO_SetBits(GPIOA,GPIO_Pin_5);     //Y+输出高电平

}

//测量Y+电压的GPIO配置

voidYP_GPIO_Configuration(void)

{

 GPIO_InitTypeDef GPIO_InitStructure;

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  //将Y+ 配置模拟输入

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

 //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

 GPIO_Init(GPIOA, &GPIO_InitStructure);

  //将Y- 配置浮空模式

 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;

 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;

 GPIO_Init(GPIOA, &GPIO_InitStructure);

  //将X+、X-配置为通用推挽输出

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_3;

 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

 GPIO_Init(GPIOA, &GPIO_InitStructure);

 GPIO_ResetBits(GPIOA,GPIO_Pin_3);//X-输出低电平

 GPIO_SetBits(GPIOA,GPIO_Pin_1);     //X+输出高电平

}

  第一步,驱动Y+为高电平,Y-为低电平,接X+管脚配置成AD输入模式,检测X+的电压,此电压与驱动电压的比例即Y坐标和整个屏的高度比率。

/***************************************************************************

** 函数信息:voidXP_ADC1_SingleChannel(uint8_tADC_Channel_x)

**功能描述:测量X+电压,配置ADC单次扫描通道

**输入函数:ADC_Channel_x ,x为0~8

**输出函数:无

***************************************************************************/

voidXP_ADC1_SingleChannel(uint8_tADC_Channel_x)

{

 ADC_InitTypeDef ADC_InitStructure;

 XP_GPIO_Configuration();

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC1时钟

  /*Initialize the ADC_PRESCARE values */

 ADC_InitStructure.ADC_PRESCARE = ADC_PCLK2_PRESCARE_16;//16分频

  /*Initialize the ADC_Mode member */

 ADC_InitStructure.ADC_Mode = ADC_Mode_Single;//配置单通道扫描模式

  /*Initialize the ADC_ContinuousConvMode member */

 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换模式

  /*Initialize the ADC_DataAlign member */

 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐

  /*Initialize the ADC_ExternalTrigConv member */

 ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T1_CC1;//外部触发通道选择

 ADC_Init(ADC1, &ADC_InitStructure);

 ADC_RegularChannelConfig(ADC1, ADC_Channel_x, 0,ADC_SampleTime_1_5Cycles);//设置换换顺序和采样时间

 ADC_Cmd(ADC1, ENABLE); //使能ADC1

 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1软件转换启动

 IF(ADC_Channel_x==ADC_Channel_8)

  {

   ADC1->ADCFG|=0x04;

  }

}

 

  第二步,驱动X+为高电平,X-为低电平,接Y+的管脚配置成AD输入模式,检测Y+的电压,此电压与驱动电压的比例即X坐标和整个屏的宽度比率。

/***************************************************************************

** 函数信息:voidYP_ADC1_SingleChannel(uint8_tADC_Channel_x)

**功能描述:测量Y+电压,配置ADC单次扫描通道

**输入函数:ADC_Channel_x ,x为0~8

**输出函数:无

***************************************************************************/

voidYP_ADC1_SingleChannel(uint8_tADC_Channel_x)

{

 ADC_InitTypeDef ADC_InitStructure;

 YP_GPIO_Configuration();

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1时钟

  /*Initialize the ADC_PRESCARE values */

 ADC_InitStructure.ADC_PRESCARE = ADC_PCLK2_PRESCARE_16; //16分频

  /*Initialize the ADC_Mode member */

 ADC_InitStructure.ADC_Mode = ADC_Mode_Single; //配置单通道扫描模式

  /*Initialize the ADC_ContinuousConvMode member */

 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //关闭连续转换模式

  /*Initialize the ADC_DataAlign member */

 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐

  /*Initialize the ADC_ExternalTrigConv member */

 ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T1_CC1;//外部触发通道选择

  ADC_Init(ADC1,&ADC_InitStructure);

 ADC_RegularChannelConfig(ADC1,ADC_Channel_x,0,ADC_SampleTime_1_5Cycles);//设置换换顺序和采样时间

 ADC_Cmd(ADC1, ENABLE); //使能ADC1

 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1软件转换启动

 if(ADC_Channel_x==ADC_Channel_8)

  {

   ADC1->ADCFG|=0x04;

  }

}

 

  第三步:根据ADC采集到的数据做校验算法,得到触摸点坐标,并且显示在显示屏对应的区域。