У меня есть код для измерения значений АЦП на номера каналов, хранящихся в массиве 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);
}