Display values from two PIC16F series controllers with one LCD display


Results 1 to 10 of 10

Threaded View

  1. #8
    Join Date
    Mar 2017
    Posts
    3


    Did you find this post helpful? Yes | No

    Default Re: Display values from two PIC16F series controllers with one LCD display

    Art -

    I completely agree with your assessment. Interfacing two channels of quadrature input is what I would prefer to do, however, I had huge issues just getting one to work reliably and fast! The current code interprets the quadrature signal (360 CPR) using ASM coded interrupt within PBP3 and it doesn't miss a beat! I was looking at another manufactures device and they actually do use two separate PICs with one LCD as I described in my original post. I agree this is a poor way to handle two inputs but after struggling for a couple of months with the existing code, I'm looking for whatever works at this point. I have to admit that the limitations I have are no more than my inexperience with PIC coding so far.

    The code I use is similar to this:
    Code:
    'Read Quadrature Encoder and display value on LCD in .25 increments. for pic16f76
    
     '************************ 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 '
     CCP1CON = 0
     CCP2CON = 0
     
     TRISA = %00000000 ' output ports
     TRISB = %11000000 ' set input and output ports
     TRISC = %00100000 ' output ports
      
     portB.4 = 0
     portB.5 = 0
     
     '************************ PROGRAM VARIABLES HERE ***************************
    
     symbol   ledUp     = portC.2 ' status led
     symbol   ledDown = portC.3 ' status led2
     symbol   lcdbkl     = portC.4 ' lcd pannel backlight
     symbol   sw1        = portC.5 ' encoder switch
     symbol   ledTest   = portC.6
     
    
     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
     enc_dir                VAR enc_old.bit7
     Counter               VAR word bank0
     enc_SIGN            VAR counter.bit15
     Sign                    VAR BIT
    
    
     '*********************** 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
     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   STATUS,Z           ;if result is not zero, 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 _ledDown ;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 _ledUp ;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
     INTCON = %10001000 ' Enable PortB Change Interupts 
     LCDOUT $FE,1 'Init The LCD
     pause 500 'wait for LCD to start 
    
     lcdout $FE,$80,  "TEST ANGLE DISP " 'display splash screen
     LCDOUT $FE,$C0,  "Initializing... " 
     high lcdbkl ' turn on backlight
    
    
     '************************** SET DEFAULT SETTINGS HERE **********************
     pause 2000 ' just wait a bit to read splash screen
     lcdout $FE,1
     enc_counter = 0 ' set default encoder value
     enc_counter_old = 0 
     Counter = 0
     
     
     lcdout $FE,$80, "Measurement   "
     lcdout $FE,$C0,"TST ANGLE: "
    
    
     '************************** TESTING ROUTINES HERE **************************
     test:
       If portC.5 = 0 then clearall
       
    if enc_counter <> enc_counter_old then 'see if value has changed
        enc_counter_old = enc_counter 'move new value to old
            Counter = enc_counter '(enc_counter */ 250)/2
            Sign = Counter.15   ' Save sign
            Counter = ((ABS Counter) * 25) ' Degrees is now 0 to 900
            
    
    If Sign THEN Counter = -Counter ' Restore sign, value is now -900 to 900
    
    
    If not sign AND (-Counter < 0 or Counter > 0) then
        lcdout $FE,$80, "Measurement   "
        lcdout $FE,$C0,"TST ANGLE:", "-",sdec Counter /100 , ".", sdec Counter // 100, " " 
    else
        lcdout $FE,$80, "Measurement   "
        lcdout $FE,$C0,"TST ANGLE:", " ", sdec -Counter /100 , ".", sdec -Counter // 100, " "
    endif 
    
     
     low ledUp 'turn off CCW led
     low ledDown 'turn off CW led
     endif
     
     goto test
    
     ClearAll:
     
        enc_counter = 0
        enc_counter_old = 0 
        Counter = 0
        clear
        lcdout $FE,$80, "Measurement   "
        lcdout $FE,$C0,"TST ANGLE:", " 0.00 "
            high ledtest
                pause 1000
            low ledtest
     goto test
     
    @INT_RETURN
    Last edited by CBRUN17; - 24th March 2017 at 18:05.

Similar Threads

  1. Trouble with LCD 2x8 and sequential display of values
    By fratello in forum mel PIC BASIC Pro
    Replies: 30
    Last Post: - 27th February 2012, 15:51
  2. LCD Display
    By lambert in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 16th January 2010, 23:18
  3. Replies: 2
    Last Post: - 5th November 2009, 18:07
  4. glcd display vs lcd display
    By davids in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 3rd July 2009, 19:16
  5. LCD Display - Which One
    By Switch in forum General
    Replies: 1
    Last Post: - 21st January 2009, 23:44

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