ok6410学习之触摸屏篇

对于触摸屏首先说说他们的工作原理:

1 电阻屏


当手指触摸屏幕时,两个相互绝缘的导电层在触摸点处连接,顶层的5伏电压就会加到底层触摸点处,底层该点的电压会发生改变。控制器检测到该点的
变化后,将该点的电压进行A/D转换,得到的值与5伏相比,再乘以该轴总长度即可得触摸点靠地那一端的坐标。

2 电容屏:


给工作面通上一个很低的电压,当用户触摸屏幕时, 手指头吸收走一个很小的电流, 这个电流分从触摸屏四个角上的电极中流出, 并且理论上流经这四个电极的电流与手指到四角的距离成比例, 控制器通过对这四个电流比例的精密计算, 得出触摸点的位置。

接下来一电阻屏为例做一个裸机驱动程序:

     此程序可分三部分: 触摸屏初始化,中断处理和进入中断;


一: 触摸屏初始化:ts_init()

      对于触摸屏的驱动设计其实就是ADC和中断;所以初始化的因为就是ADC和中

1 配置ADCCON;主要是使能ADC及计算AD转换时钟      公式:AD=pclk/(PRSCVL+1)  其中 AD自己定义,一般不能大于2MHZ,pclk 是时钟频率,PRSCVL 需要配置的;我的配置是:ADCCON = (0<<16)|(1<<14)|(49<<6)|(0<<2)|(0<<1)|(0<<0);//

2 开启使能中断,有两个 1  开启ADC中断,2 开启触摸屏下/上中断  寄存器分别是 VIC1IRQSTATUS = (1<<31);///       ADCUPDN = (1 << 0);///

3 一切准备就绪 开始等待中断   //注;在此驱动中只要是需要等待中断的就要使用语句   ADCTSC = 0xd3;  来进入等待中断模式;

   二:中断处理:irq_adc()

1 对于触摸屏两种获取x  y 坐标点的方法  一是手动获取,二是自动获取  我再次用的是自定获取x y坐标,并开启ADC ; 寄存器设置是: ADCTSC = (1<<2);    ADCCON |= (1<<0);  

2 既然用了自动转换,又已经开启了ADC,现在要做的就是等待ADC完成,判断方法是:while (!(ADCCON & (1<<15)));

3 当转换完成之后,它会自动的将x y坐标的值分别放在ADCDAT0[9:0]和ADCDAT1[9:0],如果我们想用的话就要在这两个寄存器中取值;

4 到这里中断处理已经完成了,所以我们要清除中断,以便于下次中断,有两个需要清除 1 清除ADC中断,2 清除按下中断   寄存器设置是: ADCCLRINT = 0;    ADCCLRINTPNDNUP = (1 << 0); 

5 按下去之后还没有弹起,所以要等待弹起中断; 寄存器设置时: ADCTSC = 0xd3;      ADCTSC |= (1<<8);

6 当弹起中断产生之后,在这一阶段的中断圆满结束,但还要做的就是清除弹起中断 寄存器设置是:

                 ADCCLRINTPNDNUP = (1 << 0);

                  VIC0ADDRESS = 0; //  

                VIC1ADDRESS = 0; //
               ADCCLRINT = 0;
               ADCUPDN = 0x0;

7 接下来就是等待进入下次中断;  ADCTSC = 0xd3; 

  

   三: 进入中断;

          对于进入中断有两种方法,一是 在ts.c 中直接写一个函数来将中断处理的函数地址给了相应寄存器,但好像有问题 他只能进一次中断 代码是:

         void ts_irq_init()

 {
   
  VIC1VECTADDR30 = irq_adc;
  VIC1INTENABLE |=(1<<30);//|(1<<31);//使能INT_ADC ,INT_PENDNUP
  VIC1INTSELECT = VIC1INTSELECT&(~(1<<30));//
 }

二是在我以前写得中断程序interrupt.c中将其添加进去,没错误 代码如下:

    

