打印

编码器的配置,大家帮我看一下哪有错误???

[复制链接]
3150|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mzscg|  楼主 | 2008-8-29 09:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
 想使用判断左旋右旋计数那种的3脚编码器,当旋转的时候,其中两脚(1,3脚,用上拉电阻接到VDD,2脚是接地的)会产生电压变化,,,由他们之间的关系来判断是左旋还是右旋..
1,3脚的配置:
GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure Key Button GPIO Pin as input floating (Key Button EXTI Line) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

将1脚作为中断脚,,上面一有电平变化就发生中断:

 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource6);

  /* Configure Key Button EXTI Line to generate an interrupt on Rinsing or falling edge */  
  EXTI_InitStructure.EXTI_Line =  EXTI_Line6;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  /* Generate software interrupt: simulate a falling edge applied on Key Button EXTI line */
  EXTI_GenerateSWInterrupt(EXTI_Line6);

配置中断优先级:

  NVIC_InitTypeDef NVIC_InitStructure;
  

  /* Set the Vector Table base location at 0x20000000 */ 
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 


  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  /* Enable the EXTI9_5 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

中断服务程序如下,其中不包含消抖程序:

void EXTI9_5_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line6) != RESET)
  {
    /* Toggle GPIO_LED pin 6 */
    if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==0)    //先判断是高电平产生的中断还是低点平的中断  
    {
                if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==0)    //再判断B线上的电平    
                    { 
                    keycounter--;       
                     keydirection=0; 
                    }  
                else 
                    { 
                     keycounter++; 
                     keydirection=1; 
                    }          
    }
   else 
          
   {
     if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==0) 
            { 
             keycounter++;  
             keydirection=1; 
            }  
          else 
           { 
            keycounter--; 
            keydirection=0; 
           } 
   }     
    /* Clear the Key Button EXTI line pending bit */
    EXTI_ClearITPendingBit(EXTI_Line6);
  }
}





现在第一个问题是::

我没有旋转编码器的情况下:运行程序,计数值keycounter居然显示为1,百思不得其解,没有发生中断,,怎么会执行中断服务程序呢????
沙发
mzscg|  楼主 | 2008-8-29 09:45 | 只看该作者

好久没有回答我问题,

哈哈,,,期待大虾前来....估计小虾就能搞定.......

使用特权

评论回复
板凳
mzscg|  楼主 | 2008-8-29 09:54 | 只看该作者

看了手册,

手册在对外部中断的上升沿/下降沿触发时: 外部唤醒线是边沿触发的,这些线上不能出现毛刺信号.

我在想:
第一,我没有外部中断到来,,,,,,却有计数,,,,,是不是因为信号有毛刺引起的?
第二,我旋转以来,计数值远远大于我旋转的次数??

没有加消抖电路或者程序会对此产生很大的影响吗????

使用特权

评论回复
地板
mzscg|  楼主 | 2008-8-29 10:03 | 只看该作者

刚才又发现一个错误,,

 在外部中断配置时:

EXTI_GenerateSWInterrupt(EXTI_Line6);

这句会产生一个外部中断,,去除后,没有旋转编码器,,  计数却变为2了,,

奇怪了,,,,,,,,,,,,

使用特权

评论回复
5
mzscg|  楼主 | 2008-8-29 10:42 | 只看该作者

香水,,,,召唤香水..

香水兄最近很少露面啊..........

使用特权

评论回复
6
香水城| | 2008-8-29 10:48 | 只看该作者

少安毋躁,你一个小时中发了5个帖子,哈哈哈

使用特权

评论回复
7
mzscg|  楼主 | 2008-8-29 10:50 | 只看该作者

香水,,,我这个不是交的吧....

我也看过这篇日志了,,

要用TIME的计数,,,,

你看了我的程序了吗z///

我的这个比较简单,,这个就像是用来做音量控制那样,,,

只需判断两脚的电平关系就可以判断它是左旋还是右旋......

使用特权

评论回复
8
mzscg|  楼主 | 2008-8-29 10:53 | 只看该作者

这是这个玩意的一些知识,,,香水帮我看一下.

http://www.yeyudo.cn/article.asp?id=111

使用特权

评论回复
9
iammercy| | 2008-8-29 11:09 | 只看该作者

RE

WHEEL_DEBOUNCE_TIMER    EQU            3/1        ;3ms

;ClockWise:    11,01,00,10,11...
;AntiClockWise:    11,10,00,01,11...
;--------------------------------------------------------------------------------------
ScanWheelIO:
        andim        PIN_WHEEL_Cfg        ,(WHEELA+WHEELB)^0x0f
        orim        PIN_WHEEL        ,WHEELA+WHEELB
        lda        PIN_WHEEL        ,0
                  nop
        sta        zWheelTMP        ,0
        andim        zWheelTMP        ,WHEELA+WHEELB
        ;----- Result save in zWheelTMP-------
        rtni        
;======================================================================================
;            ScanWheel
;======================================================================================    
ScanWheel:
        ;whether ever get different Wheel value than the last Wheel state
        lda        zWdebounce        ,0    
        ;yes,check whether maintain stable
         ba0        ContinueScanWheel    
         ;no,check whether get different Wheel value    
LookUpWheelState:                    
        call        ScanWheelIO    
        eor        zWheelState        ,0    
        ;if different from the last stable state
        bnz        BeginScanWheel    
        ;if equal to the last state        
          jmp        Finish_ScanWheel
