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.

ADC in PIC 16F1503

Status
Not open for further replies.
Whoooh.... Lots wrong... Lets go through it.

First:- MCLRE is on and connected to AN3 .....No no!! make MCLRE = OFF.
Second:- ADCON1 ADFM isn't set to Right align..
Third:- This line
return ((ADRESH<<8)+ADRESL); // Return 10 bit ADC value
Isn't doing what you think
Forth:- RA0 is also earmarked for a n analogue input.


I changed all your code... I made the initADC universal for both A and C ports
I changed the getADC to atleast work..

Fill your boots.
C:
#include <xc.h>                                                                                    // edit MCB data at 3 places
// Config word
//__CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_ON & CP_OFF & CPD_OFF);

// Define CPU Frequency
// This must be defined, if __delay_ms() or
// __delay_us() functions are used in the code
#define _XTAL_FREQ   4000000  

#define AN1  1
#define AN2  2
#define AN3  3
#define AN7  7

#pragma config FOSC = INTOSC    // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF        // Watchdog Timer Enable (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = ON    // Clock Out Enable (CLKOUT function is enabled on the CLKOUT pin)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = ON 


int ADC_Val;


unsigned int GetADCValue(unsigned char Channel)
{
    ADCON0 |= Channel<<2;      // Clear Channel selection bits

    if(Channel > AN7) return 0;
   
    __delay_ms(10);      // Time for Acqusition capacitor to charge up and show correct value
    GO_nDONE  = 1;         // Enable Go/Done
    while(GO_nDONE);     //wait for conversion completion
    return (int)(ADRESH<<8)+ ADRESL ;   // Return 10 bit ADC value
}

void InitADC(unsigned char Channel)
{
    ANSELA   = 0x00;
    ANSELC   = 0x00;        // Clear Pin selection bits
    if(Channel < 4)    
        ANSELA  |= Channel;       // Select Channel
    else
        ANSELC  |= Channel;


    ADCON1 = 0b11110000;  
    ADCON0 = 0x01;         // Turn on the A/D Converter
    CM1CON0  = 0x07;         // Shut off the Comparator, so that pins are available for ADC
    FVRCON  = 0x00;         // Shut off the Voltage Reference for Comparator
}

void main() {
    OPTION_REGbits.nWPUEN = 1;
    //APFCON=0x20;
    //ANSELA = 0x08;
    //ANSELC=0X04;
    //ADCON0 = 0x08;
    TRISCbits.TRISC3 = 1;
    TRISAbits.TRISA0  = 0;
    RA0=0;
    InitADC(AN7);
   
    while(1)
    {
        ADC_Val = GetADCValue(AN7);
        if(ADC_Val<500)
        {
            RA0=0;
        }
        else
        {
            RA0=1;
        }
    }
}

You can now use all the ADC ports you have tried to cnfigure... MCLRE is OFF and should stay so.. The Reading of ADRESH is cast so it can be promoted to an int..
 
hello,

I read your code and responses of everybody but i think the problem is here :

When PIC reset, ANSELA = ---1-111 and ANSELC = ----1111
so RA4,RA2, RA1, RA0, RC3, RC2, RC1 and RC0 are analog input after reset

You clear ANSELC but not ANSELA so RA4, RA2, RA1 and RA0 are always analog inputs but RCx are digital inputs

write this in your code :
//ANSELA = 0x10;
//ANSELC=0X08;

and

ANSELA = 0x00; // Clear Pin selection bits
ANSELC = 0x00; // Clear Pin selection bits

best regards
 
Don't be sorry.
I think everyone made the mistake because AN3 is on RA4 and not on RA3
This justifies that PICCONTROLERLEARNER writed 0x08 ( 00001000 ) instead of 0x10 ( 00010000 )
 
Don't be sorry.
I think everyone made the mistake because AN3 is on RA4 and not on RA3
This justifies that PICCONTROLERLEARNER writed 0x08 ( 00001000 ) instead of 0x10 ( 00010000 )
He is only reading AN7.. So ANSELA isn't the issue..
 
yes of course.
what i mean is that put 0x08 in ANSELA instead of 0x10 has no effect because ANSELA wasn't clear !
But, as he put 0x04 in ANSELC after clearing it, he configures RC2 ( AN6 ) and not RC3 ( AN7 ).