ts_irq()
{
//保存环境
__asm__(
   "sub lr,lr,#4\n"
   "stmfd sp!, {r0-r12,lr}\n"
   :
   :
);
irq_adc();
__asm__(
  "ldmfd sp!,{r0-r12,pc}^\n"
  :
  :
);
}

VIC1VECTADDR30 = ts_irq;  //保存触摸屏处理地址 
   VIC1INTENABLE |=(1<<30);//|(1<<31);//使能INT_ADC ,INT_PENDNUP

具体代码如下:

[plain]  view plain  copy
  1. #define ADCCON          *((volatile signed long*)0x7E00B000)  
  2. #define ADCDLY          *((volatile signed long*)0x7E00B008)  
  3. #define ADCTSC          *((volatile signed long*)0x7E00B004)  
  4. #define ADCDAT0         *((volatile signed long*)0x7E00B00C)  
  5. #define ADCDAT1         *((volatile signed long*)0x7E00B010)  
  6. #define ADCUPDN         *((volatile signed long*)0x7E00B014)  
  7. #define ADCCLRINTPNDNUP *((volatile signed long*)0x7E00B020)  
  8. #define VIC1VECTADDR30  *((volatile signed long*)0x71300178)  
  9. #define VIC1VECTADDR31  *((volatile signed long*)0x7130017c)  
  10. #define ADCCLRINT       *((volatile signed long*)0x7E00B018)  
  11. #define VIC1INTENABLE   *((volatile signed long*)0x71300010)  
  12. #define VIC1INTSELECT   *((volatile signed long*)0x7130000C)  
  13. #define VIC1ADDRESS     *((volatile signed long*)0x71300f00)  
  14. #define VIC0ADDRESS     *((volatile signed long*)0x71200f00)  
  15. #define VIC1IRQSTATUS   (*(volatile unsigned *)0x71300000)   //IRQ Status Register (VIC1)  
  16. int x,y;  
  17.   
  18. void  irq_adc()  
  19. {  
  20.     //1. 启动xy坐标自动转换   
  21.         ADCTSC = (1<<2);  
  22.         ADCCON |= (1<<0);  
  23.       // 2 等待转换完成  
  24.         while (!(ADCCON & (1<<15)));  
  25.       //3 获取坐标  
  26.         x = ADCDAT0 & 0x3ff;  
  27.         y = ADCDAT1 & 0x3ff;  
  28.      //4清除中断  
  29.         ADCCLRINTPNDNUP = (1 << 0);   
  30.      //5. 进入等待弹起中断  
  31.         ADCTSC = 0xd3;  
  32.         ADCTSC |= (1<<8);  
  33.     //6.清除弹起中断  
  34.         ADCCLRINTPNDNUP = (1 << 0);  
  35.         VIC0ADDRESS = 0; //  
  36.         VIC1ADDRESS = 0; //  
  37.         ADCCLRINT = 0;  
  38.         ADCUPDN = 0x0;  
  39.         printf("x is %d,y is %d\n",x,y);  
  40.     //7. 再次进入等待按下中断的状态  
  41.         ADCTSC = 0xd3;  
  42.     
  43. void ts_irq_init()  
  44. {  
  45.        
  46.     VIC1VECTADDR30 = irq_adc;  
  47.     VIC1INTENABLE |=(1<<30);//|(1<<31);//使能INT_ADC ,INT_PENDNUP  
  48.     VIC1INTSELECT = VIC1INTSELECT&(~(1<<30));//  
  49. }  
  50.   
  51. void ts_init()  
  52. {  
  53.     //1 设置AD转换时钟  
  54.        
  55.     ADCCON = (0<<16)|(1<<14)|(49<<6)|(0<<2)|(0<<1)|(0<<0);//  
  56.        
  57.     //2 开启中断使能位(2个)  
  58.     VIC1IRQSTATUS = (1<<31);///  
  59.     ADCUPDN = (1 << 0);///  
  60.        
  61.     //3 进入等待中断模式!  
  62.        ADCTSC = 0xd3;  
  63.    
  64. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值