Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ADC doesn't work properly PIC microcontroller

Status
Not open for further replies.

sam.mosfet

Newbie level 6
Joined
Dec 25, 2014
Messages
12
Helped
1
Reputation
2
Reaction score
1
Trophy points
3
Activity points
79
I have been playing with this code for about a week now and for some reason it does't work. I had some friends at school take a look at it they all could't see what is wrong with it. I am about to give up on this. I don't understand why it would't work correctly. the code looks fine but the output is not correct. The LED's dont light up when they are suppose to light up. When it is above about 2.5 volts the LEDs shoud go high. then when it is below that they should go low. I get the opposite when it is below 2.5 they are high and when it is above 2.5 they are low. I dont get it !! the only time it kinda worked was when I grounded AN0 but that is just weird... anyways this is my most recent code. any help would be appreciated.

Code:
#include <xc.h>

// Config word
#define _XTAL_FREQ   2000000 // set it to match internal oscillator

/*config1 and config2 settings*/
 // CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (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) (turned on!)/
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is MCLR) (turned off)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data 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. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

// CONFIG2
 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
 #pragma config VCAPEN = OFF // Voltage Regulator Capacitor Enable bit (Vcap functionality is disabled on RA6.)
 #pragma config PLLEN = ON // PLL Enable (4x PLL enabled)
 #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 Enable Bit (Low power brown-out is disabled)
 #pragma config LVP = OFF // Low-Voltage Programming Enable (Low-voltage programming enabled) (turned off)/


// Do the ADC convertion only for the channel indicated
// result of ADC is returned
 unsigned int ReadADC(unsigned char channel)
{
     unsigned int AN_Val;
     unsigned int bit_val;

   

     // automaticaly determines the input channel it will read the value from
     switch (channel)
         {
         case 1: // AN1 1000 0101
             ADCON0 = 0x85;                // bit0: ADC enabled
                                          //bit6-2: AN1 enabled for analog input
                                        //bit7: set for a 10-bit result(when its 1)
             break;
         case 2: // AN2 1000 1001
             ADCON0 = 0x89;
             break;
         case 3: //AN3 1000 1101
             ADCON0 = 0x8D;
             break;
         case 4: //AN4 1001 0001
             ADCON0 = 0x91;
             break;
         default: // Any other value will default to AN0
             ADCON0 = 0x81; // (1000 0001) - AN1 set up ADC ADCON0

 // sets the ADCON0 register for each port depending on the value of channel.
 // the result is 10-bit , The ADC is set to on, No convertion is in progress

         } // switch (channel)

     // Channel selected proceed with ADC convertion
    __delay_us(20); // sampling time
    ADCON0 = ADCON0 | 0x02; //This sets the go/!done bit that starts conversion. Bit will be cleared when ADC is complete
    while (ADCON0 & 0x02); //wait here until conversion is complete
    bit_val= ADRESH; // store upper 2 bits in a 16 bit int
    AN_Val = ((bit_val << 8) + ADRESL) & 0x03ff;// store the ADRESH into the 16 bit int then split it up 8 spaces after that add the ADRESL values using the and operator then clear any signed bits
    return AN_Val;
} // int ADC(unsigned char channel)



void main (void){

  //** Initalise Ports FOR ADC **//


  unsigned int AN1_Result;
  unsigned int AN0_Result;
  unsigned int AN2_Result;

  //** Initalise Ports FOR ADC **************************************************************//
     PORTA = 0x00; //Set ports to low
     PORTB = 0x00;
     TRISA = 0xFF; //Port A is all inputs. (set to 1)

     //** Set Up ADC Parameters **//
     ANSELA =0x2F ; // (0b00101111)All AN0-AN4(RA4 and RA7 have no ADC) of register A are set to analog input

     ADCON1 = 0xD0; // (0b11010000)
                    //format setup see page 182 of datasheet
                    // bit7: set for 2'complement format
                    // bit6-4 : set FOSC/16
    //********************************************************************************************//
 

  PORTC = 0x00;
  TRISC = 0x00; //Port C all output
  
         while(1){
       // __delay_us(10);
        AN0_Result = ReadADC(1);
        if(AN0_Result > 500){    // when the voltage is passed 2.5(almost) volts these two LEDS should come on.
                /*Turn these LED on*/
                LATCbits.LATC2 = 1;
                LATCbits.LATC3 = 1;
                LATCbits.LATC4 = 1;
                }
        else{
                /*turn one LED on*/
                LATCbits.LATC4 = 0;
                LATCbits.LATC2 = 0;
                LATCbits.LATC3 = 0;

                }
    }
}
 

Please specify the MCU.
The LED's dont light up when they are suppose to light up. When it is above about 2.5 volts the LEDs shoud go high. then when it is below that they should go low. I get the opposite when it is below 2.5 they are high and when it is above 2.5 they are low. I dont get it !! the only time it kinda worked was when I grounded AN0 but that is just weird...
I read three outcomes here:
1. Does not work.
2. Work with an opposite result.
3. and kinda works.
Is the 3 related to the 2 or they're separate states?
 

What PIC is the program written for? Looks like a PIC18 but the ADC configuration varies from one device to another. In particular the ADCON1 bit 7 does different things.

Brian
 

Sorry I forgot to mention that I am using PIC 16F788 .
 

Please zip and post the complete mplabx project files.
 

Here is the complete folder zipped. thanks
 

Attachments

  • ADC.X.zip
    123.3 KB · Views: 86

The code is for a 16F1788 not a 16F788 (if such a thing exists).

You seem to be trying to take a differential measurement with only one input. You have the ADC references set to 0=VSS and max=VDD but are returning a 2's compliment result. Bit 7 of ADCON1 should be = 0.

You also have the ADC set in 10-bit mode. For best results when you combine ADRESH and ADRESL you should set it to 12-bit mode.

Brian.
 

Got it to work I forgot to set the ADON2 register of the PIC. That fixed it and explained why I had to ground AN0 before to make it work. thanks for your help.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top