Skip to content

Instantly share code, notes, and snippets.

@mgwalker
Last active April 17, 2018 17:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgwalker/ef0779468614fffb5bb6c79cb73c1d21 to your computer and use it in GitHub Desktop.
Save mgwalker/ef0779468614fffb5bb6c79cb73c1d21 to your computer and use it in GitHub Desktop.
; Written: Fall 2003
; Location: Mississippi State University
; For: ECE 4532, CPE Design I
; Instructor: Dr. Joe Picone
;
; Description: Converts analog signals from fiber
; optic dataglove into digital signals and
; communicates the digital information to a PC
; over a RS232 (serial port) link. The code
; assumes a 14.7456MHz clock.
;
cblock 20h
AD_SELECT ; Which A/D input to sample
AD_SELECTM ; The manipulated A/D input select
AD_BASESET ; The base setup for the A/D control register 0
AD_HIGH ; High byte of the A/D conversion
AD_LOW ; Low byte of the A/D conversion
JOINT_ID ; ID of the joint being transmitted
JOINT_IDM ; Manipulated ID
endc
INCLUDE "p16c773.inc"
ORG 0
BCF STATUS, RP1 ; Disable banks 2 and 3
BSF STATUS, RP0 ; Select bank 1
MOVLW 0x80
MOVWF ADCON1 ; Setup A/D control register 1
MOVWF TRISC ; Setup I/O pins (TX/RX)
MOVLW 0x0F ; Setup analog pins as inputs
MOVWF TRISA
MOVLW 0x00
MOVWF TRISB
MOVLW 0x07 ; Setup the USART to high speed
MOVWF SPBRG ; asynchronous mode at 115,200
BSF TXSTA, BRGH ; baud. Max refresh rate is
BCF TXSTA, SYNC ; 480 samples/sec
; -----------------------------------------------
; High Speed SPBRG Values
; -----------------------------------------------
; Baud SPBRG Max Refresh
; 9600 95 (0x57) 40 samples/sec
; 19200 47 (0x2F) 80 samples/sec
; 38400 23 (0x17) 160 samples/sec
; 57600 15 (0x0F) 240 samples/sec
; 115200 7 (0x07) 480 samples/sec
BCF STATUS, RP0 ; Select bank 0
MOVLW 0x80
MOVWF PORTB
MOVLW 0x00
MOVWF AD_SELECT ; Initialize the A/D select
MOVWF JOINT_ID ; and Joint ID
MOVLW 0x80 ; Set the A/D base setup for control
MOVWF AD_BASESET ; register 0 into a variable
MOVWF ADCON0 ; Setup A/D control register 0
CLRF PORTC
BSF RCSTA, SPEN
BSF STATUS, RP0
BSF TXSTA, TXEN
BCF STATUS, RP0
;-------------------
MOVF AD_SELECT, W ; Prepare A/D select. It must
MOVWF AD_SELECTM ; be of the form xx21 0x3x
RLF AD_SELECTM, F ; where the numbers denote bits
RLF AD_SELECTM, F ; of the A/D select and an x denotes
RLF AD_SELECTM, F ; a zero. For example, if the A/D
; BTFSC AD_SELECTM, 0x6 ; select is 7 (0000 0111), the
; BSF AD_SELECTM, 0x1 ; modified select register should
; BCF AD_SELECTM, 0x6 ; be: 0011 1000
MOVF AD_BASESET, W ; Set the A/D control register 0
MOVWF ADCON0 ; to the base setting.
MOVF AD_SELECTM, W
IORWF ADCON0, F ; OR the A/D control register 0 with
BSF ADCON0, ADON ; the modified A/D select
; INCF AD_SELECT, F ; Increment the A/D select
; 24 instructions must pass before this
; analog input is ready:
; 1 instruction = 4 Tosc
; 1 Tad = 32 Tosc
; 1 Tad = 8 instructions
; Settle time = 3 Tad = 24 instructions
; Conversion time = 12 Tad = 96 instructions
;
; Tad ~= 2.17us
; Settle Time ~= 6.51us
; Conversion Time ~= 26.04us
;
; At 19200 baud, a byte is transmitted in 416us.
; Sending three bytes per finger, all the A/D
; delays are built into the code. The only trick
; left is to arrange the A/D commands such that
; they occur between data transmissions!
BSF PORTC, 0x5
MOVLW 0xFF ; Send START_OF_DATA byte - this signals
MOVWF TXREG ; to the PC that the peripheral is about
; to begin sending data
BSF STATUS, RP0 ; Select bank 1
HOLD_UNTIL_READY ; Wait until the data has been sent
BTFSS TXSTA, TRMT
GOTO HOLD_UNTIL_READY
BCF STATUS, RP0 ; Select bank 0
BCF PORTC, 0x5
BSF ADCON0, GO ; Start the A/D conversion
ONLY_AD_LOOP
BTFSC ADCON0, GO ; Loop until the A/D finishes
GOTO ONLY_AD_LOOP
BSF STATUS, RP0 ; Select bank 1
MOVF ADRESL, W ; Save the low A/D byte
BCF STATUS, RP0 ; Select bank 0
MOVWF AD_LOW
MOVF ADRESH, W ; Save the high A/D byte
MOVWF AD_HIGH
RLF AD_HIGH, F ; Move the two high bits
RLF AD_HIGH, F ; of the low byte into
BTFSC AD_LOW, 0x6 ; the two low bits of the
BSF AD_HIGH, 0x0 ; high byte
BTFSC AD_LOW, 0x7
BSF AD_HIGH, 0x1
MOVLW 0x3F
ANDWF AD_LOW, F
MOVLW 0x7F
ANDWF AD_HIGH, F
BSF AD_HIGH, 0x6
; This leaves the bytes arranged as:
; LOW: 00xx xxxx
; HIGH: 01xx xxxx
; The first bit identifies the bytes
; as data and the second identifies
; whether it is the high or low byte.
MOVF JOINT_ID, W
MOVWF AD_SELECT
INCF AD_SELECT, F
MOVLW 0x03
ANDWF AD_SELECT, F
MAIN_LOOP_BEGIN
; Executing Loop Iteration i
; Preparing A/D select (i+1)
MOVF AD_SELECT, W ; Prepare A/D select. It must
MOVWF AD_SELECTM ; be of the form xx21 0x3x
RLF AD_SELECTM, F ; where the numbers denote bits
RLF AD_SELECTM, F ; of the A/D select and an x denotes
RLF AD_SELECTM, F ; a zero. For example, if the A/D
; BTFSC AD_SELECTM, 0x6 ; select is 7 (0000 0111), the
; BSF AD_SELECTM, 0x1 ; modified select register should
; BCF AD_SELECTM, 0x6 ; be: 0011 1000
MOVF AD_BASESET, W ; Set the A/D control register 0
MOVWF ADCON0 ; to the base setting.
MOVF AD_SELECTM, W
IORWF ADCON0, F ; OR the A/D control register 0 with
BSF ADCON0, ADON ; the modified A/D select
; INCF AD_SELECT, F ; Increment the A/D select
; Send the i'th joint ID
BSF PORTC, 0x5
MOVF JOINT_ID, W
IORLW 0xC0
MOVWF TXREG
INCF JOINT_ID, F
MOVF JOINT_ID, W
XORLW 0x0A
BTFSC STATUS, Z
CLRF JOINT_ID
MOVF JOINT_ID, W
XORLW 0x09
BTFSC STATUS, Z
GOTO CLEAR_ADS
MOVF JOINT_ID, W
MOVWF AD_SELECT
INCF AD_SELECT, F
MOVLW 0x03
ANDWF AD_SELECT, F
GOTO ADS_DONE
CLEAR_ADS:
CLRF AD_SELECT
ADS_DONE:
BSF STATUS, RP0 ; Select bank 1
WAIT_FOR_ID
BTFSS TXSTA, TRMT
GOTO WAIT_FOR_ID
BCF STATUS, RP0 ; Select bank 0
BCF PORTC, 0x5
BSF ADCON0, GO ; Start the (i+1)'th A/D conversion
; Send the i'th low A/D byte
BSF PORTC, 0x5
MOVF AD_LOW, W
MOVWF TXREG
BSF STATUS, RP0 ; Select bank 1
WAIT_FOR_LOW
BTFSS TXSTA, TRMT
GOTO WAIT_FOR_LOW
BCF STATUS, RP0 ; Select bank 0
BCF PORTC, 0x5
; LED CHECKING HERE
MOVF JOINT_ID, W
XORLW 0x09
BTFSC STATUS, Z
GOTO CLEAR_JIDM
MOVF JOINT_ID, W
MOVWF JOINT_IDM
INCF JOINT_IDM, F
GOTO JIDM_DONE
CLEAR_JIDM:
CLRF JOINT_IDM
JIDM_DONE:
MOVLW 0x80
BTFSC JOINT_IDM, 0x2
MOVLW 0x40
BTFSC JOINT_IDM, 0x3
MOVLW 0x20
MOVWF PORTB
; Send the i'th high A/D byte
BSF PORTC, 0x5
MOVF AD_HIGH, W
MOVWF TXREG
BSF STATUS, RP0 ; Select bank 1
WAIT_FOR_HIGH
BTFSS TXSTA, TRMT
GOTO WAIT_FOR_HIGH
; Save and arrange the high and low bytes of the (i+1)'th A/D
BSF STATUS, RP0 ; Select bank 1
MOVF ADRESL, W ; Save the low A/D byte
BCF STATUS, RP0 ; Select bank 0
MOVWF AD_LOW
MOVF ADRESH, W ; Save the high A/D byte
MOVWF AD_HIGH
RLF AD_HIGH, F ; Move the two high bits
RLF AD_HIGH, F ; of the low byte into
BTFSC AD_LOW, 0x6 ; the two low bits of the
BSF AD_HIGH, 0x0 ; high byte
BTFSC AD_LOW, 0x7
BSF AD_HIGH, 0x1
MOVLW 0x3F
ANDWF AD_LOW, F
MOVLW 0x7F
ANDWF AD_HIGH, F
BSF AD_HIGH, 0x6
BCF STATUS, RP0 ; Select bank 0
BCF PORTC, 0x5
; MOVF AD_SELECT, W
; XORLW 0x04
; BTFSC STATUS, Z
; CLRF AD_SELECT
GOTO MAIN_LOOP_BEGIN
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment