Hello all, I'm having problems getting the A/D converter on the 12F675 to work properly. I'm using the internal oscillator at 4MHz. The program below should read the wiper of a 5k pot connected to GP0. TMR1 is rolling over on a 0.5 second basis. A flag is set in the ISR on the TMR1 rollover. This flag is then polled by the main loop. When the number of rollovers is equal to the A/D conversion result, GP2 should turn on for 1/2 second. It seems that the A/D conversion is not returning anything but zero. If I comment the line out that starts the conversion and change the program to move hardcoded data directly into the ADRES registers, the code seems to function properly. What am I missing? Checking the GP0 with a multimeter shows the pot to be functioning properly. I'm also open to constructive critism on how I can improve the readability/efficiency of the code below. (One obvious thing I need to do is change the way TMR1 is preloaded.) Regards, Aaron ;********************************************************************** ; * ; Filename: Pulser.asm * ; Date: 2-25-05 * ; * ;********************************************************************** ; * ; Files required: * ; 12F675i.lkr * ; P12F675.inc * ; * ;********************************************************************** ; * ; Notes: * ; A quick and dirty program. Reads pot connected to AN0. * ; A TMR1 interrupt occurs every 0.5 seconds. * ; When the number of TMR1 rollovers == the A/D result, a * ; relay will be turned on for a 0.5 second pulse. * ; * ;********************************************************************** list p=12f675 ; list directive to define processor #include ; processor specific variable definitions radix dec errorlevel -302 ; suppress message 302 from list file __CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_CLKOUT ; pin definitions ; GP0 - Analog input from wiper of 5k pot. Sets delay time betweenn 0.5 second relay pulses. ; GP1 - Not used. (Seems to be blown on this particular chip.) ; GP2 - Drives 4N32 optoisolator thru 200 ohm resistor. 4N32 then drives relay output. Delays between 0.5 second relay pulses are set by pot. ; GP3 - Reset button between ground and MCLR. MCLR tied high via 15k resister. ; GP4 - Fosc/4 clockout for debug purposes. ; GP5 - Drives an LED on a clock tick. Visual indication that program is working. ; #defines #define pot GPIO, GP0 #define relay GPIO, GP2 #define aliveLED GPIO, GP5 ; Shared Uninitialized Data Section INT_VAR UDATA_SHR 0x20 w_temp RES 1 ; variable used for context saving status_temp RES 1 ; variable used for context saving rollcntL RES 1 ; low byte of TMR1 rollovers rollcntH RES 1 ; high byte of TMR1 rollovers rollflag RES 1 ; bit 0 = TMR1 rollover flag for main loop to poll ;********************************************************************** RESET_VECTOR CODE 0x000 ; processor reset vector goto main ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register ; check for TMR1 rollover banksel PIR1 btfss PIR1, TMR1IF ; TMR1 rollover? goto nextIRQ movlw 0xBD ; reload TMR1 banksel TMR1L movwf TMR1L movlw 0xB banksel TMR1H movwf TMR1H banksel GPIO movlw b'00100000' ; toggle aliveLED for visual indication xorwf GPIO, f banksel rollflag bsf rollflag, 0 ; set roll-over flag for main loop to poll banksel PIR1 bcf PIR1, TMR1IF ; clear interrupt flag nextIRQ movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt main call 0x3FF ; retrieve factory calibration value banksel OSCCAL movwf OSCCAL ; update register with factory cal value ; initialize variables banksel rollcntL clrf rollcntL banksel rollcntH clrf rollcntH banksel rollflag clrf rollflag ; set up direction of I/O pins banksel TRISIO movlw b'00000001' ; xx------ not implemented ; --0----- 0=output, GP5, Drives an LED on a clock tick. Visual indication that program is working. ; ---0---- 0=output, GP4, Fosc/4 clockout for debug purposes ; ----x--- not used, GP3, Dedicated to MCLR ; -----0-- 0=output, GP2, Optoisolator, relay driver ; ------0- 0=output, GP1, not used (output defective) ; -------1 1=input, GP0, analog input movwf TRISIO ; set up A/D converter banksel ANSEL movlw b'00010001' ; x------- not implemented ; -001---- 001=Focs/8 Conversion Clock ; ----0--- 0=digital I/O, GP4, Fosc/4 clockout for debug purposes. ; -----0-- 0=digital I/O, GP2, Optoisolator, relay driver ; ------0- 0=digital I/O, GP1, not used (output defective) ; -------1 1=analog I/O, GP0, analog input movwf ANSEL banksel ADCON0 movlw b'10000001' ; 1------- 1=right justified result ; -0------ 0=Vdd is voltage reference ; --xx---- not implemented ; ----00-- 00=select channel 0 (GP0) ; ------0- 0=A/D conversion not started ; -------1 1=A/D converter module is operating movwf ADCON0 ; initialize output pins init banksel GPIO movlw b'00000000' movwf GPIO ; initialize interrupts banksel INTCON movlw b'01000000' ; 0------- 0=interrupts disabled ; -1------ 1=enable peripheral interrupts ; --0----- 0=disable TMR0 overflow interrupt ; ---0---- 0=disable GP2/INT external interrupt ; ----0--- 0=disable GPIO port change interrupt ; -----0-- 0=no on TMR0 overflow ; ------0- 0=no GP2/INT external interrupt ; -------0 0=no GPIO port change movwf INTCON banksel PIE1 movlw b'00000001' ; 0------- 0=disable EE write complete interrupt ; -0------ 0=disable A/D converter interrupt ; --xx---- not implemented ; ----0--- 0=comparator interrupt disabled ; -----xx- not implemented ; -------1 1=enable TMR1 overflow interrupt movwf PIE1 banksel PIR1 movlw b'00000000' ; 0------- 0=no EE write complete ; -0------ 0=no A/D conversion complete ; --xx---- not implemented ; ----0--- 0=no comparator interrupt ; -----xx- not implemented ; -------0 0=no TMR1 overflow movwf PIR1 ; initialize TMR1 banksel T1CON movlw b'00110101' ; x------- not implemented ; -0------ 0=gate disabled ; --11---- 01=1:8 prescaler ; ----0--- 0=LP oscillator is off ; -----1-- 1=external clock input not synchronized ; ------0- 0=internal clock ; -------1 1=enable timer movwf T1CON ; preload for 500ms rollover @ 4 MHZ internal oscillator ; Fosc/4 = 1 MHZ = 1 uS per clock ; 500000 clocks per 500 ms ; with 1:8 prescaler: 65535 - (500000/8) = 3035 = 0xBDB initial value banksel TMR1L movlw 0xDB movwf TMR1L banksel TMR1H movlw 0xB movwf TMR1H banksel INTCON bsf INTCON, GIE ; enable interrupts forever btfss rollflag, 0 ; TMR1 rollover? goto forever banksel GPIO bcf relay ; turn off relay ; increment number of rollovers banksel rollcntL incf rollcntL, f ; number of rollovers btfsc STATUS, Z ; more than 255 rollovers? incf rollcntH, f ; yes, increment high byte of rollover counter ; compare to see if rollover counter is = A/D result banksel ADRESH movf ADRESH, w ; high byte comparison banksel rollcntH xorwf rollcntH, w btfss STATUS, Z goto donecomp ; high bytes not equal, abort banksel ADRESL movf ADRESL, w ; low byte comparison banksel rollcntL xorwf rollcntL, w btfss STATUS, Z goto donecomp ; low bytes not equal, abort banksel rollcntL ; reset roll-over counters clrf rollcntL banksel rollcntH clrf rollcntH banksel GPIO bsf relay donecomp banksel ADCON0 bsf ADCON0, GO ; start A/D conversion ; banksel ADRESH ; these instructions were added... ; movlw 0 ; ... to simulate a working A/D ; movwf ADRESH ; banksel ADRESL ; movlw 10 ; movwf ADRESL banksel rollflag bcf rollflag, 0 ; reset ISR rollover flag goto forever ; repeat ; initialize eeprom locations EE CODE 0x2100 DE 0x00, 0x01, 0x02, 0x03 END -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist