2015-03-01 3 views
0

У меня есть код для измерения значений АЦП на номера каналов, хранящихся в массиве ch1 (первые 2 канала соответствуют измерению напряжения конденсатора Vc, а затем следующие 6 каналов соответствуют измерению тока сетки Ia, Ib, Ic; и последние 6 каналов соответствуют измерению напряжения сетки Va, Vb, Vc). Я пишу код для Atmega2560 arduino-Mega.Код АЦП на atmega2560

Чрезмерная всей структуры кода: 1.In настройки функции(), я инициализируется АЦП, Serial-монитор и прерывание 2.In функцию петли(), я начала преобразования АЦП для каждого канала, хранящихся в массиве названный ch1, чтобы получить напряжение конденсатора, ток сетки и напряжение сети в последовательности.

Я не могу получить желаемый результат, с помощью которого я имею в виду, что на последовательном терминале после 5-6 строк ничего не печатается.

#define F_CPU 16000000UL 
#include <avr/io.h> 
#include <util/delay.h> 
#include <avr/interrupt.h> 
//#include <util/atomic.h> 


#define ChannelMax 4 
uint8_t ch1[]={0,0,1,1,2,2,3,3,4,4,5,5,6,6};//channels for //Vc,Vc,Ia,Ia,Ib,IB,Ic,Ic,Va,Va,Vb,Vb,Vc,Vc(capacitor voltage,grid current,grid voltage) 

volatile unsigned short ci=0;//index for ch1 array 

unsigned int ADarray[15];//array to store ADC output data 
volatile unsigned short readFlag=0;//it is set from ADC ISR when either Vc 
or all I or all V is measured twice  






void setupADC(); 
uint16_t adc_read(uint8_t ch); 
void adc_start(uint8_t ch); 
//setup function detail for arduino 
void setup() 
{ 
    cli(); 

    Serial.begin(9600);  // connect to the serial port 
    setupADC(); 

    sei(); 


} 

//looping for infinity 
void loop() 
{ 
    while(1) 
    { 

    //initialize things 
    ci=0;// start with first channel present in ch1 
    Serial.print("Vc measuring started with"); 
    Serial.println(ch1[ci]); 
    adc_start(ch1[ci]);//start adc to measure Vc i.e ch1[0] and ch1[1] 
    //do something whil Vc is measured 

    while(1){ //wait till end of ADC measurement of Vc 
    if(readFlag==0){ 
    Serial.println(readFlag); 
    Serial.println("Vc beingmeasured"); 
    } 
    else break; 

    }; 
    readFlag=0; Serial.println("Vc finally measured"); 
//use Vc i.e. ADarray[1] for calculation 



Serial.print("I measuring started with ");Serial.println(ch1[ci]); 
adc_start(ch1[ci]);//start adc to measure grid current Ia,Ib,Ic i.e ch1[2] 
    //to ch1[7] 
//do something while grid current is being measured 
while(1){ //wait for end of measurement of grid current 
    if(readFlag==0){ 
    Serial.println(readFlag); 
    Serial.println("I beingmeasured"); 
    } 
    else break; 
}; 
readFlag=0; Serial.println("I finally measured"); 
//Use i i.e. ADarray[3],5,7 for calculation 





Serial.print("V measuring started with ");Serial.println(ch1[ci]); 
    adc_start(ch1[ci]);//start measurement of grid voltage Va,Vb and Vc 
//do something while grid volt is being measured 
while(1){//wait till end of measurement of grid voltage 
    if(readFlag==0){ 
    Serial.println(readFlag); 
    Serial.println("V beingmeasured"); 
    } 
    else break; 
}; 
readFlag=0;Serial.println("V finally measured"); 
//Use V i.e. ADarray[9],11,13 for calculation 




    }//end of while loop 
}//end of loop function 

//setup registers for ADC in atmega 2560 
void setupADC(){ 
    ADCSRA = 0; 
    ADCSRB = 0; 
    ADMUX = ch1[ci];  // Channel 0 only 
    ADMUX |= (1<<REFS0);//ADMUX|=0b01000000;//use it if u want to use AVCC  //as Aref internally ,but dont forget to use external cap at AREF 

    ADCSRA = _BV(ADEN) ; // Enable ADC, 
    //ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0) ;//prescale at 128. 
    ADCSRA|=_BV(ADIE);//to interupt enable for ADC 
    //ADCSRA |= _BV(ADSC); // Start initial ADC cycle 


} 
//Interrupt service routine for ADC measurment 
ISR(ADC_vect){ 

    ADarray[ci]=(unsigned int)ADC; 
    Serial.print(ch1[ci]);Serial.println("adc read"); 
    ci++;ci++;Serial.print(ci); 
    //if(ci>=ChannelMax) ci=0; 

    if((ci==2) ||(ci==8) ||(ci==14)){ 
    Serial.println("finished"); 
    readFlag=1; 
    return ; 
    } 
    //Serial.println("adc started"); 
    adc_start(ch1[ci]); 
    //Serial.print(ch1[ci]);Serial.println("adc started"); 





} 



//function to start ADC for particular channel 
void adc_start(uint8_t ch){ 
    // Serial.print(ch);Serial.println("adc started subroutine"); 
    // select the corresponding channel 0~7 
    // ANDing with ’7? will always keep the value 
    // of ‘ch’ between 0 and 7 
    ch &= 0b00001111; // AND operation with 7 
    ADMUX = (ADMUX & 0xF0)|ch; // clears the bottom 3 bits before ORing 

    // start single convertion 
    // write ’1? to ADSC 
    ADCSRA |= (1<<ADSC); 
} 

ответ

0

делать вещи, я понял, что не следует использовать Serial.print внутри ISR или любой функции, вызываемой из ISR (возможно, потому, что Serial.print использует прерывание) ... Тогда вопрос заключается в том, что, как отладить внутри ISR ? Могу ли я использовать Atomic_Block, чтобы что-то сделать?