This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Wrong reading provided by ADC while using 2 ADC Channels

I was using an ADC channel ADC0.1 in lpC2468 for taking controller to power down, and it worked properly. Now I configured ADC channel 2 ADC0.2 for reading value from thermistor, as I load code into the controller the controller goes to power down just after reset after code loading.

if i comment init_adc_thermistor() i.e. ADC channel 2 initialization the system works properly,controller does not go to power down.

I am using both channels turn by turn, as shown in code in interrupt routine of channel1, i configure channel 2 and in interrupt routine of channel 2 i configure channel 1 of ADC

My code has following format

Void main()
{
   Init_peripherals();
   Init_Adc();
While(1){
//statements

                }

}
 ADC channel 1 initailized for power down 
void Init_Adc(void){
PINSEL1 |=0x00004000;
AD0CR = 0X0021ff01;
VICVectAddr18 = (unsigned)ADC_on_con_isr
VICIntEnable |= 0x00040000;
AD0INTEN = 0X00000001;
AD0CR |= 0X01000000;
}


 channel1 interupt routine 
void ADC_on_con_isr(void) __irq{
        int Dvalue;
        Dvalue =(AD0DR0 >> 6)& 0x3ff;
        AD0DR0 = 0X00000000;    //CLEAR ALL DATA
        AD0GDR=0X00000000;
             VICVectAddr = 0x00000000;
         init_adc_thermistor();ADC channel 2 initialized

        if(Dvalue<0x292){
        //power down
                                       }

                                           }


 ADC channel 2 initailized for  thermistor 
void init_adc_thermistor(void){
 PINSEL1 |=0x00010000;
AD0CR         = 0X00218002;
VICVectAddr18 = (unsigned)
VICIntEnable |= 0x00040000
AD0INTEN      = 0X00000002;
AD0CR        |= 0X01000000;
                                   }




 channel2 interupt routine 
void ADC_on_thermistor(void)__irq
{
int Dvalue1;
Dvalue1 =(AD0DR1 >> 6)& 0x3ff;
AD0DR1 = 0X00000000;
AD0GDR=0X00000000;
VICVectAddr = 0;
Init_Adc(); ADC channel 1 initialized
If(Dvalue1<0x170)
//printer off
}

  • Now, I'm confused - why do you initialize the ADC again and again?

    Use a single ISR.

    Start a conversion.

    Let the ISR pick up the data - either from that specific channel. Or after all enabled channels has been converted.

    Your ISR should not play around like it does now.

  • @Per Westermark sir u mean to say that i should do like this

    
    void Init_Adc(void){
    
    PINSEL1 |=0x00014000; adc function selected for both pins
    AD0CR = 0X00218003; both channels selected
    VICVectAddr18 = (unsigned)ADC_on_con_isr
    VICIntEnable |= 0x00040000;
    AD0INTEN = 0X00000003;interrupts enabled for both channels 
    AD0CR |= 0X01000000;
    }
    
    
    void ADC_on_con_isr(void) __irq{
            int Dvalue,adc_value;
    
     channel 1 data reading 
            Dvalue =(AD0DR0 >> 6)& 0x3ff;
            AD0DR0 = 0X00000000;    //CLEAR ALL DATA
            AD0GDR=0X00000000;
    
     channel 2 data reading 
     adc_value =(AD0DR1 >> 6)& 0x3ff;
      AD0DR1 = 0X00000000;
       AD0GDR=0X00000000;
    
    VICVectAddr = 0x00000000;
    
        if(Dvalue<0x292)
            //power down
    
    
    if(adc_value<0x170)
      //printer off
    
                                               }
    
    

  • I haven't scanned through all your bits there, but consider checking bit DONE in the ADxDRx register to verify if the interrupt handler has a new valid value available - this flag is auto-cleared when you read from the data register so you don't need to write zero to the register.

    And either run conversion continuously (which requires that you slow down the ADC conversion speed) or have your main loop now and then start a conversion.