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.

       
    • 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.

         

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks