Globlal Variable Problem: Pic18f4550 and Pickit3 Debugging

adcmicrocontrollerpicprogramming

I'm working on a project which includes the usage of the A/D converter module in the micro-controller (pic18f4550). I haven't had any problems in the past with the micro-controller using a pickit3 programmer for the debugging process.

The problem comes when I'm in the debugging process since I know that the value of the ADC converter can the result be storage in ADRESH in my case (Left Justify), after that I want to save this result in a simple variable,when I'm doing this process the result of ADC converter isn't saved properly giving a rare result.

The following code was implemented, also I've done a video to reproduce the problem.

#include "fuses.h"
#include <stdio.h>
#include <adc.h>
#include <p18f4550.h>
#include <delays.h>

int Canal0,dato1,dato2; 
#define  Time Delay10KTCYx(60)

void main(void)

{ 

TRISA=0XFF;             //PORTA INPUTS
TRISB=0xFF;             //PORTB OUTPUTS
TRISC=0X00;
TRISD=0x00;             //PORTB OUTPUTS
PORTC=0x00;
PORTD=0x00;
PORTB=0x00;             //CLEAN PORTB

 //ADC Configs
ADCON1=0b00001011;      //  Canales AN0,AN1,AN2,AN3 ADCON1:|0|0|VSS(0)|VDD(0)|AN3(1)|AN2(0)|AN1(1)|AN0(1)|
                        //  VSS,VDD 5v / 2^8 = 20mV por numero osea que para 100 = 20mV*1.953125~1.96
ADCON2=0b00011010;      //  ADCON2: ADFM Left justified(0)|-|6 TAD (0)|6 TAD(1)|6 TAD (1)|FOSC32(0)|FOSC32(1)|FOSC32(0)|
/*  . . .ADRESH . . : . . ADRESL. . .
    7 6 5 4 3 2 1 0 : 7 6 5 4 3 2 1 0
    X X X X X X X X . X X . . . . . . <-Left Justified
    . . . . . . X X . X X X X X X X X <-Right Justified
 */
ADCON0=0b00000000;      //  |-|-|CHS3(0)|CHS2(0)| CHS1 (0)| CHS0(0)| GO/DONE | ADON (0) AD DISABLED.
//when adon=1 , go_done 1 = A/D conversion in progress 0 = A/D Idle
ADCON0bits.ADON = 0x01;    //Enable A/D module

while(1)
{
    Canal0=0;
    //blinker();          //STATUS
    ADCON0bits.ADON = 0x01;//Enable A/D module
    SetChanADC(ADC_CH0);  //Seleciono canal.
    Delay10TCYx(1);         
    ConvertADC();
    while(BusyADC()==1){}
    dato0=ReadADC();
    Delay10TCYx(1);

    SetChanADC(ADC_CH1);  //Seleciono canal.
    Delay10TCYx(1); 
    ConvertADC();
    while(BusyADC()==1){}
    dato1=ReadADC();
    Delay10TCYx(1);

    SetChanADC(ADC_CH2);  //Seleciono canal.
    Delay10TCYx(1);
    ConvertADC();
    while(BusyADC()==1){}
    dato2=ReadADC();
    Delay10TCYx(1);

}

}

What could be the problem ? if the adc converter module is configured ok, and the reading process is ok, maybe the problem is the data type.

    SetChanADC(ADC_CH0);  //Channel
    Delay10TCYx(1);
    ConvertADC();          //Begin convertion
    while(BusyADC()==1){}  //Convertion in progress.
    dato2=ReadADC();       //Move the adresh result to the variable. unsigned int
    Delay10TCYx(1);

The video is : here

Best Answer

Of course. Do notice that I don't use an ADC-library. Maybe you should try to read the ADC-value without using the library and see if that works.

    //confifure A/D-module
void adc_module_setup() {
    ADCON0bits.ADRMD = 0;           //12 bits result
    ADCON0bits.CHS = 0b01010;       //analog channel select
    ADCON0bits.GO_nDONE = 0;        //ADC conversion completed/not in progress

ADCON1bits.ADFM = 1;            //2's complement format
ADCON1bits.ADCS = 0b101;        //ADC conversion clock; 101 => Fosc/16
ADCON1bits.ADNREF = 0;          //negative voltage reference; 0 => Vss
ADCON1bits.ADPREF = 0b00;       //positive voltage reference; 00 => Vdd

ADCON2bits.CHSN = 0b1111;
ADCON0bits.ADON = 1;            //ADC enabled

}

//function to read the ADC-result and return the value

unsigned int read_analog_value(unsigned char channel) {

ADRESH = 0x00; ADRESL = 0x00; unsigned int adc_result; adc_result = 0x0000; ADCON0bits.CHS = channel; __delay_us(10); //acquisition time ADCON0bits.GO_nDONE = 1; //start conversion while(ADCON0bits.GO_nDONE) { } //conversion busy adc_result = ADRESH; adc_result <<= 8; adc_result |= ADRESL; PIR1bits.ADIF = 0; //clear interrupt flag ADCON0bits.GO_nDONE = 0; //clear GO_nDONE return adc_result;

}