Control a Radio PLL with a PIC


Results 1 to 40 of 54

Threaded View

  1. #5
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default Re: Control a Radio PLL with a PIC

    Quote Originally Posted by cncmachineguy View Post
    Joe, How fast are you spinning the encoder? How many CPR? I have been using 500 line (2000 CPR) encoder for a gate position applacation for about 6-7 years now. No bounce because they are optical. never lose any pulses, but they are going pretty slow. (30RPM) 1000 cps. I am doing this with 16F676, no interrupts just checking the A-B states in my main. It is a fast main loop but never the less. Oh and running on 4Mhz internal OSC
    Hi, I am using the "El Cheapo" mechanical encoders similar to a rotory switch, just 3 terminals A com B tried both kinds gray scale and quatdradture. I think it is losing counts during the serout routine, it should not but it does, again it could be noisy encoder too, I will know better when I get those PICs next week. I have some optical encoders here, but they have a bizillion steps per rev. These switch type have 24.
    Here is the code:
    Code:
    @ __config _HS_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF  & _CP_OFF & _FCMEN_OFF & _BOR_OFF
    
    '************************ DEFINES HERE *************************************
    DEFINE OSC 20               ' set to 20mhz
    INCLUDE "MODEDEFS.BAS"
    clear                       ' clear out variables
     DEFINE DEBUG_REG PORTC
     DEFINE DEBUG_BIT 6
     DEFINE DEBUG_BAUD 19200
     DEFINE DEBUG_MODE 0
    
    '********************** PIC16F690 setup ************************************
    ADCON0  = 0
    ADCON1  = 0
    ANSEL   = 0
    ANSELH  = 0
    CM1CON0 = 0
    CM2CON0 = 0
    
    TrisA = %00000000
    TrisB = %11000000 
    TrisC = %00000000
    
    '*********************** 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
    ssave   var     byte bank0 system
    psave   var     byte bank0 system     
    
    '***************************************************************************
    enc_old         VAR BYTE
    enc_new         VAR BYTE
    enc_tmp         var byte
    enc_counter     VAR BYTE
    enc_counter_old VAR BYTE
    enc_scaler      var BYTE
    Display         Var Byte
    
    INTCON = %10001000      ' Enable PortB Change Interupts  
    IOCB   = %11000000
    pause 5500            ' wait for LCD to start 
    
    goto start            'skip over interupt handler
    '*********************** ASSEMBLY INTERUPT HANDLER *************************
    
    define  INTHAND myint
    Asm
           
    myint 
        
    
    
    
        ;====== 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.
            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
                                       ;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, RABIF          ; Clear the Interupt Flag
            RETFIE                             ; Return from interrupt
    endasm
    
    '***************************************************************************
    '************************* PROGRAM STARTS HERE *****************************
    '***************************************************************************
    
    START:              ' Main Program starts here
    
    
    
    
    enc_counter     = 0    ' set default encoder value
    enc_counter_old = 0
       ' DEBUG 254,2,  "ENCODER             "  ' change display
       ' DEBUG 254,192,#Display,"                 "
       ' DEBUG 254,148,"                    "  ' clear display
       ' DEBUG 254,212,"                    "    
        
    MAIN:  'see if value has changed
        if  enc_counter <> enc_counter_old then enc_counter_old = enc_counter
        Display = (enc_counter/2)
        
    
       
                     
        DEBUG 254,2,"ENCODER             "          ' change display
        DEBUG 254,192,#Display,"                  "
        DEBUG 254,148,"                    "  ' clear display
        DEBUG 254,212,"                    "      ' display enc_counter value
        sound portC.7,[display,1]           
                    
    goto MAIN
    Got it here, more or less: http://www.picbasic.co.uk/forum/showthread.php?t=9700

    It actually works a bit better using serout instead of debug, at least as far as the display goes, but is faster using debug, in terms of how fast the loop cycles.
    I really have not invested that much time into it.
    Last edited by Archangel; - 11th June 2011 at 07:13.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

Members who have read this thread : 0

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