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流程
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< /* 注册中断处理函数 */ register_irq(31, AdcTsIntHandle); /*31号中断*/ /* 使能中断 */ INTSUBMSK &= ~((1< //INTMSK &= ~(1< 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%xnr", ADCUPDN, ADCDAT0, ADCDAT1, ADCTSC); if (ADCDAT0 & (1<<15))//dat寄存器的第15位判断按下还是松开 { printf("pen upnr"); enter_wait_pen_down_mode(); } else { printf("pen downnr"); /* 进入"等待触摸笔松开的模式" */ enter_wait_pen_up_mode(); } } void AdcTsIntHandle(int irq) { if (SUBSRCPND & (1< // if (SUBSRCPND & (1< // Isr_Adc(); SUBSRCPND = (1< } AdcTsIntHandle函数: 这里先注解掉ADC中断,只检测单独的按下松开触摸屏操作。那当isr处理完后为了能够正常响应下一次中断,需要清中断,否则会一直触发interrupt。 Isr_Tc函数:ADCDAT0 寄存器的第15位判断按下还是松开。那么当按下后,要将控制器进入”等待松开模式“,当松开后,要将控制器配置进入”等待按下模式“。