BeginScanWheel:
        ;save current state to zWheelState buffer
        lda        zWheelTMP            ,0
          sta        zWheelState        ,0    
          ;----- Reload Debounce counter and clear debounce done flag -----
        ldi        zWheelPeriod        ,WHEEL_DEBOUNCE_TIMER
        andim        zIntFlag        ,1101b
        ;----------------------------------------------------------------
         ;mark ever get different Wheel value than the last Wheel state flag
        orim        zWdebounce    ,0001b    
          jmp        Finish_ScanWheel               ;exit     
ContinueScanWheel:
        call        ScanWheelIO    
        eor        zWheelState        ,0
        ;if different from the last stable state again
        bnz        BeginScanWheel
        ;if still equal to the last state
DebounceScanWheel:
        ;the Wheel state must be stable here
        lda        zIntFlag        ,0
        ba1        $+2
        jmp        Finish_ScanWheel
        andim        zIntFlag        ,1101b
        ;Judge whether finish debouncing work.
        sbim        zWheelPeriod        ,01h
        baz        VerifyWheelValue
         jmp        Finish_ScanWheel
VerifyWheelValue:
        andim        zWdebounce    ,1110b
        ;whether state chage?
        lda        zWheelTMP    ,0
        eor        zWheelValue    ,0
        baz        Finish_ScanWheel
;judge clockWise or anti-clockWise
        sbi        zWheelTMP    ,0100b
        baz        ?mayBeAntiClockWise
        sbi        zWheelTMP    ,1000b    
        baz        ?mayBeClockWise
        jmp        ?next
?mayBeClockWise:
        sbi        zWheelValue    ,1100b
        bnz        ?next
        call        IncreaseIronSetpoint        ;refer to Iron.asm
        jmp        ?next
?mayBeAntiClockWise:
        sbi        zWheelValue    ,1100b
        bnz        ?next
        call        DecreaseIronSetpoint        ;refer to Iron.asm
?next:        
;save------------------------------------------------------------------------------------
SaveWheelState:
        ;curren state as stable state
        lda        zWheelTMP        ,0        
        sta        zWheelValue        ,0
Finish_ScanWheel:          
        call        ReturnToWorkState        ;refer to Iron.asm    
        jmp        Exit_ScanWheel        

使用特权

评论回复
10
mzscg|  楼主 | 2008-8-29 11:34 | 只看该作者

iammercy ,你给的程序,,,不适合我这个吧..

没注意看你的程序..

但不会跟我这个一样,,

你那个精度应该非常高.

使用特权

评论回复
11
mzscg|  楼主 | 2008-8-29 11:36 | 只看该作者

还有,,,我的编码器两个输入引脚都上拉了.

是不是应该将对应的GPIO配置为了,上拉输入??

还是配置为浮动输入??

使用特权

评论回复
12
mzscg|  楼主 | 2008-8-29 11:37 | 只看该作者

我这个编码应该是属于转一格计数一次那种,

手上没有datasheet,但感觉应该是这种..

使用特权

评论回复
13
mzscg|  楼主 | 2008-8-29 12:02 | 只看该作者

对了,,,,EXTI唤醒信号

EXTI唤醒线是边沿触发的,这些线上不能出现毛刺信号.


我用示器测触发信号上是有毛刺,,但很小,,,,,

这样也能触发???

但程序运行时,,确实是触发了...

如何解决,,,接一个瓷片电容就能解决毛刺??

使用特权

评论回复
14
iammercy| | 2008-8-29 12:59 | 只看该作者

RE

就是那种3个脚的偏码器,其实有5个脚,2个脚是用来固定的,1个是接GND,另外2个是A和B

AB这2个脚直接接到MCU输入脚,如果IO有内部上拉就不需要用外部上拉电阻了
平时的时候AB都是高电平,当转动的时候,AB会先后出现低电平,转动结束又回到高电平

AB出现低电平的先后次序可以用来判断正反转

对于AB的状态,只有当:
11 -> 01 认为是正转
11 -> 10 认为是反转

其余状态的切换情况忽略

去抖时间为3ms

其实可以用一个通用的去抖模型来表达
去抖模型:暫態,緩沖態,穩定態,去抖標志,去抖時間 

當緩沖態與暫態不一致的時:緩沖態<=暫態,置去抖標志,初始化去抖時間,開始去抖

當緩沖態與暫態在整個去抖時間內都保持一致時:清去抖標志,把狀態保存為穩定態,結束去抖,同時對穩定態進行分析

對于旋轉編碼器,暫態就是讀取 2個旋轉開關IO的狀態,去抖時間設置為3ms
去抖結束后:根據穩定態和緩沖態進行上一次和這一次狀態的比較
這次是01,上一次是11,判斷為正轉
這次是10,上一次是11,判斷為反轉
其它情況不處理
最后 穩定態<=緩沖態

使用特权

评论回复
15
mzscg|  楼主 | 2008-8-29 14:23 | 只看该作者

回iammercy ,

平时的时候AB都是高电平,当转动的时候,AB会先后出现低电平,转动结束又回到高电平
???

我这个转动之后没有恢复到高电平耶......

转后是什么状态就是什么状态,,,

没有都恢复到高电平,,


你说的转动结束是指转一圈??

使用特权

评论回复
16
uuchy000| | 2008-8-29 14:43 | 只看该作者

re

a,b经由hc14施密特触发器整形试试看

使用特权

评论回复
17
iammercy| | 2008-8-29 18:01 | 只看该作者

RE

轉動過程中,AB會分別與地接通,轉動后回到高電平
轉一小格,看看示波器就知道了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

51

主题

234

帖子

0

粉丝