zhongshanlang 发表于 2008-4-4 10:54:30

ADC中断问题

#pragma interrupt_handler adc_isr:22
void adc_isr(void)
{
    unsigned char temp;          

        IDCBusSample = ADCL;
        temp = ADCH;
        IDCBusSample += (unsigned int)(temp << 8);
          
    IDCBusSum += IDCBusSample;
    IDCBus = IDCBusSum >> IDCBUS_FILT_INDEX;
    IDCBusSum -= IDCBus;
                     
    if(IDCBus > IDCBusMax)
    {
             nr_overcurrent++;
             if(nr_overcurrent > 3)
               {
                          nr_overcurrent = 0;
                          FaultStatus = ERROR_OVERCURRENT;
             }
        }
    else
    {                     
             nr_overcurrent = 0;
        }
}

/*---          Get the ADC result         ---*/
unsigned int adc_result(unsigned char channel)
{
       unsigned int result;
           unsigned char temp;
          
           //--- Select the AD channel ---
       ADMUX &= 0xe0;//default

           ADMUX += channel;                     
          
           //--- ADC start convertion ---
           ADCSRA += 0x40;

           temp = ADCSRA;
           while((temp & 0x40) == 0x40)
           {
             _NOP();
                   temp = ADCSRA;
           }                     
           result = 0;
           result += ADCL;
           temp = ADCH;
          
           result += (unsigned int)(temp << 8);                     
          
           return(result);           
}
/*---   Initialize the A/D converters    ---*/
void init_adc(void)
{
   //Select the ref volt and adc channel
   ADMUX += 1 << REFS0;   //AVCC with external capacitor at AREF pin.
       ADCSRA += 1 << ADPS2;//Division factor : 64       
       ADCSRA += 1 << ADPS1;
       //ADCSRA += 1 << ADPS0;
       ADCSRA += 1 << ADATE;//Auto triger
       ADCSRA += 1 << ADIF;
       ADCSRA += 1 << ADIE;   //Enable the adc       
       ADCSRB += 1 << ADTS2;//Triger source: Timer0 overflow
       
       /*---      Enable ADC      ---*/
       ADCSRA |= 0x80;
}
我用了4个ADC管脚,想不同顺序的进行AD转换,我可以怎么做好呢? 按照我这样的写法,在MAIN()中调用的时候会中断掉。到底怎么样能做到有顺序的转换呢?请大家帮忙想想。

machao 发表于 2008-4-4 13:09:31

用CVAVR中的程序生成向导生成一ADC中断的程序框架,然后学习里面的处理方法.

zhongshanlang 发表于 2008-4-4 13:45:23

谢谢machao,虽然我还没有解决,但是我知道问题在哪里!

zhongshanlang 发表于 2008-4-8 09:54:30

已经解决了,在ADC中断中用switch语句选择通道就可以了。这个想法很不错的,调了很久才调通的。
现在把问题的答案发上来和大家分享下。
#pragma interrupt_handler adc_isr:22
void adc_isr(void)
{
       static unsigned char adc_state = 0;
       unsigned char temp;                     
          
          
           IDCBusSample = ADCL;
           temp = ADCH;
           IDCBusSample += (unsigned int)(temp << 8);
           ADMUX &= 0xe0;
          
           switch(adc_state)
           {
             case 0:
                IDCBusSum += IDCBusSample;
                IDCBus = IDCBusSum >> IDCBUS_FILT_INDEX;
                IDCBusSum -= IDCBus;
                               
                        if(IDCBus > IDCBusMax)
                        {                     
                                nr_overcurrent++;
                                if(nr_overcurrent > 3)
                                {
                                    nr_overcurrent = 0;
                                    FaultStatus = ERROR_OVERCURRENT;
                                }
                        }
                        else
                        {                     
                                nr_overcurrent = 0;
                        }       

                                //ADMUX &= 0xe0;
                                ADMUX += 1;
                                adc_state++;                  
                        break;
                   case 1:
                        TBottomBusSum += IDCBusSample;
                TBottomBus = TBottomBusSum >> TBOTTOMBUS_FILT_INDEX;
                TBottomBusSum -= TBottomBus;

                                  
                                ADMUX += 2;
                                adc_state++;                          
                        break;
                   case 2:
                        TTopBusSum += IDCBusSample;
                TTopBus = TTopBusSum >> TTOPBUS_FILT_INDEX;
                TTopBusSum -= TTopBus;
                               
                                ADMUX += 3;
                                adc_state++;                          
                        break;
                   case 3:
                        TBoilerBusSum += IDCBusSample;
                TBoilerBus = TBoilerBusSum >> TBOILERBUS_FILT_INDEX;
                TBoilerBusSum -= TBoilerBus;
                               

                                adc_state = 0;                          
                        break;
                   default:
                                adc_state = 0;                          
                        break;
           }                                 
}
页: [1]
查看完整版本: ADC中断问题