电阻触屏因其使用简单,成本较低被广泛应用在消费市场,医疗,工业和汽车市场.其中,4线电阻触屏更是因为成本的原因,在市场中最为常见.本文将就4线电阻触屏与Xinnova 32位XN12L系列MCU连接的一个低成本低功耗方案进行讨论.
测量X坐标时:
在大多数应用中,一般通过外加专用的电阻触屏IC.该IC一方面检测X+,X-,Y+,Y-因用户触摸引起的电压的变化,另一方面通过I2C/SPI接口把检测到的XY坐标传输给系统MCU.该方案主要的问题是单独的触屏IC增加了系统成本.把对电阻触屏X+,X-,Y+,Y-的检测集成到系统MCU无疑是最好的选择.
由于在检测X/Y坐标位置需要用到ADC转换,并且要提供相应的信号源,一般的MCU控制比较麻烦,但幸运的是,Xinnova MCU的引脚具备多重模拟/数字复用功能,可以轻而易举的解决这个问题.
• 高达100MHz ARM Cortex M0 CPU
• 高达88KB用户Flash和16KB SRAM
• xDSP 用于增强MCU运算功能
32位单周期除法器
CORDIC运算器
CRC校验
• 多种时钟系统供用户选择
1%精度的内部晶振
支持外部时钟和晶振
内部PLL
支持实时时钟(RTC)
• 多达3个独立的ADC转换器更适合系统高速采样需求
12位,1MHz采样率
多达12路ADC通道
• 2个模拟比较器
• 10位DAC,1MHz转换率
• 4个增强型系统定时/计数器,支持正交编码信号
• 集成的片上温度传感器
• 支持各种通讯接口
1个SPI
1个Quad SPI (支持Flash 4 IOs数据传输)
1个TWS(I2C兼容)
• 支持内存,外设间的DMA大容量数据传输
• 支持故障诊断恢复功能(WDT/BOD)
• 支持睡眠,深度睡眠和掉电三种低功耗模式
• 数据和程序的高可靠和保密性能
加密模式下的应用二次开发,更好知识产权回报
• 单电源供电(3.3v)
在该方案中,Y+,X+,Y-,X-直接与MCU引脚相连,无需任何外部器件。
在该应用中,重点考量以下几个方面:
考虑到CPU时间占用和功耗,CPU不要时时刻刻对Y+,X+,Y-,X-进行检测。只有在用户触屏时才会做出反应。因此,我们考虑使用中断来对用户触屏进行检测。在平常,X+,X-设置为GPIO输出低电平,而Y+,Y-为GPIO带内部上拉输入,并允许下降沿中断。无触摸时,CPU没有任何动作且没有任何功耗在电阻触屏。当用户触屏时,Y+,Y-变为低并触发中断。在该中断处理程序中,我们需把X+端口置为高电平,同时把Y+,Y-设为ADC输入。在检测到Y+的电压值(该电压值对应触点X轴位置)后,把Y+,Y-设置为GPIO输出,且Y+为高,Y-为低,X+,X-设为ADC输入并对X+进行检测。检测到的电压值对应触点Y轴位置。在检测结束后,恢复X+,X-设置为GPIO输出低电平,而Y+,Y-为GPIO带内部上拉输入,并允许下降沿中断。
注意,在对X,Y进行位置ADC检测时,由于存在高低电平转换,需注意ADC检测必须在电压信号稳定后进行,所以相应的延迟是必须的。
另外,用户在使用电阻触屏时,需加入位置校对。
检测方法示意图
程序例程
本例程用到下列Xinnova MCU库函数,请参看Xinnova网页和论坛。
Xn12lxxx.h: device description file
Xn_adc.h: ADC h file
Xn_adc.c: ADC driver file
Xn_uart.h: UART h file
Xn_UART: UART driver file
/*****************************************************************************
// PIO1_0 (AD2) -> X-
// PIO1_1 (AD3) -> Y-
// PIO1_2 (AD4) -> X+
// PIO1_3 (AD5) -> Y+
**
*****************************************************************************/
uint32_t x,y;
void SetTouchIO(void)
{
//init Touch
XN_IOCON->PIO1_0 = 0x91; //x-
XN_IOCON->PIO1_1 = 0x91; //y-
XN_IOCON->PIO1_2 = 0x90; //x+
XN_IOCON->PIO1_3 = 0x90; //y+
XN_GPIO1->DIR = 0x05; //set x-,x+ as output
XN_GPIO1->OUT = 0; //x-,x+ set to low
delayms(100);
XN_GPIO1->IBE = 0x02; //沿触发中断
//XN_GPIO1->IC = 0x02; //清除中断
//XN_GPIO1->IE = 0x02;
//NVIC_EnableIRQ(EINT1_IRQn);
}
uint32_t TouchPressed(void)
{
//verify if y is low
if ((XN_GPIO1->PIN & 0x2)==0)
return 1;
else
return 0;
}
void ReadXY(uint32_t * x,uint32_t* y)
{
uint32_t temp;
*x=0;
*y=0;
//Read x
SetADCPin(AD3PIN|AD5PIN);
XN_IOCON->PIO1_0 = 0x91; //x-
XN_IOCON->PIO1_2 = 0x90; //x+
XN_GPIO1->MASK = 0xFFFFFFF0;
XN_GPIO1->DIR = 0x05;
XN_GPIO1->OUT = 0x04; //X+ 3.3v;X- GND
//SetADCPin(AD3PIN|AD5PIN);
ADCInit(XN_ADC0,10000,TRIGGERMODE,START_BY_SOFTWAER, 0); //?K conversion rate and software trigger
ADCSelChannel(XN_ADC0,((AD5<<DR0SEL)|(AD5<<DR1SEL)|(AD5<<DR2SEL)|(AD5<<DR3SEL)|(AD5<<DR4SEL)|(AD5<<DR5SEL)|(AD5<<DR6SEL)|(AD5<<DR7SEL)));
delayms(100);
ADCSoftwareTrigger(XN_ADC0);
do
{
temp=ADCValue(XN_ADC0,DR7);
}while(temp==0xFFFFFFFF);
*x =temp;
//Read y
SetADCPin(AD2|AD4);
XN_IOCON->PIO1_1 = 0x91; //y-
XN_IOCON->PIO1_3 = 0x90; //y+
XN_GPIO1->MASK = 0xFFFFFFF0;
XN_GPIO1->DIR = 0x0A;
XN_GPIO1->OUT = 0x02; //y+ 3.3v;y- GND
//SetADCPin(AD2|AD4);
ADCSelChannel(XN_ADC0,(AD2<<DR0SEL)|(AD2<<DR1SEL)|(AD2<<DR2SEL)|(AD2<<DR3SEL)|(AD2<<DR4SEL)|(AD2<<DR5SEL)|(AD2<<DR6SEL)|(AD2<<DR7SEL));
delayms(100);
ADCSoftwareTrigger(XN_ADC0);
do
{
temp=ADCValue(XN_ADC0,DR7);
}while(temp==0xFFFFFFFF);
*y =temp;
}
int main(void)
{
//disable watchdog
XN_WDT->MOD = 0;
//init Touch
SetTouchIO();
XN_GPIO1->IC = 0x02; //清除中断
XN_GPIO1->IE = 0x02; //enable INT
NVIC_EnableIRQ(EINT1_IRQn);
while (1)
{
// Loop forever
}
}
void EINT1_IRQHandler(void)
{
NVIC_DisableIRQ(EINT1_IRQn);
XN_GPIO1->IE = 0x0; //屏蔽GPIO1 IO 中断
if (TouchPressed())
{
ReadXY(&touch_x,&touch_y);
SetTouchIO();
if (TouchPressed())
{
touch_xy_new=1;
UART0PutHex (touch_x);
UART0Send(",",1);
UART0PutHex (touch_y);
UART0Send(" ",4);
}
}
XN_GPIO1->IC = 0x02; //清除中断
XN_GPIO1->IE = 0x02; //enable INT
NVIC_EnableIRQ(EINT1_IRQn);
return;
}
总结
Xinnova MCU 引脚复用,配置灵活。在应对4线电阻触屏应用中占用较少资源,使用简单。该方法在EBike显示屏被采用,表现稳定。
文章评论(0条评论)
登录后参与讨论