zoukankan      html  css  js  c++  java
  • s3c2440裸机-电阻触摸屏编程(3.触摸屏TSC的初始化和中断服务程序框架)

    1. ADC中断产生流程

     

    中断源:

    这里是ADC和TSC共用一个中断源。

    SRCPND表示哪个中断源产生了中断请求。

     

     INTMODE:配置中断模式

     

    配置中断屏蔽寄存器

     

    中断挂起寄存器(用来显示当前优先级最高的、正在发生的中断, 需要清除对应位)

    从SRCPND寄存器可以读到ADC和TSC复用的同一个中断源,那么如何区分呢?

    可以从SUBSRCPND寄存器配置,如下:

     

     当bit 9被置1时,表示TSC中断。那么我们需要打开subsrcmask寄存器

     所以TSC中断的产生流程如下:

     2. TSC编程实现

      ①初始化TSC,ADCTSC寄存器

      ②设定TSC处于“等待中断模式”

      ③使能TSC中断

          INTSUBMSK

          MSK/MODE

      ④按下,进入TSC中断

          进入自动采集转换模式

          启动ADC

      ⑤ADC中断

          读数据

          再次进入”等待中断模式“

          启动定时器(为了处理长按或者滑动操作)

      ⑥定时器中断

          若松开,结束

          如任然按下,进入④步骤的启动ADC流程

    2.1 初始化

    void touchscreen_init(void)
    {
        /* 设置触摸屏接口:寄存器 */
        adc_ts_reg_init();
        /* 设置中断 */
        adc_ts_int_init();
        /* 让触摸屏控制器进入"等待中断模式" */
        enter_wait_pen_down_mode();
    }

    2.1.1 tsc寄存器init

    主要是设置预分频,产生ADC clk = 1MHz.

    void adc_ts_reg_init(void)
    {
        /* [15] : ECFLG,  1 = End of A/D conversion
         * [14] : PRSCEN, 1 = A/D converter prescaler enable
         * [13:6]: PRSCVL, adc clk = PCLK / (PRSCVL + 1)
         * [5:3] : SEL_MUX, 000 = AIN 0
         * [2]   : STDBM
         * [0]   : 1 = A/D conversion starts and this bit is cleared after the startup.
         */
        ADCCON = (1<<14) | (49<<6) | (0<<3);
    
        ADCDLY = 0xff;    
    }

    2.1.2 TSC interrupt init并且使能int

    为了将中断源开启,这里设置SUBSRCPND 和INTSUBMSK让中断源开启。通过register_irq()注册中断号和中断服务程AdcTsIntHandle,查表得出中断号为31,这样当硬件产生中断后可以从INTOFFSET区分是哪个中断号。如下图:

    void adc_ts_int_init(void)
    {
        SUBSRCPND = (1<<TC_INT_BIT) | (1<<ADC_INT_BIT);/*清中断*/
    
        /* 注册中断处理函数 */
        register_irq(31, AdcTsIntHandle);    /*31号中断*/
    
        /* 使能中断 */
        INTSUBMSK &= ~((1<<ADC_INT_BIT) | (1<<TC_INT_BIT));//防止屏蔽(SUBMSK)
        //INTMSK    &= ~(1<<INT_ADC_TC);//reg_irq已经使能了31中断号
    }

    2.1.3 进入"等待中断模式" 

    进入等待中断模式,YM闭合, YP, XP, XM断开,需要pull up,WAIT_PEN_DOWN表示要等待的是按下中断,当触摸屏按下时就会产生一个TSC irq,反之WAIT_PEN_UP表示要等待的是松开中断。

    #define ADC_INT_BIT (10)
    #define TC_INT_BIT  (9)
    #define INT_ADC_TC   (31)
    /* ADCTSC's bits */
    #define WAIT_PEN_DOWN    (0<<8) /*触摸笔按下*/
    #define WAIT_PEN_UP      (1<<8) /*触摸笔松开*/
    #define YM_ENABLE        (1<<7)
    #define YM_DISABLE       (0<<7)
    #define YP_ENABLE        (0<<6)
    #define YP_DISABLE       (1<<6)
    #define XM_ENABLE        (1<<5)
    #define XM_DISABLE       (0<<5)
    #define XP_ENABLE        (0<<4)
    #define XP_DISABLE       (1<<4)
    #define PULLUP_ENABLE    (0<<3)
    #define PULLUP_DISABLE   (1<<3)
    #define AUTO_PST         (1<<2) /*自动转换*/
    #define WAIT_INT_MODE    (3)    /*等待中断模式*/
    #define NO_OPR_MODE      (0)    /*禁止模式*/
    void enter_wait_pen_down_mode(void)/*等待按下模式*/
    {
        ADCTSC = WAIT_PEN_DOWN | PULLUP_ENABLE | YM_ENABLE | YP_DISABLE | XP_DISABLE | XM_DISABLE | WAIT_INT_MODE;}
    void enter_wait_pen_up_mode(void)/*等待松开模式*/
    {
      ADCTSC = WAIT_PEN_UP | PULLUP_ENABLE | YM_ENABLE | YP_DISABLE | XP_DISABLE | XM_DISABLE | WAIT_INT_MODE;
    }

    2.2 TSC中断服务程序

    SUBSRCPND的bit9, bit10可以区分是TC中断还是ADC中断。

    void Isr_Tc(void)/*触摸屏中断服务程序*/
    {
      printf("ADCUPDN = 0x%x, ADCDAT0 = 0x%x, ADCDAT1 = 0x%x, ADCTSC = 0x%x
    
    ", ADCUPDN, ADCDAT0, ADCDAT1, ADCTSC);
      if (ADCDAT0 & (1<<15))//dat寄存器的第15位判断按下还是松开
      {
        printf("pen up
    
    ");
        enter_wait_pen_down_mode();
      }
      else
      {
        printf("pen down
    
    ");
    
        /* 进入"等待触摸笔松开的模式" */
        enter_wait_pen_up_mode();
      }
    }
    void AdcTsIntHandle(int irq)
    {
      if (SUBSRCPND & (1<<TC_INT_BIT)) /* 如果是触摸屏中断 */
        Isr_Tc();
    
      // if (SUBSRCPND & (1<<ADC_INT_BIT)) /* ADC中断 */
      // Isr_Adc();
      SUBSRCPND = (1<<TC_INT_BIT) | (1<<ADC_INT_BIT);/*清中断*/
      //SRCPND = 1<<31;/*在interrupt.c已经清中断了*/
    }

     AdcTsIntHandle函数: 这里先注解掉ADC中断,只检测单独的按下松开触摸屏操作。那当isr处理完后为了能够正常响应下一次中断,需要清中断,否则会一直触发interrupt。

    Isr_Tc函数:ADCDAT0 寄存器的第15位判断按下还是松开。那么当按下后,要将控制器进入”等待松开模式“,当松开后,要将控制器配置进入”等待按下模式“。

  • 相关阅读:
    CloudStack 4.2 与CloudStack 4.1二级存储API发生变化
    添加虚拟机磁盘扩容步骤
    NAT概述
    CloudStack全局参数
    在 Web 项目中应用 Apache Shiro
    使用 Spring Security 保护 Web 应用的安全
    获取浏览器的homepage
    剑指offer系列——2.替换空格
    剑指offer系列——1.二维数组中的查找
    JDK下载需要Oracle账号登录问题
  • 原文地址:https://www.cnblogs.com/fuzidage/p/14644802.html
Copyright © 2011-2022 走看看