Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16F877 ADC problems, urgent help needed

Status
Not open for further replies.

grutt

New Member
Hi,

Im currently creating a program which uses the on chip ADC. Currently, on an interupt, a section of code is run which i need to obtain the A to D result from multiple inputs and store them in some vars which i use later.

I plan to convert one input, then stores these results. Then change channel, convert that input etc.

The problem i have i think is to do with delay that is needed before the ADC can be used. I'm using timer0 to delay before the conversion completes, which is fine for the first time it is used, however the next time i try and delay for the next channel, it seems to hang and never leave the loop for the timer. If i ommit this timer for the second conversion, i get the wrong output... any ideas would be much appreciated...

PS: how do the timers work exactly... its all very confusing. For example what's a prescaler?

Thanx :)[/img]
 
Hi

I can't recomend to many things unles you post your code here or at least the part i'snt workig for you.

You can try to use bit test on the adcon0 GO/DONE bit
Code:
MAIN		  ;START HERE
		       BANKSEL	ADCON0
		       MOVLW	  B'10000001';SET UP ADCON0 
		       MOVWF	  ADCON0	;CH0, Fosc/32
READ_AD		BSF	    ADCON0,2 ;START A/D CONVERSION	
TESTBIT		BTFSC	  ADCON0,2 ;CHECK IF IS DONE	
		       GOTO 	  TESTBIT	;NO, NOT YET
		       GOTO	   SAVERESULT ; DONE, BIT 2 SET TO "0" BY THE A/D
SAVERESULT	NOP	    ;MAKE YOUR CODSE HERE TO SAVE A/D VALUE
		       GOTO	   READ_AD	;CHANGE THE A/D CHANEL
		                 ; BEFORE YOU START NEW A/D CONVERSION
or use the interrupt
PIR1 ADIF set when A/D convertsion completed.

:idea: STEVE
 
grutt said:
The problem i have i think is to do with delay that is needed before the ADC can be used. I'm using timer0 to delay before the conversion completes, which is fine for the first time it is used, however the next time i try and delay for the next channel, it seems to hang and never leave the loop for the timer. If i ommit this timer for the second conversion, i get the wrong output... any ideas would be much appreciated...

I'm presuming you're waiting for the 'end of conversion' signal from the A2D, and your delay is simply for the sample and hold capacitor to charge after changing channels?. This is highly dependent on the source impedance feeding the converter, for fastest conversions you need a low impedance source to charge the capacitor quickly.

The easiest way is to simply use a delay loop rather than using the timer, have a look at my analogue PIC tutorial on the URL below - some of those use two input channels, and show the technique required.
 
k7michal said:
why not just have the ADC trigger an interrupt when it's done sampling

There's not much point, unless the processor is busy with other tasks at the same time - often interrupt driven code simply places the processor in an endless loop while waiting for an interrupt to occur, which seems pretty pointless?.

Far better to keep it simple, no point in adding the complication of interrupts unless you need to - remember 'KISS' - 'Keep It Simple Stupid'.
 
The problem i have i think is to do with delay that is needed before the ADC can be used. I'm using timer0 to delay before the conversion completes, which is fine for the first time it is used, however the next time i try and delay for the next channel, it seems to hang and never leave the loop for the timer. If i ommit this timer for the second conversion, i get the wrong output... any ideas would be much appreciated...

PS: how do the timers work exactly... its all very confusing. For example what's a prescaler?

Unless you need to use timers for other uses, it is better to poll the ADCON0 GO/DONE bit for completion of the A/D conversion.

Having said that, if timer0 is used, the delay should be longer than the conversion time. This is at least 12 Tad or 12 x 1.6usec = 19.2 usec. The default delay of tmr0 (@4Mhz & 1:1 prescale) is 256usec and is more than enough.

To use TMR0, assign the prescaler to the watchdog timer by setting the PSA bit to 1. Select internal oscillator by clearing T0CS to 0. Wait until T0IF bit in the INTCON register is set on overflow. Once set, don't forget to clear it in software. After which, you can now go to read the A/D conversion result, start a new conversion and sample the next channel.
 
A prescaler btw is like making the tmr0 register longer by a defined number of bits, and there by making it take more count cycles for the timer to overflow.

Instead of having the timer increment on every cycle, it increments after the prescaler overflows.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top