Excuse me if I don’t write well but English is not my usual language !
 
Excuse me if I don’t write well but English is not my usual language !
No need for excuse... I don't want to confuse the OP... It looks like the code was originally designed for an older 8 pin pic.. "GPIO and TRIS" and I'm assuming his English is also a tad rusty...
 
That was a huge problem on earlier pics and seems to have been addressed on newer ones by having them off by default. Definitely worth checking though.

Mike.
 
That was a huge problem on earlier pics and seems to have been addressed on newer ones by having them off by default. Definitely worth checking though.

Mike.
they are off... since the "ol" pics they have their own control register... the code I posted works fine... We'll wait for the OP... he has probably been helped on another forum..
 
the code I posted works fine...
Actually, there are a couple of problems with that code, esp. for the 16F1503

Try this modified version of it:
Code:
// PIC16F1503
// Config word
//__CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_ON & CP_OFF & CPD_OFF);
// these should be before any '#include'
#pragma config FOSC = INTOSC    // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF        // Watchdog Timer Enable (WDT enabled)
#pragma config PWRTE = ON       // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled CLKOUT pin)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = ON

#include <xc.h>                                                                                    // edit MCB data at 3 places

// Define CPU Frequency
// This must be defined, if __delay_ms() or
// __delay_us() functions are used in the code
#define _XTAL_FREQ   4000000

#define AN0  0
#define AN1  1
#define AN2  2
#define AN3  3      // RA4
#define AN4  4
#define AN5  5
#define AN6  6
#define AN7  7      // RC3

unsigned int GetADCValue(unsigned char Channel)
{
    if (Channel > AN7) return 0;

    ADCON0 = (ADCON0 & 0x03) | (Channel<<2);   // select channel

    __delay_ms(1);                  // Time for Acqusition capacitor to charge up and show correct value
    GO_nDONE  = 1;                  // Enable Go/Done
    while(GO_nDONE);                // wait for conversion completion
    return (ADRESH<<8) | ADRESL;    // Return 10 bit ADC value (uses unsigned int operation)
}

void InitADC(unsigned char Channel)
{
    // all pins default to analog mode with TRISx = 1, so this isn't
    // required, but...
    switch (Channel) {
        case AN0: ANSELAbits.ANSA0 = 1; TRISAbits.TRISA0 = 1; break;    // RA0
        case AN1: ANSELAbits.ANSA1 = 1; TRISAbits.TRISA1 = 1; break;    // RA1
        case AN2: ANSELAbits.ANSA2 = 1; TRISAbits.TRISA2 = 1; break;    // RA2
        case AN3: ANSELAbits.ANSA4 = 1; TRISAbits.TRISA4 = 1; break;    // RA4
        case AN4: ANSELCbits.ANSC0 = 1; TRISCbits.TRISC0 = 1; break;    // RC0
        case AN5: ANSELCbits.ANSC1 = 1; TRISCbits.TRISC1 = 1; break;    // RC1
        case AN6: ANSELCbits.ANSC2 = 1; TRISCbits.TRISC2 = 1; break;    // RC2
        case AN7: ANSELCbits.ANSC3 = 1; TRISCbits.TRISC3 = 1; break;    // RC3
    }

    ADCON1 = 0b11110000;    // right-justified, FRC clock, VREF=VDD
    ADCON0 = 0x01;          // Turn on the A/D Converter
    // these are not needed... comparator off by default
    // CM1CON0  = 0x07;         // NOT CORRECT FOR 16F1503
    // FVRCON  = 0x00;         // Shut off the Voltage Reference for Comparator
}

void main() {
    unsigned int ADC_Val;

    OPTION_REGbits.nWPUEN = 1;
    //APFCON=0x20;
    TRISAbits.TRISA0  = 0;
    RA0=0;
    InitADC(AN7);

    while(1)
    {
        ADC_Val = GetADCValue(AN7);
        if(ADC_Val<500)
        {
            RA0=0;
        }
        else
        {
            RA0=1;
        }
    }
}

I left the MCLR and LVP settings the way they were... don't know if that matches what the OP wants or not.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top