• AVR Freaks

Hot!ADC in 16F876a

Author
buildlab
Starting Member
  • Total Posts : 32
  • Reward points : 0
  • Joined: 2019/06/26 11:50:03
  • Location: 0
  • Status: offline
2019/12/07 01:09:03 (permalink)
0

ADC in 16F876a

Hi i am a complete beginner in pic programming.
i have been playing around with pic 16f876a for a couple of days.
i cant seem to make the adc pins working.
as there is no ANSEL register for initilizing ADC pins its quite a bit confusing.
can anyone help me to write a sample code adc input ?


#include <xc.h>
#define _XTAL_FREQ 8000000// PIC16F886 Configuration Bit Settings
// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// 'C' source line config statements
int sensor;
int readAdc(int);
void main(void) {
PORTA = 0x00;
PORTC = 0x00;
PORTC = 0x00;
TRISA = 0xFF;
TRISB = 0x00;
TRISC = 0x00;
//ADCON1 = 0b10000000; // not sure about this part
// ANSEL = 0b00000111;
// CMCON = 0x07;


while(1)
{
sensor = readAdc(2);
if (sensor > 500)
{
RC7 = 1;
}
if (sensor < 500)
{
RC7 = 0;
}

}
}
int readAdc(int channel){
int vol;
ADCON0 = 0x83 | (channel << 2);  // i have taken this as right oriented, rest is unclear
ADCON1 = 0b10000000;
__delay_us(20);
GO = 1;
while(GO == 1);
vol = (ADRESH << 8) + ADRESL;
__delay_us(5);
return vol;
}

can anyone let me know what corrections i should do to make this code work ? .i need to make this work for my college project,any help would be appreciated.
#1

