Last active
April 17, 2018 17:09
-
-
Save mgwalker/ef0779468614fffb5bb6c79cb73c1d21 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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