gujingji 发表于 2010-6-10 17:00:45

帮忙看看这个正交解码程序有什么问题

/******************************************************************************
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
用来读取伺服电机驱动器输出的编码器信号,正交编码信号

现在的问题就在于中断过于频繁,计数脉冲也不准确

gujingji 发表于 2010-6-10 17:15:31

http://cache.amobbs.com/bbs_upload782111/files_30/ourdev_561007.JPG
(原文件名:未命名.JPG)

oldtom 发表于 2010-6-10 19:46:50

为啥在中断里面干这么多事情啊?

gujingji 发表于 2010-6-10 20:36:51

能给个其它方法的思路吗

suntime 发表于 2010-6-11 11:41:32

找个带QEP抓捕功能的ARM吧,STM32应该有的,这样处理起来容易些的。

http://cache.amobbs.com/bbs_upload782111/files_30/ourdev_561133.jpg
(原文件名:QEP.jpg)

gujingji 发表于 2010-6-11 22:01:48

现在打算使用正交解码芯片HCTL-2032,不知道有用过该芯片的朋友没有

wang_xm 发表于 2010-6-11 22:55:16

HCTL-2032 性能好 价格高 货也不好找

gujingji 发表于 2010-6-12 09:41:07

HCTL-2032确实货源不好找,那有什么比较好找的正交解码芯片吗?麻烦推荐一下

wang_xm 发表于 2010-6-12 14:14:39

请参考这个贴 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

gujingji 发表于 2010-6-12 16:37:49

谢谢楼上

gujingji 发表于 2010-6-12 17:12:50

/******************************************************************************
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中断       

}
现在修改为这样,但是可能是由于干扰,造成不断计数,不知道有什么好办法没有

eworker 发表于 2010-8-5 06:14:39

解决了么?
页: [1]
查看完整版本: 帮忙看看这个正交解码程序有什么问题