1 2 list p=16f819 3 include <p16f819.inc> 4 include <coff.inc> 5 6 __CONFIG _WDT_OFF 7 8 ;; The purpose of this program is to test gpsim 9 ;; Specifically, the a/d converter is tested. 10 11 errorlevel -302 12 13; Printf Command 14.command macro x 15 .direct "C", x 16 endm 17 18;---------------------------------------------------------------------- 19;---------------------------------------------------------------------- 20GPR_DATA UDATA_SHR 21 22x RES 1 23t1 RES 1 24t2 RES 1 25avg_lo RES 1 26avg_hi RES 1 27w_temp RES 1 28status_temp RES 1 29 30 31;---------------------------------------------------------------------- 32; ********************* RESET VECTOR LOCATION ******************** 33;---------------------------------------------------------------------- 34RESET_VECTOR CODE 0x000 ; processor reset vector 35 movlw high start ; load upper byte of 'start' label 36 movwf PCLATH ; initialize PCLATH 37 goto start ; go to beginning of program 38 39INT_VECTOR CODE 0x004 ; interrupt vector location 40 ;; 41 ;; Interrupt 42 ;; 43 movwf w_temp 44 swapf STATUS,W 45 movwf status_temp 46 47 bcf STATUS,RP0 ;adcon0 is in bank 0 48 49 btfsc INTCON,ADIE 50 btfsc PIR1,ADIF 51 goto inta2d 52 53 .assert "'FAILED 16F819 a2d unexpected interupt'" 54 nop 55 goto check 56;; An A/D interrupt has occurred 57inta2d: 58 bsf t1,0 ;Set a flag to indicate we got the int. 59 bcf PIR1,ADIF ;Clear the a/d interrupt 60 61 62check: 63 swapf status_temp,w 64 movwf STATUS 65 swapf w_temp,F 66 swapf w_temp,W 67 retfie 68 69 70 71;---------------------------------------------------------------------- 72; ******************* MAIN CODE START LOCATION ****************** 73;---------------------------------------------------------------------- 74MAIN CODE 75start: 76 77 .sim "module library libgpsim_modules" 78 ; Use a pullup resistor as a voltage source 79 .sim "module load pullup V1" 80 .sim "V1.resistance = 100.0" 81 82 .sim "node na0" 83 .sim "attach na0 V1.pin porta0" 84 85 .sim "module load pullup V2" 86 .sim "V2.resistance = 100.0" 87 88 .sim "node na1" 89 .sim "attach na1 V2.pin porta3" 90 91 ;; Let's use the ADC's interrupt 92 ; RA0 is an Analog Input. 93 ; RA1 - RA5 are all configured as outputs. 94 ; 95 ; Use VDD and VSS for Voltage references. 96 ; 97 ; PCFG = 1110 == AN0 is the only analog input 98 ; ADCS = 110 == FOSC/64 99 ; ADFM = 0 == 6 LSB of ADRESL are 0. 100 ; 101 102 103 bsf STATUS,RP0 ;adcon1 is in bank 1 104 movlw 1 105 movwf TRISA 106 107 108 movlw (1<<PCFG1) | (1<<PCFG2) | (1<<PCFG3) 109 movwf ADCON1 110 movlw (1<<ADCS1) | (1<<ADON) 111 bsf PIE1,ADIE ;A2D interrupts 112 bcf STATUS,RP0 ;adcon0 is in bank 0 113 movwf ADCON0 114 115 bsf INTCON,GIE ;Global interrupts 116 bsf INTCON,PEIE ;Peripheral interrupts 117 118 119 call Convert 120 121 .assert "adresh == 0xff, 'Failed 16F819 a2d initial test'" 122 nop 123 124 ;; The next test consists of misusing the A/D converter. 125 ;; TRISA is configured such that the I/O pins are digital outputs. 126 ;; Normally you want them to be configued as inputs. According to 127 ;; the data sheet, the A/D converter will measure the voltage produced 128 ;; by the digital I/O output: either 0 volts or 5 volts (or Vdd). 129 ;; [I wonder if this would be a useful way of measuring the power supply 130 ;; level in the event that there's an external reference connected to 131 ;; an3?] 132 133 .command "V1.resistance=1e6" 134 135 movlw 0 136 bsf STATUS,RP0 137 movwf TRISA ;Make the I/O's digital outputs 138 movwf ADCON1 ;Configure porta to be completely analog 139 ;(note that this is unnecessary since that's 140 ;the condition they're in at power up.) 141 bcf STATUS,RP0 142 143 movwf PORTA ;Drive the digital I/O's low 144 145 ;; 146 ;; First do a few conversion with porta configured as a digital output 147 ;; that is driving low 148 ;; 149 150 call Convert 151 152 .assert "adresh == 0x00, 'Failed 16F819 a2d Digital low'" 153 nop 154 155 ;; 156 ;; Now do some with the digital output high 157 ;; 158 159 movlw 0xff 160 movwf PORTA 161 162 call Convert 163 164 .assert "adresh == 0xff, 'Failed 16F819 a2d Digital high'" 165 nop 166 ;; 167 ;; Now make the inputs analog (like they normally would be) 168 ;; 169 170 .command "V1.resistance=100.0" 171 172 bsf STATUS,RP0 173 movlw 0xff 174 movwf PORTA 175 bcf STATUS,RP0 176 177 call Convert 178 179 .assert "adresh == 0xff, 'Failed 16F819 a2d AN0=5V'" 180 nop 181 182 183 .command "V1.voltage=1.0" 184 185 call Convert 186 187 .assert "adresh == 0x33, 'Failed 16F819 a2d AN0=1V'" 188 nop 189 ;; 190 ;; Now let's use the external analog signal connected to AN3 191 ;; as the voltage reference 192 193 bsf STATUS,RP0 194 movlw 1<<PCFG0 195 movwf ADCON1 ^ 0x80 196 bcf STATUS,RP0 197 198 .command "V2.voltage=2.0" 199 200 call Convert 201 .assert "adresh == 0x80, 'Failed 16F819 a2d AN0=1V Vref+=2V'" 202 nop 203 204 .assert "'*** PASSED 16F819 a2d test'" 205 206 goto $-1 207 208 209 210Convert: 211 212 clrf t1 ;flag set by the interrupt routine 213 214 bsf ADCON0,GO ;Start the A/D conversion 215 216 btfss t1,0 ;Wait for the interrupt to set the flag 217 goto $-1 218 219 movf ADRESH,W ;Read the high 8-bits of the result 220 221 222 return 223 224 end 225