list p=16c71
include <p16c71.inc>
include <coff.inc>
__CONFIG _WDT_OFF
;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71.
;; Specifically, the a/d converter is tested.
errorlevel -302
; Printf Command
.command macro x
.direct "C", x
endm
;----------------------------------------------------------------------
;----------------------------------------------------------------------
GPR_DATA UDATA
x RES 1
t1 RES 1
t2 RES 1
avg_lo RES 1
avg_hi RES 1
w_temp RES 1
status_temp RES 1
;----------------------------------------------------------------------
; ********************* RESET VECTOR LOCATION ********************
;----------------------------------------------------------------------
RESET_VECTOR CODE 0x000 ; processor reset vector
movlw high start ; load upper byte of 'start' label
movwf PCLATH ; initialize PCLATH
goto start ; go to beginning of program
;;
;; Interrupt
;;
movwf w_temp
swapf STATUS,W
movwf status_temp
bcf STATUS,RP0 ;adcon0 is in bank 0
btfsc INTCON,ADIE
btfsc ADCON0,ADIF
goto a2dint
.assert "\"p16c71 FAIL unexpected interrupt\""
nop
;; An A/D interrupt has occurred
a2dint:
bsf t1,0 ;Set a flag to indicate we got the int.
bcf ADCON0,ADIF ;Clear the a/d interrupt
swapf status_temp,w
movwf STATUS
swapf w_temp,F
swapf w_temp,W
retfie
;----------------------------------------------------------------------
; ******************* MAIN CODE START LOCATION ******************
;----------------------------------------------------------------------
MAIN CODE
start:
.sim "module library libgpsim_modules"
; Use a pullup resistor as a voltage source
.sim "module load pullup V1"
.sim "V1.resistance = 100.0"
.sim "module load pullup V2"
.sim "V2.voltage=2.0"
.sim "V2.resistance = 100.0"
.sim "node na0"
.sim "attach na0 V1.pin porta0"
.sim "node na1"
.sim "attach na1 V2.pin porta3"
;; Let's use the ADC's interrupt
clrf INTCON
#define FAST_CONVERSION ((1<<ADCS1) | (1<<ADCS0))
movlw FAST_CONVERSION | (1<<ADON)
movwf ADCON0
#define ENABLE_INTS ((1<<GIE) | (1<<ADIE))
movlw ENABLE_INTS
movwf INTCON
;; Upon power up, porta is configured for analog inputs.
;; (how many times have I been burnt by this???).
;; So let's test this out to see if it's true:
call Convert
.assert "adres == 0xff, \"FAILED 16C71 power-on result\""
nop
;; The next test consists of misusing the A/D converter.
;; TRISA is configured such that the I/O pins are digital outputs.
;; Normally you want them to be configued as inputs. According to
;; the data sheet, the A/D converter will measure the voltage produced
;; by the digital I/O output: either 0 volts or 5 volts (or Vdd).
;; [I wonder if this would be a useful way of measuring the power supply
;; level in the event that there's an external reference connected to
;; an3?]
.command "V1.resistance=1e6"
movlw 0
bsf STATUS,RP0
movwf PORTA ;Make the I/O's digital outputs
movwf ADCON1 ;Configure porta to be completely analog
;(note that this is unnecessary since that's
;the condition they're in at power up.)
bcf STATUS,RP0
movwf PORTA ;Drive the digital I/O's low
;;
;; First do a few conversion with porta configured as a digital output
;; that is driving low
;;
call Convert
.assert "adres == 0x00, \"FAILED 16C71 Digital low\""
nop
;;
;; Now do some with the digital output high
;;
movlw 0xff
movwf PORTA
call Convert
.assert "adres == 0xff, \"FAILED 16C71 Digital high\""
nop
;;
;; Now make the inputs analog (like they normally would be)
;;
.command "V1.resistance=100.0"
bsf STATUS,RP0
movlw 0xff
movwf PORTA
bcf STATUS,RP0
call Convert
.assert "adres == 0xff, \"FAILED 16C71 AN0=5V\""
nop
.command "V1.voltage=1.0"
call Convert
.assert "adres == 0x33, \"FAILED 16C71 AN0=1V\""
nop
;;
;; Now let's use the external analog signal connected to AN3
;; as the voltage reference
bsf STATUS,RP0
movlw 1<<PCFG0
movwf ADCON1 ^ 0x80
bcf STATUS,RP0
call Convert
.assert "adres == 0x80, \"FAILED 16C71 AN0=1V Vref+=2V\""
nop
.assert "\"*** PASSED 16C71 a2d test\""
goto $-1
Convert:
clrf t1 ;flag set by the interrupt routine
bsf ADCON0,GO ;Start the A/D conversion
btfss t1,0 ;Wait for the interrupt to set the flag
goto $-1
movf ADRES,W ;Read the result
return
end
syntax highlighted by Code2HTML, v. 0.9.1