今天看了一下s3c2440的touch screen control借口,完成了裸机程序的调试,把代码记录如下
其他的代码和前面做的实验基本一样,只是在ad中断里面添加了对于触摸屏的处理,初始化ad的函数有了一点点修改,只记录ad.c
ad.c
#define ADCCON (*((volatile unsigned long*)(0x58000000)))
#define ADCTSC (*((volatile unsigned long*)(0x58000004)))
#define ADCDLY (*((volatile unsigned long*)(0x58000008)))
#define ADCDAT0 (*((volatile unsigned long*)(0x5800000C)))
#define ADCDAT1 (*((volatile unsigned long*)(0x58000010)))
#define SUBSRCPND (*((volatile unsigned long*)(0X4A000018)))
#define SRCPND (*((volatile unsigned long*)(0X4A000000)))
#define INTPND (*((volatile unsigned long*)(0X4A000010)))
#define PURE_RED 0b0000011111100000
extern void change_num_string(unsigned short num, char *buffer);
extern void put_char(char ch);
extern void put_string(char *string);
unsigned short read_ad(unsigned char chanel_num)
{
/*
enable prescale operation, the value of prescaling is 49+1=50
PCLK has been set to 50MHz, so the clock of ad conventer is 1MHz
*/
ADCCON = (1<<14)|(49<<6)|(chanel_num<<3);
//set ad conventer to normal working mode
ADCTSC &= ~(1<<2);
//set ADCCON[0] to 1 in order to starting converting operation
ADCCON |= 1;
//wait converting operation to start, at that moment ADCCON[0] will be cleared
while (ADCCON & 1);
//wait till convertion operatioin stops
while (!(ADCCON&(1<<15)));
//return the result (10bits)
return (unsigned short)(ADCDAT0 & 0x3ff);
}
void init_ad(unsigned char chanel_num)
{
/*
enable prescale operation, the value of prescaling is 49+1=50
PCLK has been set to 50MHz, so the clock of ad conventer is 1MHz
*/
//ADCCON = (1<<14)|(49<<6)|(chanel_num<<3);
ADCCON = (1<<14)|(49<<6);
/*
after touch screen interrupt happens, cpu will delay 1/3.68M*50000 = 13.5ms
and start the ad converting operation for x and y
*/
ADCDLY = 50000;
//set ad conventer to normal working mode and waiting for touch screen down interrupt
ADCTSC = 0b011010011;
}
inline void start_ad()
{
//set ADCCON[0] to 1 in order to starting converting operation
ADCCON |= 1;
}
void delay(int times);
void ad_interrupt_handler()
{
if(SUBSRCPND&(1<<10)) //standard ad interrupt
{
char buffer[4];
int x, y;
unsigned short adc_result = ADCDAT0&0x3ff;
x = adc_result;
put_string("x:0x");
change_num_string(x, buffer);
put_string(buffer);
adc_result = ADCDAT1&0x3ff;
y = adc_result;
put_string(" y:0x");
change_num_string(y, buffer);
put_string(buffer);
put_char('\r');
delay(10); //give com0 enough time to print information
//wait screen up interrupt
ADCTSC = 0b111010011;
//clear ad screen interrupt
SUBSRCPND = SUBSRCPND;
SRCPND |= (1<<31);
INTPND = INTPND;
}
else if(SUBSRCPND&(1<<9)) //touch screen interrupt
{
//put_string("touch screen interrupt!\r\n");
if(ADCTSC & (1<<8)) //it is touch up interrupt currently
{
ADCTSC = 0b011010011;
//put_string("touch screen up interrupt!\r\n");
//clear touch screen interrupt
SUBSRCPND = SUBSRCPND;
SRCPND |= (1<<31);
INTPND = INTPND;
}
else //it is touch down interrupt currently
{
//put_string("touch screen down interrupt!\r\n");
//clear touch screen interrupt first, so that standard ad interrupt can be served
SUBSRCPND = SUBSRCPND;
SRCPND |= (1<<31);
INTPND = INTPND;
ADCTSC = 0x0c; //auto xy mode
ADCCON |= (1<<0); //start the ad converting operation
}
}
}
显示16进制的xy坐标的ad转换结果: