decoding quadrature encoders


Results 1 to 40 of 94

Threaded View

  1. #15
    cbrun17's Avatar
    cbrun17 Guest


    Did you find this post helpful? Yes | No

    Default Re: decoding quadrature encoders

    Hi Richard,

    Here is what I've done so far. Since I'm just learning asm (and coding in general), I made the changes you suggested as I understand them (haven't tried to compile yet). The part I am still not too sure about is the reference to is testing bit7. Are you saying I should not be testing bit7 (btfsc _enc_old,7)? How do I reference this in the asm code?

    I've tried going through this step by step and it's starting to make a little sense. I guess until I've done this a few times, I'll have to ask some lame questions....

    Again, I really appreciate your input.

    Code:
    'Read Quadrature Encoder and display value on LCD. for ****pic16f876****
    
    '************************ DEFINES HERE *************************************
    DEFINE OSC 20               ' set to 20mhz
    DEFINE LCD_DREG PORTA       ' Set Data Registers port
    DEFINE LCD_DBIT 0           ' Set starting data bit
    DEFINE LCD_RSREG PORTB      ' Set LCD RS Port
    DEFINE LCD_RSBIT 1          ' Set LCD RS Bit
    DEFINE LCD_EREG PORTB       ' Set LCD Enable Port
    DEFINE LCD_EBIT 2           ' Set LCD Enable Bit
    DEFINE LCD_BITS 4           ' Set LCD 4bit Mode
    DEFINE LCD_LINES 2          ' Set number of LCD Lines
    DEFINE LCD_COMMANDUS 2000   ' Set Command Delay time in uS
    DEFINE LCD_DATAUS 60        ' Set Data delay time in uS 
    
    clear                       'clear out variables
    
    '*********************** CHIP REGISTER SETUP *******************************
    
    ADCON0 = 7              ' turn off analog porta, set to digital IO
    ADCON1 = 7              '
    CMCON =  7              ' Turn off Port A Comparator
    TRISA = 0               ' output ports
    TRISB = %11000001       ' set input and output ports
    TRISC = 0               ' output ports
    
    '************************ PROGRAM VARIABLES HERE ***************************
    
    symbol led = portc.2         ' status led
    symbol led2 = portc.0       ' status led2
    symbol lcdbkl = portc.7     ' lcd pannel backlight
    symbol sw1 = portb.0       ' encoder switch
    
    enc_old 	          VAR     BYTE
    enc_new 	          VAR     BYTE
    enc_tmp 	          VAR     BYTE
    enc_counter 	  	  VAR    WORD bank0
    enc_counter_old  	  VAR    WORD bank0
    enc_scaler 	  	  VAR    WORD bank0
    
    
    '*********************** ASSEMBLY INTERUPT VARIABLES ***********************
    wsave     VAR     byte $20 system
    wsave1    VAR     byte $a0 system  ' Necessary for devices with RAM in bank1
    wsave2    VAR     byte $120 system ' Necessary for devices with RAM in bank2
    wsave3    VAR     byte $1a0 system ' Necessary for devices with RAM in bank3
    ssave     VAR     byte bank0 system
    psave     VAR     byte bank0 system     
    
        goto start			'skip over interupt handler
    
    '*********************** ASSEMBLY INTERUPT HANDLER *************************
    
    define  INTHAND myint
    Asm
           
    myint 
    	; Save W, STATUS and PCLATH registers
    	; Not Necessary for Chips with >2k of Codespace
    	
    	; ****Changed from original isr initialization settings****
            ;movwf   wsave
            ;swapf   STATUS, W
            ;clrf    STATUS
            ;movwf   ssave
            ;movf    PCLATH, W
            ;movwf   psave  
             
    ; Changed from original isr initialization settings
    	movwf wsave
     	swapf STATUS, W
     	clrf STATUS
     	movwf ssave
     	movf PCLATH, W
     	movwf psave 
     	CLRF PCLATH
    
    
    	;====== BEGINNING OF THE ROTARY ENCODER CODE ========
    	;The Rotary Encoder is connected to PORTB  
    	;The A signal of the encoder connected to the PIN portB.7
    	;The B signal of the encoder connected to the PIN portB.6
    	;
    	;The 4 variables used are declared in the PicBasic code.
    	;
    	;	enc_new VAR BYTE
    	;	enc_old VAR BYTE
    	;       enc_tmp VAR BYTE
    	;	enc_counter VAR WORD
    	;
    	;================================================
    		
    	   ;Read latest input from PORTB & put the value in _enc_new.
         	movf    PORTB,W
         	movwf  _enc_new
    
         	;Strip off all but the 2 MSBs in _enc_new.
         	movlw	0xc0    	     ;Create bit mask (bits 7 & 6). b'11000000' ?
         	andwf   _enc_new,F       ;Zero bits 5 thru 0.
    
            ;check to see if encoder has moved
            movf    _enc_old,W         ;move enc_old to W
            movwf   _enc_tmp           ;put W to enc_tmp
            movf    _enc_new,W         ;move enc_new to W for XOR
            xorwf   _enc_tmp,F         ;XOR enc_tmp to detect encoder movement
            btfsc   _enc_tmp,7         ;if bit is clear, encoder moved.       ************Not sure what needs to happen here**************
            goto    Continue           ;no movement exit isr
    
         	;Determine the direction of the Rotary encoder.  
         	rlf     _enc_old,F     	 ;left shift it into _enc_old to align bit 6 of 
                                     ;_enc_old with bit 7 of _enc_new.
    
         	movf    _enc_new,W     	 ;Move the contents of _enc_new to W in order to XOR.
         	xorwf   _enc_old,F    	 ;XOR previous inputs (in _enc_old) with latest
                                     ;inputs (in W) to determine CW or CCW.
     
          	btfsc   _enc_old,7     	 ;Test bit 7 of result (in _enc_old).  Skip next line ************Not sure what needs to happen here**************
          	                         ;if it is 0 (direction is CCW).
         	goto    Up               ;Bit is 1 (direction is CW).  Go around Down
                                     ;and increment counter.
    
    Down
         	;Decrements _enc_counter because the rotary encoder moved CCW.
    	    ;Decrements _enc_counter (16 bit value), sets Z on exit.
    	     	 
            decf    _enc_counter,F      ; Decrement low byte
            incfsz  _enc_counter,W      ; Check for underflow
            incf    _enc_counter+1,F    ; Update
            decf    _enc_counter+1,F    ; Fixup
            movf    _enc_counter,W
            iorwf   _enc_counter+1,W    ; Set Z bit
    
    		
    	    ;Add here code for the CCW LED if needed.
         	bsf     _led		    ;turn on led
         	
         	goto    Continue  	    ;Branch around UP.
    
    Up
            ;Increments _enc_counter because the rotary encoder moved CW.
            ;Increments _enc_counter (16 bit value), sets Z on exit.
    
            incfsz  _enc_counter,W      ; Add one to low byte
            decf    _enc_counter+1,F    ; No carry (negates next step)
            incf    _enc_counter+1,F    ; Add one to high byte
            movwf   _enc_counter        ; Store updated low byte back.
            iorwf   _enc_counter+1,W    ; Set Z flag
    
    		
    	   ;Add here code for the CW LED if needed.
    	   bsf     _led2		    ;turn on led
    	
    Continue     	
         	;Assign the latest encoder inputs (in _enc_new) to _enc_old.
         	movf 	_enc_new,W
         	movwf   _enc_old
    
            ; Restore saved registers
            movf    psave, W
            movwf   PCLATH
            swapf   ssave, W
            movwf   STATUS
            swapf   wsave, F
            swapf   wsave, W
            bcf     INTCON, RBIF		  ; Clear the Interupt Flag
            RETFIE                 	  	  ; Return from interrupt
    endasm
    
    '***************************************************************************
    '************************* PROGRAM STARTS HERE *****************************
    '***************************************************************************
    
    START:              ' Main Program starts here
    
       LCDOUT $FE,1		'Init The LCD
          pause 500		    'wait for LCD to start 
    
       LCDOUT $FE,1,"ENCODER"	    'display splash screen
       LCDOUT $FE,$C0," TEST "       
         high lcdbkl                 ' turn on backlight
    
    
    '************************** SET DEFAULT SETTINGS HERE **********************
    pause 1000		    ' just wait a bit to read splash screen
    enc_counter = 0	' set default encoder value
    enc_counter_old = 0	
    
            ' Initial display
        LCDOUT $FE,1,"ENCODER"  ' Initial display
        LCDOUT $FE,$C0, "00.00"
    
    INTCON = %10001000      ' Enable PortB Change Interupts  
    
    
    '************************** TESTING ROUTINES HERE **************************
    
    test:
    	  
                if buffered_enc_counter <> enc_counter_old then 'see if value has changed
                   	'enc_counter_old = enc_counter 'move new value to old ******Removed this line and replaced with*******
                     
                    gosub get_enc_count                                  '******this line******************************
    
     		 Counter = buffered_enc_counter
     
     		Sign = Counter.15 ' Save sign
     		Counter = ((ABS Counter) * 5) ' Degrees is now 0 to 900
     	If Sign THEN Counter = -Counter ' Restore sign, value is now -900 to 900
    
     	   If NOT sign then
     		LCDOUT $FE,1, sdec Counter /10 , ".", sdec Counter // 10 
     	   else
     		LCDOUT $FE,1, "-", sdec -Counter /10 , ".", sdec -Counter // 10
     	   endif
    
    '*********************************************************************************
    
                    low led		                        'turn off CCW led
                    low led2	                        'turn off CW led
                endif
    goto test
    
    get_enc_count:
     intcon.3=0 ; rbc_int off
     buffered_enc_counter=enc_counter
     intcon.3=1 ; rbc_int on
     return
    Last edited by cbrun17; - 9th February 2017 at 18:08.

Similar Threads

  1. Quick thoughts: DT Ints with encoders
    By kevlar129bp in forum mel PIC BASIC Pro
    Replies: 19
    Last Post: - 7th January 2010, 01:01
  2. PMDC SERVO MOTOR WITH quadrature encoder DRIVE ?
    By phoenix_1 in forum Schematics
    Replies: 37
    Last Post: - 22nd November 2009, 19:45
  3. 32-bit Quadrature Counter With Serial Interface
    By precision in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 10th June 2008, 02:49
  4. quad encoders
    By cpayne in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 13th March 2007, 17:49
  5. "momentary" IR decoding
    By sporker in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 20th June 2005, 01:53

Members who have read this thread : 4

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts