Unable to Reset ADC channel

Help
sansenan
2008-04-03
2013-03-12
  • sansenan
    sansenan
    2008-04-03

    hello,

             I am using PIC18f4550,and below is the code...The ADC works fine for any single channel..But i am unable to read multiple channels ..

    Pls help. The lower bits of the 2 channels are diplayed on the ports.I only see one channels
    reading on the PORT.

    Pls help this is urgent...

    void main(void)
    {

    int adc0,adc1; 
    TRISA = 0xff;         // All are inputs
    TRISB = 0;            // All are output
    TRISD = 0;
    count = 0;

    adc_open(ADC_CHN_1, ADC_FOSC_64,ADC_CFG_08A_0R, ADC_FRM_RJUST|ADC_INT_OFF);

    ADCON2bits.ACQT0 = 1;//(clock derived from A/D RC oscillator)
    ADCON2bits.ACQT1 = 1;
    ADCON2bits.ACQT2 = 1;
    adc_setchannel(ADC_CHN_0);
    adc_conv(); 

        while(1)
        {
             
                if (!ADCON0bits.GO) {
       
                          adc0 = adc_read();         // read value
                 }
                            adc_setchannel(ADC_CHN_1);
                            adc_conv();

                            if (!ADCON0bits.GO) {
       
                          adc1 = adc_read();         // read value
                 }

                            adc_setchannel(ADC_CHN_0);
                            adc_conv();

                                   
    PORTB = adc1  ;
    PORTD = adc0  ;   

        }        //   End While

    }

     
    • kein0r
      kein0r
      2008-04-03

      Afaik the adc code provided with sdcc doesnt work with most of the pic18f devices. It does, however, work using this http://sourceforge.net/tracker/index.php?func=detail&aid=1776197&group_id=599&atid=300599 patch. I usually do

      /**
      initializes the adc modul
      **/
      void init_adc(){
        // init read_sequence and values
        // Configure A/D
        // channel 0, fosc 6, pcfg 1110=14, config 0
        adc_open(read_sequence[read_counter] , ADC_FOSC_64, ADC_CFG_05A_0R, ADC_FRM_RJUST | ADC_INT_ON);
        // must be set manually, since it isnt done in adc_open
        // set for maximum (=20TAD) aquisition time
        ADCON2bits.ACQT0 = 1;
        ADCON2bits.ACQT1 = 1;
        ADCON2bits.ACQT2 = 1;
        TRISA = 0xff;   // input
        // start sampling adc data
        adc_conv();
      }

      and in an isr

      if (PIR1bits.ADIF) {
          values[read_counter] = adc_read();
          // increment channel read counter
          read_counter = (read_counter + 1) % sizeof(read_sequence);
          // set next channel
          adc_setchannel(read_sequence[read_counter]);
          // reset interrupt
          PIR1bits.ADIF = 0;
          adc_conv();       // when read_counter is again 0 wait for next round (see TMR1IF)
        }

      both adc_conv() are important, since you wont get any results or interrupts.

       
      • Raphael Neider
        Raphael Neider
        2008-05-01

        > Afaik the adc code provided with sdcc doesnt work with most of the pic18f devices. It does, however, work using this
        > http://sourceforge.net/tracker/index.php?func=detail&aid=1776197&group_id=599&atid=300599 patch.

        From SDCC rev. 5150 on, a modified variant of the patch is included/applied in the official SDCC sources.
        Success and failure reports are welcome.

        Regards,
        Raphael

         
    • sansenan
      sansenan
      2008-04-03

      Thanks kein for the help...

      I had previously updated your patch thats how i got the Module working...

      But need i to do a ISR to have the ADC work for multiple channels

      Is there no other way...If else Can you please also give the procidure how to call
      an ISR in main...can you please share the code for doing the same.

      Thanks again
      san

       
    • sansenan
      sansenan
      2008-04-03

      DO you see anything wrong in my code To do the same...
      All the modules work...

      I can individually set adc_setchannel(ADC_CHN_0); to any channel and have it read without  any problems
      But cant read the the next channel only the first channel read is displayed on the ports...
      And when i change the pot also..Only the first channel is updated..

      I think the problem might be in my way of calling the procedures.Is there anything wrong i did in the while loop ??

      Thanks again
      san

       
    • kein0r
      kein0r
      2008-04-03

      If im correct, sorry i have right now no device here to test it, the loop should be

      unsigned char act_channel;

      adc_open(ADC_CHN_0, ADC_FOSC_64,ADC_CFG_08A_0R, ADC_FRM_RJUST|ADC_INT_OFF);

      ADCON2bits.ACQT0 = 1;//(clock derived from A/D RC oscillator)
      ADCON2bits.ACQT1 = 1;
      ADCON2bits.ACQT2 = 1;
      /* dont switch chanel here directly after open */
      act_channel = ADC_CHN_0;
      adc_conv(); 

      while(1) 

      if (!ADCON0bits.GO) {
         /* read actual channel and determine next channel to read */
         if (act_channel == 0) {
           adc0 = adc_read(); // read value
           act_channel = ADC_CHN_1;
         } else {
           adc1 = adc_read(); // read value
           act_channel = ADC_CHN_0;
         }
         /* switch to that channel */
         adc_setchannel(act_channel);
         /* start conversion aka set ADCON0bits.GO */
         adc_conv();
      }
      PORTB = adc1 ;
      PORTD = adc0 ; 

      } // End While

       
    • sansenan
      sansenan
      2008-04-16

      Thanks a lot kein0r,

      That worked...I have my ADC working now ..I also recently tried hardware PWM in 18f4550 ..which also worked..
      But was thinking of doing More PWM channels ..Maybe a software PWM for any PINS i select..

      Have anyone tried this..

      with warm regards

       
      • kein0r
        kein0r
        2008-04-16

        Yes, there is a board that controls like 21 Servos with this "trick" (search for SD21 with google). Unfortunately this only works with slow frequencies.