13 Replies Related Threads

    ric
    Super Member
    • Total Posts : 27979
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 01:29:34 (permalink)
    +2 (2)
    buildlab
    as there is no ANSEL register for initilizing ADC pins its quite a bit confusing.

    There is a register to control it, but it is not called ANSEL.
    The ADC inputs are controlled by the PCFG bits in the ADCON1 register.
     
    You don't mention how fast your PIC is running. This detail is needed to calculate the correct ADC clock.
    Your comment about selecting "right justified" is on the wrong register. That is controlled by ADCON1, not ADCON0.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    buildlab
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2019/06/26 11:50:03
    • Location: 0
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 02:27:54 (permalink)
    0
    Thank you Ric , i tried to modify the code according to your suggestions.

     
     
     
    #include <xc.h>
    #define _XTAL_FREQ 8000000// PIC16F886 Configuration Bit Settings
    // CONFIG
    #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
    #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
    #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
    #pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
    #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
    #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
    #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
    #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
     
     
     
    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.
    // 'C' source line config statements
    int sensor;
    int readAdc(int);
     
     
     
    void main(void) {
    PORTA = 0x00;
    PORTC = 0x00;
    PORTC = 0x00;
    TRISA = 0xFF;
    TRISB = 0x00;
    TRISC = 0x00;
    ADCON1 = 0b100000; // right justified and turned all analog inputs ON (conversion clock i selected fosc/8)
    // CMCON = 0x07;


    while(1)
    {
     
    sensor = readAdc(2);
    if (sensor > 500)
    {
    RC7 = 1;
    }
    if (sensor < 500)
    {
    RC7 = 0;
    }

    }
    }
    int readAdc(int channel){
    int vol;
    ADCON0 = 0b0101011 | (channel << 2); (clock fosc/8,adc channel2 ,Go/done and ADON)
    ADCON1 = 0b100000;
    __delay_us(20);
    GO = 1;
    while(GO == 1);
    vol = (ADRESH << 8) + ADRESL;
    __delay_us(5);
    return vol;
    }
     
     
     

      
    when i try to simulate in proteus simulator i am getting error "
    [PIC16 ADC] PC=0x07B8. Attempt to sample non-existant ADC channel 5 (zero assumed). [U1]"

    And the code doesn't seems to work. what are the changes i have to make  ?
    post edited by buildlab - 2019/12/07 02:35:01
    #3
    ric
    Super Member
    • Total Posts : 27979
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 02:56:27 (permalink)
    +1 (1)
    You should count the bits in your values here:
     ADCON1 = 0b100000; // right justified and turned all analog inputs ON (conversion clock i selected fosc/8)


    here
    ADCON0 = 0b0101011 | (channel << 2); (clock fosc/8,adc channel2 ,Go/done and ADON)
     
    and here
    ADCON1 = 0b100000;



    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #4
    buildlab
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2019/06/26 11:50:03
    • Location: 0
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 03:10:49 (permalink)
    0
    Yes i corrected it according the values but still i am getting error in proteus.
    "
    [PIC16 ADC] PC=0x07B8. Attempt to sample non-existant ADC channel 5 (zero assumed). [U1]"
    is there any other changes i have to make for the adc to work ?
     
    i am so sorry Ric i know its a simple code, been trying to make it work since a couple of days.
    #5
    ric
    Super Member
    • Total Posts : 27979
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 03:13:36 (permalink)
    0
    What do you mean "corrected it" ?
    All those values are corrupted, because you have miscounted 8 bits.
    I think your "correcting" was actually "corrupting".
    It's not that hard if you just do what the datasheet tells you to do.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #6
    ric
    Super Member
    • Total Posts : 27979
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 03:20:26 (permalink)
    0
    Why do you keep jumping PIC models, and not finishing projects?
     
    PIC16F676: https://www.microchip.com/forums/m1115992.aspx
    PIC16F886: https://www.microchip.com/forums/m1121108.aspx
    and now PIC16F876 here

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #7
    buildlab
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2019/06/26 11:50:03
    • Location: 0
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 03:28:43 (permalink)
    0
    These are the values i have given after correcting it.

    ADCON0 = 0b01010101 | (channel << 2);
    ADCON1 = 0b10000000;

     
    #8
    buildlab
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2019/06/26 11:50:03
    • Location: 0
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 03:32:56 (permalink)
    0
    The project with 16f676 is finished. Because it was a 14 pin Controller and we require more pins for the coming project. That's why i shifted from 16f676 to 16f886 and 16f876a. 
     i had been doing projects in Arduino and adrduino ide based controllers. Here in pic there are no sample codes or anything available to understand. Thats why we have to depent on  microchip community this much. 
     
    post edited by buildlab - 2019/12/07 03:37:21
    #9
    1and0
    Access is Denied
    • Total Posts : 10997
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 04:04:12 (permalink)
    +1 (1)
    buildlab
    These are the values i have given after correcting it.

    ADCON0 = 0b01010101 | (channel << 2);
    ADCON1 = 0b10000000;


    Do you know what the Bitwise OR operator does?  Why are you ignoring my suggestions in the PIC16F886 thread that Ric linked to?
     
    buildlab
    The project with 16f676 is finished. Because it was a 14 pin Controller and we require more pins for the coming project. That's why i shifted from 16f676 to 16f886 and 16f876a. 
    i had been doing projects in Arduino and adrduino ide based controllers. Here in pic there are no sample codes or anything available to understand. Thats why we have to depent on  microchip community this much. 

    Open both 16F886 and 16F876A datasheets to the ADC chapter, and compare the bits in both the ADCON0 and ADCON1 registers.



    #10
    ric
    Super Member
    • Total Posts : 27979
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 04:37:42 (permalink)
    +1 (1)
    This line probably does what you want
    ADCON1 = 0b10000000;
    i.e. it sets bit 7, which is ADFM, so you get a right justified result.

    but this line
    ADCON0 = 0b01010101 | (channel << 2);
    is just plain wrong. Maybe if you try to describe what each bit is doing, you will see why.



     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #11
    buildlab
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2019/06/26 11:50:03
    • Location: 0
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 05:13:37 (permalink)
    0
    It worked when i edited ADCON0 value.

    #include <xc.h>
    #define _XTAL_FREQ 8000000// PIC16F886 Configuration Bit Settings
    // CONFIG
    #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
    #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
    #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
    #pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
    #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
    #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
    #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
    #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.
    // 'C' source line config statements
    int sensor;
    int readAdc(int);
    void main(void) {
    PORTA = 0x00;
    PORTC = 0x00;
    PORTC = 0x00;
    TRISA = 0xFF;
    TRISB = 0x00;
    TRISC = 0x00;
    ADCON0 = 0b10000001;
    ADCON1 = 0b10000000;
    while(1)
    {
    sensor = readAdc(2);
    if (sensor > 500)
    {
    RC7 = 1;
    }
    if (sensor < 500)
    {
    RC7 = 0;
    }
    }
    }
    int readAdc(int channel){
    int vol;
    ADCON0bits.CHS = channel;
    __delay_us(20);
    GO = 1;
    while(GO == 1);
    vol = (ADRESH << 8) + ADRESL;
    __delay_us(5);
    return vol;
    }

    Thank you for the helping out @ric.
    #12
    1and0
    Access is Denied
    • Total Posts : 10997
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 05:32:30 (permalink)
    +1 (1)
    If you had followed all the suggestions in both threads ;)
    unsigned int readAdc(unsigned char channel) {
        ADCON0bits.CHS = channel;
        __delay_us(20);
        GO = 1;
        while (GO == 1);
        return ((ADRESH << 8) + ADRESL);
    }

    #13
    buildlab
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2019/06/26 11:50:03
    • Location: 0
    • Status: offline
    Re: ADC in 16F876a 2019/12/07 10:48:36 (permalink)
    0
    Hey thank you for the correction.
    @1and0
    #14
    Jump to:
    © 2020 APG vNext Commercial Version 4.5