Adc in pic16f877a...

takao21203

Joined Apr 28, 2012
3,702
Hi,

Testing ADC code in MP lab is this possible??
Don't know it will work but it is according to data sheet ....

Rich (BB code):
#include <htc.h>
__CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
#define _XTAL_FREQ 20000000


#define DAD PORTB


main(){
    TRISB=0X00;
TRISA = 0xff ;
ADCON1=0b00000000;
ADCON0=0b10000001;//000 = channel 0, (RA0/AN0)
while(1){
    ADIF=0;
    ADIE=1;
    PEIE=1;
    GIE=1;
    
    __delay_ms(1);
GO_DONE=1;
    __delay_ms(1);

    DAD=ADRESH;
    }
}
It is a very bad program.

1. The initialization is found inside the main loop. Nobody does that.
2. Interrupt is switched on, but no interrupt handler (this was pointed out already).
3. There are unneccessary delays.

OP needs to wait for the A/D like that:
Rich (BB code):
while(!ADIF);
The flag gets set anyway, no matter if you have interrupts enabled.

4. Use MPLAB X + templates. This would save OP from such a bad starter for a program.
 

Thread Starter

RRITESH KAKKAR

Joined Jun 29, 2010
2,829
This code is working fine now...!!
2. Interrupt is switched on, but no interrupt handler (this was pointed out already).
How to do this??
while(!ADIF);
not clear to me!!



Rich (BB code):
#include <htc.h>
__CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
#define _XTAL_FREQ 20000000


#define DAD PORTB


main(){
    TRISB=0X00;
TRISA = 0xff ;
ADCON1=0b00000000;
ADCON0=0b10000001;//000 = channel 0, (RA0/AN0)
    ADIF=0;
    ADIE=1;
    PEIE=1;
while(1){

    //GIE=1;
    
    __delay_us(10);
GO_DONE=1;
    __delay_us(10);

PORTB=ADRESH;
    }
}
 

Thread Starter

RRITESH KAKKAR

Joined Jun 29, 2010
2,829
The example was for timer but in ADC i think there is no need of it.....
Actually what is the need of ISR in ADC. if the ADC is working fine without it??
 

ErnieM

Joined Apr 24, 2011
8,377
This code is working fine now...!!
Excellent! Glad to see you keep at it.

I suggest you start by reading the C compiler manual for interrupts if you want to learn those.

not clear to me!!
Rich (BB code):
while(!ADIF);
ADIF is a flag (single bit) of the PIR register that is set when the A2D completes it's conversion. So the code while(!ADIF) will loop just on that line until ADIF is set, or until the conversion is complete.

Once you detect the conversion is complete you then reset ADIF so it is ready for the next time

But... I wouldn't do it that way. The GO_DONE bit you set to start a conversion is automatically reset when the conversion completes. So if you use:
Rich (BB code):
while(GO_DONE);
you get the same delay for the conversion to complete, and you need not reset the test bit.

ADIF is the Analog to Digital Interrupt Flag and is best for interrupt use... hey, that's what you want to learn, so there's some hints how to make the A2D trigger an interrupt.
 

spinnaker

Joined Oct 29, 2009
7,830
The example was for timer but in ADC i think there is no need of it.....
Actually what is the need of ISR in ADC. if the ADC is working fine without it??
The only interrupt for ADC would be the interrupt that occurs when the ADC is ready but there is really not a need in most cases.

I believe you can also interrupt when ADC reaches a certain level but that would be through a comparator.

You can use timer interrupts with ADC to read the ADC at regular intervals.
 

spinnaker

Joined Oct 29, 2009
7,830
Lots of people don't like using it because it is memory intensive but I use sprintf to make my job easier in writing numbers to the LCD.
 
Top