帮忙看看这个正交解码程序有什么问题
/******************************************************************************2个输入引脚:
EINT8-----( GPF)---A Phase
EINT11 -----( GPF)---B Phase
4倍频检测,A相和B相的边沿进行中断,通过读取超前和滞后状态确定方向
*******************************************************************************/
/*********************************[边沿触发中断处理程序]*********************************************/
static void __irq Decode_ISR(void)
{
U32 r;
U8 n;
EnterCritical(&r);
ClearPending(BIT_EINT8_23);//清除中断标志位
if(rEINTPEND&(1<<8))//用户手册V1.3 P307
{
rEINTPEND |= 1<< 8;
if (rGPGDAT&(1<<0))//若A为上升沿
{
for(n=0;n<200;n++)
{
__asm{NOP;}
}
if (rGPGDAT&(1<<0))
{
if(rGPGDAT&(1<<3))//上升沿且B相为高
{
count --;
dir = ccw;
// Uart_Printf( "A 1 Motion occur!... Pulse count: %d \n Dir: %d\n", count,dir) ;
}
else //上升沿且B相为低
{
count ++;
dir = cw;
// Uart_Printf( "A2 Motion occur!... Pulse count: %d \n Dir: %d\n", count,dir) ;
}
}
}
else
{
for(n=0;n<200;n++)
{
__asm{NOP;}
}
if( !(rGPGDAT&(1<<0)))
{
if(rGPGDAT&(1<<3))//下降沿且B相为高
{
count ++;
dir = cw;
// Uart_Printf( "A 3Motion occur!... Pulse count: %d \n Dir: %d\n", count,dir) ;
}
else //下降沿且B相为低
{
count --;
dir = ccw;
// Uart_Printf( "A 4 Motion occur!... Pulse count: %d \n Dir: %d\n", count,dir) ;
}
}
}
}
if(rEINTPEND&(1<<11))
{
rEINTPEND |= 1<<11;
if (rGPGDAT&(1<<3))//若为上升沿
{
for(n=0;n<200;n++)
{
__asm{NOP;}
}
if (rGPGDAT&(1<<3))
{
if(rGPGDAT&(1<<0))//上升沿且A相为高
{
count ++;
dir = cw;
// Uart_Printf( "B1 Motion occur!... Pulse count: %d \n Dir: %d\n", count,dir) ;
}
else //上升沿且A相为低
{
count --;
dir = ccw;
// Uart_Printf( "B2 Motion occur!... Pulse count: %d \n Dir: %d\n", count,dir) ;
}
}
}
else
{
for(n=0;n<200;n++)
{
__asm{NOP;}
}
if (!(rGPGDAT&(1<<3)))
{
if(rGPGDAT&(1<<0))//下降沿且A相为高
{
count --;
dir = ccw;
//Uart_Printf( "B3 Motion occur!... Pulse count: %d \n Dir: %d\n", count,dir) ;
}
else //下降沿且A相为低
{
count ++;
dir = cw;
//Uart_Printf( "B4 Motion occur!... Pulse count: %d \n Dir: %d\n", count,dir) ;
}
}
}
}
ExitCritical(&r);
}
/*********************************[中断检测函数]*********************************************/
void KeyScan_Test(void)
{
Uart_Printf("\nKey Scan Test, press ESC key to exit !\n");
rGPGCON = rGPGCON & (~((3<<6)|(3<<0))) | (2<<6)|(2<<0) ; //GPG0 3 set EINT 用户手册V1.3 P293
rEXTINT1 = rEXTINT1 &( ~((0xf<<0)|(0xf<<12)))|(0xe<<0)|(0xe<<12);//用户手册V1.3 P301
//set eint8 11 both edge int
rEINTPEND |= (1<<8)|(1<<11); //clear eint 4用户手册V1.3 P307
rEINTMASK &= ~((1<<8)|(1<<11)); //enable eint 4
ClearPending(BIT_EINT8_23);
pISR_EINT8_23 = (U32)Decode_ISR;
EnableIrq(BIT_EINT8_23); //打开中断
while( Uart_GetKey() != ESC_KEY ) ;//一直在此处循环,直到ESC按下
Uart_Printf( "B4 Motion occur!... Pulse count: %d \n Dir: %d\n", count,dir) ;
count = 0;
DisableIrq(BIT_EINT8_23);//关闭IRQ中断
}
用S3C2440来做的,其中
FCLK =400000000 Hz
PCLK =50000000 Hz
HCLK =100000000 Hz
用来读取伺服电机驱动器输出的编码器信号,正交编码信号
现在的问题就在于中断过于频繁,计数脉冲也不准确 http://cache.amobbs.com/bbs_upload782111/files_30/ourdev_561007.JPG
(原文件名:未命名.JPG) 为啥在中断里面干这么多事情啊? 能给个其它方法的思路吗 找个带QEP抓捕功能的ARM吧,STM32应该有的,这样处理起来容易些的。
http://cache.amobbs.com/bbs_upload782111/files_30/ourdev_561133.jpg
(原文件名:QEP.jpg) 现在打算使用正交解码芯片HCTL-2032,不知道有用过该芯片的朋友没有 HCTL-2032 性能好 价格高 货也不好找 HCTL-2032确实货源不好找,那有什么比较好找的正交解码芯片吗?麻烦推荐一下 请参考这个贴 http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3219450&bbs_page_no=1&search_mode=4&search_text=wang_xm&bbs_id=9999 谢谢楼上 /******************************************************************************
2个输入引脚:
EINT8-----( GPF)---A Phase
EINT11 -----( GPF)---B Phase
4倍频检测,A相和B相的边沿进行中断,通过读取超前和滞后状态确定方向
对于A信号的外中断来说,每一个变化的边沿都检查A,B两个信号电平
是否相同,相同则计数器减小,不同则计数器增加;对于B信号的外中断来说,每一个变化的边沿都检测A、B两信号电
平是否相同,相同则计数器增加,不同则计数器减小。
******************************************************************************/
/*********************************[边沿触发中断处理程序]*********************************************/
static void __irq Decode_ISR(void)
{
U32 r;
EnterCritical(&r);
ClearPending(BIT_EINT8_23);//清除中断标志位
if(rEINTPEND&(1<<8))//用户手册V1.3 P307
{
rEINTPEND |= 1<< 8;
if ((rGPGDAT&(1<<0))==(rGPGDAT&(1<<3)))
{
count--;
dir = ccw;
}
else
{
count++;
dir = cw;
}
}
if(rEINTPEND&(1<<11))
{
rEINTPEND |= 1<< 8;
if ((rGPGDAT&(1<<0))==(rGPGDAT&(1<<3)))
{
count++;
dir = cw;
}
else
{
count--;
dir = ccw;
}
}
ExitCritical(&r);
}
/*********************************[中断检测函数]*********************************************/
void KeyScan_Test(void)
{
Uart_Printf("\nKey Scan Test, press ESC key to exit !\n");
rGPGCON = rGPGCON & (~((3<<6)|(3<<0))) | (2<<6)|(2<<0) ; //GPG0 3 set EINT 用户手册V1.3 P293
rEXTINT1 = rEXTINT1 &( ~((0xf<<0)|(0xf<<12)))|(0xe<<0)|(0xe<<12);//用户手册V1.3 P301
//set eint8 11 both edge int
rEINTPEND |= (1<<8)|(1<<11); //clear eint 4用户手册V1.3 P307
rEINTMASK &= ~((1<<8)|(1<<11)); //enable eint 4
ClearPending(BIT_EINT8_23);
pISR_EINT8_23 = (U32)Decode_ISR;
EnableIrq(BIT_EINT8_23); //打开中断
while( Uart_GetKey() != ESC_KEY ) ;//一直在此处循环,直到ESC按下
Uart_Printf( "B4 Motion occur!... Pulse count: %d \n Dir: %d\n", count,dir) ;
count = 0;
DisableIrq(BIT_EINT8_23);//关闭IRQ中断
}
现在修改为这样,但是可能是由于干扰,造成不断计数,不知道有什么好办法没有 解决了么?
页:
[1]