Examples Index

' =========================================================================
'
'   File...... ENCODER.SXB
'   Purpose... Grayhill 25LB10-Q Encoder Demo
'   Author.... (c) Parallax, Inc. -- All Rights Reserved
'   E-mail.... support@parallax.com
'   Started...
'   Updated... 05 JUL 2006
'
' =========================================================================

' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' Reads a Grayhill 25LB10-Q quadrature encode and displays a value on
' three 7-segment LEDs.  When the value is zero, the display reads "OFF."
' Reading the encoder and multiplexing the displays is handled in the
' "background" with an ISR.

' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

DEVICE          SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ            4_000_000
ID              "ENCODER"

' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------

EncPort         VAR     RA                      ' encoder port
TRIS_Enc        VAR     TRIS_A
Cathodes        VAR     RB                      ' LED cathodes
TRIS_Cath       VAR     TRIS_B
Anodes          VAR     RC                      ' LED anodes
TRIS_Ano        VAR     TRIS_C

' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

Blank           CON     %00000000               ' all segs off
Ltr_O           CON     %00111111               ' pattern for "O"
Ltr_F           CON     %01110001               ' pattern for "F"

Yes             CON     1
No              CON     0

MaxVal          CON     100

' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

display         VAR     Byte(3)                 ' multiplexed segments
digPntr         VAR     Byte                    ' digit pointer
digLimit        VAR     Byte                    ' 0 - 2

flags           VAR     Byte
newVal          VAR     flags.0

encCheck        VAR     Byte
encOld          VAR     Byte                    ' previous encoder bits
encNew          VAR     Byte                    ' new encoder bits
encValue        VAR     Byte                    ' encoder value

tmpB1           VAR     Byte
tmpB2           VAR     Byte
tmpB3           VAR     Byte

' -------------------------------------------------------------------------
  INTERRUPT
' -------------------------------------------------------------------------

' Runs every 64 uS @ 4 MHz (no prescaler)

ISR_Start:
  encNew = EncPort & %00000011                  ' get econder bits
  tmpB3 = encOld XOR encNew                     ' test for change
  IF tmpB3 > 0 THEN                             ' change?
    encOld = encOld << 1                        ' adjust old bits
    encOld = encOld XOR encNew                  ' test direction
    IF encOld.1 = 1 THEN
      IF encValue < MaxVal THEN                 ' if max, no change
        INC encValue                            ' increase value
        newVal = 1                              ' alert "foreground"
      ENDIF
    ELSE
      IF encValue > 0 THEN                      ' if 0, no change
        DEC encValue                            ' decrease value
        newVal = 1                              ' alert "foreground"
      ENDIF
    ENDIF
    encOld = encNew                             ' save last input
  ENDIF

Update_Display:
  INC digPntr                                   ' point to next digit
  IF digPntr = digLimit THEN                    ' update digit
    digPntr = 0                                 ' wrap if needed
  ENDIF
  Anodes = Blank                                ' blank display
  READ DigCtrl + digPntr, Cathodes              ' select display element
  Anodes = display(digPntr)                     ' output new digit segs

ISR_Exit:
  RETURNINT

' =========================================================================
  PROGRAM Start
' =========================================================================

' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------

UPDATE_ABUF     SUB     0                       ' update anode buffer

' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  Anodes = Blank                                ' clear LEDs
  TRIS_Ano = %00000000                          ' make anode ctrl outputs
  Cathodes = %111                               ' all digits off
  TRIS_Cath = %11111000                         ' make cath ctrl outputs
  encNew = EncPort & %00000011                  ' read encoder pos
  encOld = encNew                               ' copy
  encValue = 0                                  ' clear value
  UPDATE_ABUF                                   ' update display char buf
  OPTION = $88                                  ' interrupt, no prescaler

Main:
  DO
    IF newVal = Yes THEN                        ' check flag
      UPDATE_ABUF                               ' refresh display buffer
    ENDIF
  LOOP

' -------------------------------------------------------------------------
' Subroutine Code
' -------------------------------------------------------------------------

UPDATE_ABUF:
  IF encValue = 0 THEN
    PUT display(0), Ltr_F, Ltr_F, Ltr_O         ' if 0, show "OFF"
    digLimit = 3
  ELSE
    digLimit = 1                                ' at least one digit
    IF encValue > 9 THEN                        ' into 10s?
      INC digLimit                              ' -- yes, show another digit
    ENDIF
    IF encValue > 99 THEN                       ' into 100s?
      INC digLimit                              ' -- yes, show another digit
    ENDIF
    tmpB1 = encValue                            ' convert value to segments
    tmpB2 = tmpB1 / 100
    tmpB1 = __REMAINDER
    READ SegMaps + tmpB2, display(2)
    tmpB2 = tmpB1 / 10
    tmpB1 = __REMAINDER
    READ SegMaps + tmpB2, display(1)
    READ SegMaps + tmpB1, display(0)
  ENDIF
  newVal = No                                   ' clear flag
  RETURN

' =========================================================================
' User Data
' =========================================================================

SegMaps:                                        ' segments maps
'        .gfedcba
  DATA  %00111111                               ' 0
  DATA  %00000110                               ' 1
  DATA  %01011011                               ' 2
  DATA  %01001111                               ' 3
  DATA  %01100110                               ' 4
  DATA  %01101101                               ' 5
  DATA  %01111101                               ' 6
  DATA  %00000111                               ' 7
  DATA  %01111111                               ' 8
  DATA  %01100111                               ' 9
  DATA  %01110111                               ' A
  DATA  %01111100                               ' b
  DATA  %00111001                               ' C
  DATA  %01011110                               ' d
  DATA  %01111001                               ' E
  DATA  %01110001                               ' F

DigCtrl:
  DATA  %11111110                               ' column 0 on
  DATA  %11111101
  DATA  %11111011