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