1 list p=18f26k22 ; list directive to define processor 2 include <p18f26k22.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 0 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 CONFIG MCLRE=INTMCLR 23 24;------------------------------------------------------------------------ 25STARTUP CODE 0 26 27 bra Start 28 29;------------------------------------------------------------------------ 30; 31; Interrupt Vector 32; 33;------------------------------------------------------------------------ 34 35INT_VECTOR CODE 0x008 ; interrupt vector location 36 37 38check_TMR0_interrupt: 39 40 btfsc PIR1,ADIF ;If A2D int flag is not set 41 btfsc PIE1,ADIE ;Or the interrupt is not enabled 42 goto a2dint 43 44 .assert "'FAIL 18F26k22 unexpected interrupt'" 45 nop 46 RETFIE 1 ; Then leave 47 48;; An A/D interrupt has occurred 49a2dint: 50 bsf a2dIntFlag,0 ;Set a flag to indicate we got the int. 51 bcf PIR1,ADIF ;Clear the a/d interrupt 52 53ExitInterrupt: 54 RETFIE 1 55 56 57;---------------------------------------------------------------------- 58; ******************* MAIN CODE START LOCATION ****************** 59;---------------------------------------------------------------------- 60MAIN CODE 61 62 .sim "p18f26k22.xpos = 192" 63 .sim "p18f26k22.ypos = 48" 64 65 66 .sim "module library libgpsim_modules" 67 ; Use a pullup resistor as a voltage source 68 .sim "module load pullup V1" 69 .sim "V1.resistance = 100.0" 70 .sim "V1.xpos = 48" 71 .sim "V1.ypos = 24" 72 73 .sim "module load pullup V2" 74 .sim "V2.resistance = 100.0" 75 .sim "V2.xpos = 48" 76 .sim "V2.ypos = 204" 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 = 120" 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 ; AN0 is the only analog input 102 ; ADCS = 110 == FOSC/64 103 ; ADFM = 0 == 6 LSB of ADRESL are 0. 104 ; 105 BANKSEL ANSELA 106 movlw 0x01 ; RA0 analog 107 movwf ANSELA 108 clrf TRISA 109 MOVLW 0xff 110 movwf PORTA 111 movf PORTA,W 112 113 MOVLW 1<<RA0 114 MOVWF TRISA 115 116 MOVLW 0 ; ADC ref = Vdd,Vss 117 MOVWF ADCON1 118 MOVLW (1<<ADCS1) | (1<<ADCS2) 119 MOVWF ADCON2 120 MOVLW (1<<ADON) 121 MOVWF ADCON0 122 123 BSF INTCON,GIE ;Global interrupts 124 BSF INTCON,PEIE ;Peripheral interrupts 125 BSF PIE1,ADIE ;A2D interrupts 126 127 RCALL Convert 128 nop 129 130 .assert "adresh == 0xff, 'FALIED 18F26k22 a2d AN0=5V'" 131 nop 132 133 ;; The next test consists of misusing the A/D converter. 134 ;; TRISA is configured such that the I/O pins are digital outputs. 135 ;; Normally you want them to be configued as inputs. According to 136 ;; the data sheet, the A/D converter will measure the voltage produced 137 ;; by the digital I/O output: either 0 volts or 5 volts (or Vdd). 138 ;; [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 139 ;; an3?] 140 141 142; .command "V1.resistance=1e6" 143 144 movlw 0 145 movwf TRISA ;Make the I/O's digital outputs 146 movwf PORTA ;Drive the digital I/O's low 147 movlw 0xff 148 movwf ANSELA ;Configure porta to be completely analog 149 bsf ADCON0,CHS0 ;Use AN1 150 151 152 RCALL Convert 153 154 .assert "adresh == 0x00, 'FAILED 18F26k22 Digital low'" 155 nop 156 157 movlw 0x02 158 movwf PORTA ; drive bit 1 high 159 160 RCALL Convert 161 162 .assert "adresh == 0xff, 'FAILED 18F26k22 Digital high'" 163 nop 164 165 movlw 0xff 166 movwf TRISA ;Make the I/O's inputs 167 bcf ADCON0,CHS0 ;Use AN0 168 169 .command "V1.voltage=1.0" 170 171 rcall Convert 172 173 .assert "adresh == 0x33, 'FAILED 18F26k22 AN0=1V'" 174 nop 175 176 .command "V2.voltage=2.0" 177 bsf ADCON1,PVCFG0 ; RA3 is Vref 178 rcall Convert 179 180 .assert "adresh == 0x80, 'FAILED 18F26k22 AN0=1V Vref+=2V'" 181 nop 182 183 bsf VREFCON0,FVREN 184 btfss VREFCON0,FVRST 185 goto $-2 186 movlw 0x7d 187 movwf ADCON0 ; read Vref 1.024 188 rcall Convert 189 nop 190 .assert "adresh == 0x83, 'FAILED 18F26k22 FVR=1.024V Vref+=2V'" 191 nop 192 193done: 194 .assert "'*** PASSED 18F26k22 a2d test'" 195 bra $ 196 197 198Convert: 199 BCF a2dIntFlag,0 ;Clear interrupt handshake flag 200 201 BSF ADCON0,GO 202 203LWait: 204 BTFSS a2dIntFlag,0 ;Wait for the interrupt to set the flag 205 bra LWait 206 207 MOVF ADRESH,W ;Read the high 8-bits of the result 208 209 RETURN 210 211 end 212