I’ve gotten the A/D converter on the Microchip PIC P12F675 to work. The pulse width modulation technique is allowing me to simulate different intensities of light. What you do is send extremely fast pulses of light on and off. Your eye “averages” these out to appear as a middle intensity brightness.
Here is a movie:
Here is the source code:
1 ;Software License Agreement 2 ; 3 ;The software supplied herewith by Microchip Technology 4 ;Incorporated (the "Company") is intended and supplied to you, the 5 ;Company~Rs customer, for use solely and exclusively on Microchip 6 ;products. The software is owned by the Company and/or its supplier, 7 ;and is protected under applicable copyright laws. All rights are 8 ;reserved. Any use in violation of the foregoing restrictions may 9 ;subject the user to criminal sanctions under applicable laws, as 10 ;well as to civil liability for the breach of the terms and 11 ;conditions of this license. 12 ; 13 ;THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, 14 ;WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED 15 ;TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 16 ;PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, 17 ;IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR 18 ;CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 19 ;**************************************************************************** 20 ;Filename: atod.asm 21 ;Author: Ruan Lourens 22 ;Date: 1.03.03 23 ;Version: 1.0 (A/D Version) 24 ;Description: This is an ASSEMBLY written program designed to show the user 25 ; a timer driven analog-to-digital conversion.It is based on the 26 ; interrupt driven conversionLED State Machine used in 27 ; tutorial #3. 28 ;**************************************************************************** 29 ;Revision History 30 ;**************************************************************************** 31 32 33 list p=12F675 ; list directive to define processor 34 #include <p12f675.inc> ; processor specific variable definitions 35 ;#include "atod.h" 36 errorlevel -302 ; suppress message 302 from list file 37 38 __CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 39 40 ; '__CONFIG' directive is used to embed configuration word within .asm file. 41 ; The lables following the directive are located in the respective .inc file. 42 ; See data sheet for additional information on configuration word settings. 43 44 ;**************************************************************************** 45 ;Defines 46 ;**************************************************************************** 47 #define BANK1 bsf STATUS,RP0 ; Bank1 48 #define BANK0 bcf STATUS,RP0 ; Bank0 49 #define LED1TRIS b'11001111' 50 #define LED2TRIS b'11001111' 51 #define LED3TRIS b'11101011' 52 #define LED4TRIS b'11101011' 53 #define LED5TRIS b'11011011' 54 #define LED6TRIS b'11011011' 55 #define LED7TRIS b'11111001' 56 #define LED8TRIS b'11111001' 57 #define LED1ON b'00010000' 58 #define LED2ON b'00100000' 59 #define LED3ON b'00010000' 60 #define LED4ON b'00000100' 61 #define LED5ON b'00100000' 62 #define LED6ON b'00000100' 63 #define LED7ON b'00000100' 64 #define LED8ON b'00000010' 65 #define NUMBEROFBITS .8 66 #define ANSelect b'00010001' ;Used to configure AD 67 #define ADControl b'00000001' ;Used to configure AD 68 69 LEDREGISTER EQU 0x31 70 71 mcount EQU 22h 72 ncount EQU 23h 73 new_tris EQU 24h 74 new_gpio EQU 25h 75 brightness_num EQU 26h 76 brightness_den EQU 27h 77 brightness_dat EQU 28h 78 IS_ON_BIT EQU 0 79 brightness_count EQU 29h 80 temp EQU 30h 81 ALL_OFF_TRIS EQU b'11111111' 82 83 ;**************************************************************************** 84 ;General Purpose Registers (GPR's) 85 ;**************************************************************************** 86 ; UDATA_SHR 87 WTEMP res 1 ; register used in Interrupt Routine 88 STATUSTEMP res 1 ; register used in Interrupt Routine 89 PCLATHTEMP res 1 ; register used in Interrupt Routine 90 FSRTEMP res 1 ; register used in Interrupt Routine 91 FLAGS res 1 ; register used to set flags 92 93 ;**************************************************************************** 94 ;Reset Vector 95 ;**************************************************************************** 96 ORG 0x000 ; processor reset vector 97 nop ; Inserted For ICD2 Use 98 goto Init ; go to beginning of program 99 100 ;**************************************************************************** 101 ;Interrupt Vector - Interrupts only active during animation sequence 102 ; - Interrupt Sources: 1. TIMER0 Overflow 103 ; 104 ;FLAGS register - bit0: 1 = A/D will be serviced, 0 = Display will be serviced 105 ; 106 ;**************************************************************************** 107 ORG 0x004 ; interrupt vector location 108 Isr 109 movwf WTEMP ;Save off current W register contents 110 movf STATUS,w 111 clrf STATUS ;Force to page0 112 movwf STATUSTEMP 113 ;movf PCLATH,w 114 ;movwf PCLATHTEMP ;Save PCLATH 115 ;movf FSR,w 116 ;movwf FSRTEMP ;Save FSR 117 118 119 ;**************************************************************************** 120 ;Interrupt Source Checks 121 ;**************************************************************************** 122 Timer0InterruptCheck 123 BANK1 ; BANK1 124 movf INTCON,w 125 andlw 0x20 126 btfsc STATUS,Z ;Is T0IE Set? 127 goto Next1 ;No 128 movf INTCON,w ;Yes 129 andlw 0x04 130 btfss STATUS,Z ;Is TOIF Set? 131 goto Timer0Interrupt ;Yes 132 133 Next1 134 GPIFInterruptCheck 135 movf INTCON,w 136 andlw 0x08 137 btfsc STATUS,Z ;Is GPIE Set? 138 goto Next2 ;No 139 movf INTCON,w ;Yes 140 andlw 0x01 141 btfss STATUS,Z ;Is GPIF Set? 142 goto GPIFInterrupt ;Yes 143 144 Next2 145 GP2_INT_ExternalInterruptCheck 146 movf INTCON,w 147 andlw 0x10 148 btfsc STATUS,Z ;Is INTE Set? 149 goto Next3 ;No 150 movf INTCON,w ;Yes 151 andlw 0x02 152 btfss STATUS,Z ;Is INTF Set? 153 goto GP2_INTExternalInterrupt;Yes 154 155 Next3 156 PeripheralInterruptCheck 157 movf INTCON,w 158 andlw 0x40 159 btfsc STATUS,Z ;Is PEIE Set? 160 goto EndIsr ;No 161 162 Next4 163 EEIFInterruptCheck 164 movf PIE1,w 165 andlw 0x80 166 btfsc STATUS,Z ;Is EEIE Set? 167 goto Next5 ;No 168 BANK0 ;Yes 169 movf PIR1,w 170 BANK1 171 andlw 0x80 172 btfss STATUS,Z ;Is EEIF Set? 173 goto EEPROMInterrupt;Yes 174 175 Next5 176 ADIFInterruptCheck 177 movf PIE1,w 178 andlw 0x40 179 btfsc STATUS,Z ;Is ADIE Set? 180 goto Next6 ;No 181 BANK0 182 movf PIR1,w 183 BANK1 184 andlw 0x40 185 btfss STATUS,Z ;Is ADIF Set? 186 goto A_DConverterInterrupt;Yes 187 188 Next6 189 CMIFInterruptCheck 190 movf PIE1,w 191 andlw 0x08 192 btfsc STATUS,Z ;Is CMIE Set? 193 goto Next7 ;No 194 BANK0 ;Yes 195 movf PIR1,w 196 BANK1 197 andlw 0x08 198 btfss STATUS,Z ;Is CMIF Set? 199 goto ComparatorInterrupt;Yes 200 201 Next7 202 TMR1IFInterruptCheck 203 movf PIE1,w 204 andlw 0x01 205 btfsc STATUS,Z ;Is TMR1IE Set? 206 goto EndIsr ;No 207 BANK0 ;Yes 208 movf PIR1,w 209 BANK1 210 andlw 0x01 211 btfss STATUS,Z ;Is TMR1IF Set? 212 goto Timer1Interrupt ;Yes 213 goto EndIsr ;No 214 215 Timer0Interrupt ;Interrupt every 1024 uS 216 BANK0 ;BANK0 217 btfsc FLAGS,0 ;Check if A/D functions will be serviced or the display routine 218 call AD_Functions ;Yes, service A/D 219 BANK0 ;BANK0 220 btfss FLAGS,0 ;Check if Display functions will be serviced 221 call Display ;Yes, goto Display 222 BANK0 ;BANK0 223 movlw b'00000001' 224 xorwf FLAGS,F ;Toggle FLAGS,1 225 BANK1 ;BANK1 226 bcf INTCON,T0IF ;Clear TMR0 Interrupt Flag 227 goto EndIsr 228 229 Display 230 decfsz brightness_count,f 231 goto activate_leds 232 goto toggle_on_off 233 toggle_on_off: 234 movlw b'11111111' 235 xorwf brightness_dat,f 236 btfsc brightness_dat,IS_ON_BIT 237 goto store_off_time 238 goto store_on_time 239 store_on_time: 240 movfw brightness_num 241 movwf brightness_count 242 goto activate_leds 243 store_off_time: 244 movfw brightness_den 245 movwf brightness_count 246 activate_leds: 247 btfsc brightness_dat,IS_ON_BIT 248 goto show_black 249 goto show_lights 250 show_black: 251 movlw b'11111111' 252 bsf STATUS,RP0 ;Bank 1 253 movwf TRISIO ;and set GP<5:4,1:0> 254 bcf STATUS,RP0 ;Bank 0 255 movlw b'00000000' 256 movwf GPIO 257 goto end_of_intr 258 show_lights: 259 movfw new_tris; 260 bsf STATUS,RP0 ;Bank 1 261 ;movlw b'11001111' 262 movwf TRISIO ;and set GP<5:4,1:0> 263 bcf STATUS,RP0 ;Bank 0 264 movfw new_gpio 265 ;movlw b'00010000' 266 movwf GPIO 267 end_of_intr: 268 return 269 270 271 272 273 GPIFInterrupt 274 goto EndIsr 275 276 GP2_INTExternalInterrupt 277 goto EndIsr 278 279 EEPROMInterrupt 280 goto EndIsr 281 282 A_DConverterInterrupt 283 goto EndIsr 284 285 ComparatorInterrupt 286 goto EndIsr 287 288 Timer1Interrupt 289 290 EndIsr 291 clrf STATUS ;Select Bank0 292 ;movf FSRTEMP,w 293 ;movwf FSR ;Restore FSR 294 ;movf PCLATHTEMP,w 295 ;movwf PCLATH ;Restore PCLATH 296 movf STATUSTEMP,w 297 movwf STATUS ;Restore STATUS 298 swapf WTEMP,f 299 swapf WTEMP,w ;Restore W without corrupting STATUS bits 300 retfie ;Return from interrupt 301 302 303 ;**************************************************************************** 304 ;AD_Functions 305 ;**************************************************************************** 306 AD_Functions 307 BANK0 ;BANK0 308 movf ADRESH,W ;Move the most significant byte of A/D Result to W 309 movwf LEDREGISTER ;The A/D result is moved to LEDREGISTER and will be displayed 310 bsf ADCON0,GO ;Start A/D 311 return 312 313 ;**************************************************************************** 314 ;Initialization 315 ;**************************************************************************** 316 Init 317 ;call 0x3FF ; retrieve factory calibration value 318 ; comment instruction if using simulator, ICD2, or ICE2000 319 BANK1 320 movwf OSCCAL ; update register with factory cal value 321 ;call InitLED ;Initialize LED Routine Variables 322 movlw b'00000001' 323 movwf TRISIO ;Tri-State All Inputs 324 BANK0 ;BANK 0 325 clrf GPIO ;Clear Port 326 movlw b'00100000' 327 movwf GPIO 328 329 BANK1 ;BANK 1 330 clrf VRCON ;Vref Off 331 BANK0 ;BANK 0 332 clrf TMR0 333 movlw 0x07 334 movwf CMCON ;Comparator Off 335 336 BANK1 ;BANK 1 337 movlw b'10000001' 338 movwf OPTION_REG ;TIMER0 Prescaler = 4 and pull-ups disabled 339 bsf INTCON,T0IE ;Interrupt on TIMER0 Overflow Enabled 340 bcf INTCON,T0IF ;Clear TIMER0 Overflow Interrupt Flag 341 bsf INTCON,GIE ;Turn on Global Interrupts 342 movlw ANSelect 343 movwf ANSEL ;Configure AN0 & prescale to A/D 344 345 BANK0 ;BANK 0 346 movlw ADControl 347 movwf ADCON0 ;Select AN0, Left justified & enables A/D 348 NOP 349 NOP 350 NOP 351 NOP ; Give 4 uS delay before starting A/D 352 bsf ADCON0,GO ; Start A/D 353 354 ;**************************************************************************** 355 ;MAIN - Main Routine 356 ;**************************************************************************** 357 Main 358 movlw 0x02 359 movwf brightness_num 360 movlw 0x1F 361 movwf brightness_den 362 movlw 0xFF 363 movwf brightness_count 364 go 365 ; D0 366 movlw b'11001111' 367 movwf new_tris 368 movlw b'00010000' 369 movwf new_gpio 370 call delay 371 ; D0 372 movlw b'11001111' 373 movwf new_tris ;and set GP<5:4,1:0> 374 movlw b'00100000' 375 movwf new_gpio 376 call delay 377 ; D0 378 movlw b'11101011' 379 movwf new_tris ;and set GP<5:4,1:0> 380 movlw b'00010000' 381 movwf new_gpio 382 call delay 383 ; D0 384 movlw b'11101011' 385 movwf new_tris ;and set GP<5:4,1:0> 386 movlw b'00000100' 387 movwf new_gpio 388 call delay 389 ; D7 390 movlw b'11111001' 391 movwf new_tris ;and set GP<5:4,1:0> 392 movlw b'00000010' 393 movwf new_gpio 394 call delay 395 ; D6 396 movlw b'11111001' 397 movwf new_tris ;and set GP<5:4,1:0> 398 movlw b'00000100' 399 movwf new_gpio 400 call delay 401 ; D5 402 movlw b'11011011' 403 movwf new_tris ;and set GP<5:4,1:0> 404 movlw b'00000100' 405 movwf new_gpio 406 call delay 407 ; D0 408 movlw b'11011011' 409 movwf new_tris ;and set GP<5:4,1:0> 410 movlw b'00100000' 411 movwf new_gpio 412 call delay 413 goto go 414 415 416 ;delay loop 417 delay movlw 0x01 418 movwf temp 419 movwf brightness_num 420 loadm2 movlw 0x2f 421 movwf mcount 422 loadn2 movfw LEDREGISTER 423 addlw 1 424 movwf ncount 425 repeat2 426 decfsz ncount,f 427 goto repeat2 428 decfsz mcount,f 429 goto loadn2 430 incf brightness_num,f 431 movlw 0x13 432 movwf brightness_den 433 movfw brightness_num 434 subwf brightness_den,f 435 incf brightness_den,f 436 movlw 0x13 437 xorwf brightness_num,w 438 movwf temp 439 incf temp,f 440 decfsz temp,f 441 goto loadm2 442 goto delay2 443 delay2 movlw 0x13 444 movwf brightness_num 445 loadm movlw 0x2f 446 movwf mcount 447 movlw 0x13 448 movwf brightness_den 449 movfw brightness_num,f 450 subwf brightness_den,f 451 incf brightness_den,f 452 loadn movfw LEDREGISTER 453 addlw 1 454 movwf ncount 455 repeat 456 decfsz ncount,f 457 goto repeat 458 decfsz mcount,f 459 goto loadn 460 decfsz brightness_num,f 461 goto loadm 462 return 463 464 465 ; initialize eeprom locations 466 467 ORG 0x2100 468 DE 0x00, 0x01, 0x02, 0x03 469 470 471 END ; directive 'end of program' 472
One reply on “A/D conversion”
nobody is going to comment on this thing because you have to scroll through 300+ lines of code. sheesh. he claims that he is posting this for the good of computer geeks everywhere…