1	list    p=18f452                ; list directive to define processor
2	include <p18f452.inc>           ; processor specific variable definitions
3        include <coff.inc>              ; Grab some useful macros
4
5.command macro x
6  .direct "C", x
7  endm
8
9;----------------------------------------------------------------------
10;----------------------------------------------------------------------
11GPR_DATA                UDATA
12temp            RES     1
13temp1           RES     1
14temp2           RES     1
15failures        RES     1
16
17a2dIntFlag	RES	1  ;LSB is set when an A2D interrupt occurs
18
19  GLOBAL done
20  GLOBAL a2dIntFlag
21
22;------------------------------------------------------------------------
23STARTUP    CODE	0
24
25	bra	Start
26
27;------------------------------------------------------------------------
28;
29;  Interrupt Vector
30;
31;------------------------------------------------------------------------
32
33INT_VECTOR   CODE    0x008               ; interrupt vector location
34
35
36check_TMR0_interrupt:
37
38	btfsc	PIR1,ADIF	;If A2D int flag is not set
39	 btfsc	PIE1,ADIE	;Or the interrupt is not enabled
40	goto a2dint
41
42  .assert "'FAIL 18F452 unexpected interrupt'"
43	nop
44	RETFIE 1		; Then leave
45
46;;	An A/D interrupt has occurred
47a2dint:
48	bsf	a2dIntFlag,0	;Set a flag to indicate we got the int.
49	bcf	PIR1,ADIF	;Clear the a/d interrupt
50
51ExitInterrupt:
52	RETFIE	1
53
54
55;----------------------------------------------------------------------
56;   ******************* MAIN CODE START LOCATION  ******************
57;----------------------------------------------------------------------
58MAIN    CODE
59
60
61   .sim "p18f452.xpos = 192"
62   .sim "p18f452.ypos = 48"
63
64
65   .sim "module library libgpsim_modules"
66   ; Use a pullup resistor as a voltage source
67   .sim "module load pullup V1"
68   .sim "V1.resistance = 100.0"
69   .sim "V1.xpos = 48"
70   .sim "V1.ypos = 36"
71
72   .sim "module load pullup V2"
73   .sim "V2.resistance = 100.0"
74   .sim "V2.xpos = 48"
75   .sim "V2.ypos = 168"
76
77
78   ; V3 and na1 required for A/D to see voltage bug ?
79   ; RRR 5/06
80   .sim "module load pullup V3"
81   .sim "V3.resistance = 10e6"
82   .sim "V3.xpos = 48"
83   .sim "V3.ypos = 96"
84
85   .sim "node na0"
86   .sim "attach na0 V1.pin porta0"
87   .sim "node na1"
88   .sim "attach na1  V3.pin porta1"
89   .sim "node na3"
90   .sim "attach na3 V2.pin porta3"
91
92
93Start:
94
95
96    ; RA0 is an Analog Input.
97    ; RA1 - RA5 are all configured as outputs.
98    ;
99    ; Use VDD and VSS for Voltage references.
100    ;
101    ; PCFG = 1110  == AN0 is the only analog input
102    ; ADCS = 110   == FOSC/64
103    ; ADFM = 0     == 6 LSB of ADRESL are 0.
104    ;
105
106	MOVLW	1<<RA0
107	MOVWF	TRISA
108
109	MOVLW	(1<<ADCS2) | (1<<PCFG1) | (1<<PCFG2) | (1<<PCFG3)
110	MOVWF	ADCON1
111	MOVLW	(1<<ADCS1) | (1<<ADON)
112	MOVWF	ADCON0
113
114	BSF	INTCON,GIE	;Global interrupts
115	BSF	INTCON,PEIE	;Peripheral interrupts
116	BSF	PIE1,ADIE	;A2D interrupts
117
118	RCALL	Convert
119
120  .assert "adresh == 0xff, 'FALIED 18F452 a2d AN0=5V'"
121	nop
122
123        ;; The next test consists of misusing the A/D converter.
124        ;; TRISA is configured such that the I/O pins are digital outputs.
125        ;; Normally you want them to be configued as inputs. According to
126        ;; the data sheet, the A/D converter will measure the voltage produced
127        ;; by the digital I/O output:    either 0 volts or 5 volts (or Vdd).
128        ;; [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
129        ;; an3?]
130
131
132;  .command "V1.resistance=1e6"
133
134        movlw   0
135        movwf   TRISA           ;Make the I/O's digital outputs
136        movwf   ADCON1          ;Configure porta to be completely analog
137	bsf	ADCON0,CHS0	;Use AN1
138
139        movwf   PORTA           ;Drive the digital I/O's low
140
141	RCALL	Convert
142
143  .assert "adresh == 0x00, 'FAILED 18F452 Digital low'"
144	nop
145
146	movlw	0x02
147	movwf	PORTA		; drive bit 1 high
148
149	RCALL	Convert
150
151  .assert "adresh == 0xff, 'FAILED 18F452 Digital high'"
152	nop
153
154        movlw   0xff
155        movwf   TRISA           ;Make the I/O's inputs
156	bcf	ADCON0,CHS0	;Use AN0
157
158  .command "V1.voltage=1.0"
159
160        rcall    Convert
161
162   .assert "adresh == 0x33, 'FAILED 18F452 AN0=1V'"
163        nop
164
165  .command "V2.voltage=2.0"
166	bsf	ADCON1,PCFG0	; RA3 is Vref
167        rcall    Convert
168
169   .assert "adresh == 0x80, 'FAILED 18F452 AN0=1V Vref+=2V'"
170        nop
171
172done:
173  .assert  "'*** PASSED 18F452 a2d test'"
174        bra     $
175
176
177Convert:
178	BCF	a2dIntFlag,0	;Clear interrupt handshake flag
179
180	BSF	ADCON0,GO
181
182LWait:
183	BTFSS	a2dIntFlag,0	;Wait for the interrupt to set the flag
184	 bra	LWait
185
186	MOVF	ADRESH,W		;Read the high 8-bits of the result
187
188	RETURN
189
190        end
191