- 論壇徽章:
- 0
|
哪位大哥做過旋轉(zhuǎn)編碼開關(guān)程序幫忙看一下!
我最近在做旋轉(zhuǎn)編碼開關(guān)驅(qū)動(dòng)程序,碰到一點(diǎn)問題,請高手幫忙看一下:
是基于2410 linux2.6內(nèi)核的
旋轉(zhuǎn)編碼開關(guān)運(yùn)動(dòng)周期的時(shí)序?yàn)?br />
順時(shí)針運(yùn)動(dòng): A B 逆時(shí)針運(yùn)動(dòng): A B
1 1 1 1
0 1 1 0
0 0 0 0
1 0 0 1
我把當(dāng)前的A,B輸出值保存起來,與下一個(gè)A,B輸出值做比較,得出運(yùn)動(dòng)方向(如果A,B輸出11后輸出01,則為順時(shí)針;如果輸出11后馬上輸出10,則為逆時(shí)針),
我采用的是雙邊緣中斷方式,其中A接到INT16(GPIOG ,接到INT8(GPIOG0),以下是我的驅(qū)動(dòng)程序中的中斷處理函數(shù)
static unsigned int inc[] = {0,0,0,0};
static unsigned int dec[] = {0,0,0,0};
//static int a=0;
unsigned int right=0, left=0,irq_num=0;
static irqreturn_t buttons2_irq(int irq, void *dev_id, struct pt_regs *reg)
{
unsigned int gpg_con2,gpg_dat2,gpg_up2;
unsigned long flags;
disable_irq(irq);
irq_num = irq_num + 1;
//local_irq_save(flags);
unsigned int k1 = 0,k2 = 0;
gpg_con2=readl(gpbase+0x60); //取出G端口控制字寄存器值
gpg_dat2=readl(gpbase+0x64); // 取出G端口數(shù)據(jù)寄存器值
gpg_up2=readl(gpbase+0x6 ; // 取出G端口上拉寄存器值
writel(gpg_con2 & 0xfffcfffc,gpbase+0x60);//G端口中G0、G8管腳設(shè)為輸入模式
writel(gpg_up2 | 0x0101,gpbase+0x6 ;
k1 = s3c2410_gpio_getpin(S3C2410_GPG ;
k2 = s3c2410_gpio_getpin(S3C2410_GPG0);
writel(gpg_con2 & 0xfffefffe,gpbase+0x60);//G端口中G0、G8管腳設(shè)為中斷模式
set_irq_type(INC_IRQ,IRQT_BOTHEDGE);
set_irq_type(DEC_IRQ,IRQT_BOTHEDGE);
//printk("%x,%x\n",k1,k2);
inc[3] = k1;
dec[3] = k2;
if((inc[0]==0x100) && (dec[0]==1)){ //1
if((inc[1]==0) && (dec[1]==1)){
if((inc[2]==0) && (dec[2]==0)){
if((inc[3]==0x100) && (dec[3]==0)){
right = 1;
left = 0;
}
}
}
}
if((inc[0]==0x100) && (dec[0]==1)){ //2
if((inc[1]==0x100) && (dec[1]==0)){
if((inc[2]==0) && (dec[2]==0)){
if((inc[3]==0) && (dec[3]==1)){
right = 0;
left = 1;
}
}
}
}
if((inc[0]==0) && (dec[0]==1)){ //3
if((inc[1]==0) && (dec[1]==0)){
if((inc[2]==0x100) && (dec[2]==0)){
if((inc[3]==0x100) && (dec[3]==1)){
right = 1;
left = 0;
}
}
}
}
if((inc[0]==0x100) && (dec[0]==0)){ //4
if((inc[1]==0) && (dec[1]==0)){
if((inc[2]==0) && (dec[2]==1)){
if((inc[3]==0x100) && (dec[3]==1)){
right = 0;
left = 1;
}
}
}
}
if((inc[0]==0) && (dec[0]==0)){ //5
if((inc[1]==0x100) && (dec[1]==0)){
if((inc[2]==0x100) && (dec[2]==1)){
if((inc[3]==0) && (dec[3]==1)){
right = 1;
left = 0;
}
}
}
}
if((inc[0]==0) && (dec[0]==0)){ //6
if((inc[1]==0) && (dec[1]==1)){
if((inc[2]==0x100) && (dec[2]==1)){
if((inc[3]==0x100) && (dec[3]==0)){
right = 0;
left = 1;
}
}
}
}
if((inc[0]==0x100) && (dec[0]==0)){ //7
if((inc[1]==0x100) && (dec[1]==1)){
if((inc[2]==0) && (dec[2]==1)){
if((inc[3]==0) && (dec[3]==0)){
right = 1;
left = 0;
}
}
}
}
if((inc[0]==0) && (dec[0]==1)){ //8
if((inc[1]==0x100) && (dec[1]==1)){
if((inc[2]==0x100) && (dec[2]==0)){
if((inc[3]==0) && (dec[3]==0)){
right = 0;
left = 1;
}
}
}
}
inc[0] = inc[1];
dec[0] = dec[1];
inc[1] = inc[2];
dec[1] = dec[2];
inc[2] = inc[3];
dec[2] = dec[3];
if(irq_num==1){
if(right==1)
key_value = 0x14;//int=20,正向遞增
else if(left==1)
key_value = 0x15;//int=21,逆向遞減
ready = 1;
wake_up_interruptible(&buttons_wait);
}
else
irq_num = 0;
enable_irq(irq);
//local_irq_restore(flags);
return IRQ_HANDLED;
}
我是對4種狀態(tài)一起比較的
我按上面處理方法能正常輸出,也不會(huì)出現(xiàn)誤碼,只是在轉(zhuǎn)換方向時(shí),不能立即變向,而是在兩次中斷后在換過來,
當(dāng)我只取其中兩位分別比較時(shí),能立即轉(zhuǎn)換方向,但會(huì)出現(xiàn)誤碼(即出現(xiàn)反向的輸出值)
請高手幫忙指點(diǎn)一下,或提供一下這方面的經(jīng)驗(yàn),在此感激不盡!謝謝! |
|