Перенос математических преобразований из ISR в LOOP

DimaP.
Offline
Зарегистрирован: 21.04.2013

Здравствуйте прошу помощи!

подскажите как можно математические функции, в частности возведение в квадрат (строка 167) и суммирование квадратов перенести из обработчика прерывания в loop!

Это нужно для того, чтобы повысить точность измерения такой длинный код в ISR выполняется не коректно((


// Подключаем стандартную библиотеку LiquidCrystal
#include <LiquidCrystal.h>
#include <Wire.h>
#include <DS1307.h> //Подключение библиотеки для DS1307
// Инициализируем объект-экран, передаём использованные 
// для подключения контакты на Arduino в порядке:
// RS, E, DB5, DB6, DB7, DB8
LiquidCrystal lcd(4, 5, 10, 11, 12, 13);

/* переменные работающие в обработчике прерывания */
volatile long Uism_A = 0; // переменная для хранения измеренного напряжения и квадрата фазы А
volatile long Usumm_A = 0; // переменная для хранения сумм квадратов фазы А 
volatile long Uism_B = 0; // ------В-----
volatile long Usumm_B = 0;//------В------
volatile long Uism_C = 0; // -------С-----
volatile long Usumm_C = 0;// --------С------
volatile int cntr = 0; // счетчик в обработчике прерывания

/* подключаем аналоговые входы */
int ADC0 = 0; // аналоговый вход 0 для переменной Ucor!
int ADC1 = 1; // вход измерения фазы А
int ADC2 = 2; // вход измерения фазы B
int ADC3 = 3; // вход измерения фазы С
int Ucor = 0; // переменная будет хранить напряжение корректировки!!!

/*переменные для расчета реальных величин!!*/
int real_U_A = 0; //переменная расчета рельной величины для фазы А
float sqrtUsum_A = 0.0; //переменная расчете квадратного корня для фазы A
int real_U_B = 0; //переменная расчета рельной величины для фазы В
float sqrtUsum_B = 0.0; //переменная расчете квадратного корня для фазы В
int real_U_C = 0; //переменная расчета рельной величины для фазы С
float sqrtUsum_C = 0.0; //переменная расчете квадратного корня для фазы С



unsigned long timeOut = 0;// переменная для хранения времени!!!
unsigned long time = 0;


void setup()  
{ 
    TIMSK2 = 0b00000000;         // запрещение прерывания по совпадению таймера/счетчика Т2  
    TCCR2A = 0b00000100;       // режим работы СТС
    TCCR2B = 0b00000101;     // предделитель на 32
    ASSR &= ~(1<<AS2);    // Выбор источника синхронизации таймера(от системного генератора
                                         
    OCR2A = 100;           // срабатывание таймера 16000000/32/100=5000 раз в секунду 100 раз за секунду
    
                    
     lcd.begin(16, 2);
     
     
     RTC.stop();
  RTC.set(DS1307_SEC,1);        //set the seconds
  RTC.set(DS1307_MIN,50);     //set the minutes
  RTC.set(DS1307_HR,15);       //set the hours1
  RTC.set(DS1307_DOW,4);       //set the day of the week
  RTC.set(DS1307_DATE,14);       //set the date
  RTC.set(DS1307_MTH,07);        //set the month
  RTC.set(DS1307_YR,13);         //set the year
  RTC.start(); 
}


void loop() 
{    
  if(millis() - timeOut >400)// ждем 0,25 секунды и...
 
  {
    Ucor = analogRead (ADC0); // сохраняем напряжение коррекции
    cntr = 0;
    TCNT2 = 0x00; // перезарежаем таймер
    /* обнуляем суммы напряжений*/ 
    Usumm_A = 0;
    Usumm_B = 0;
    Usumm_C = 0;
    
    TIMSK2 |= (1<<OCIE2A); // разрешаем прерывание по совпадению
    timeOut = millis();
  }
  
    
  
  
  
  /* расчет реальных величин*/
   if (cntr==100)
  {
    sqrtUsum_A = sqrt(Usumm_A); //вычисляем квадратный корень из суммы квадратов
    real_U_A = 0.104 * sqrtUsum_A; //вычисляем реальное напряжение для фазы А
    /*для фазы В */
    sqrtUsum_B = sqrt(Usumm_B); //вычисляем квадратный корень из суммы квадратов
    real_U_B = 0.104 * sqrtUsum_B; //вычисляем реальное напряжение для фазы В
    /*для фазы С */
    sqrtUsum_C = sqrt(Usumm_C); //вычисляем квадратный корень из суммы квадратов
    real_U_C = 0.104 * sqrtUsum_C; //вычисляем реальное напряжение для фазы С
  }
	



  if(millis() - time >50)
   {
    lcd.setCursor(0, 1);
    // печатаем вторую строку
    lcd.print("A=");
    lcd.print(real_U_A);
    lcd.setCursor(5, 1);
    lcd.print("B=");
    lcd.print(real_U_B);
    lcd.setCursor(10, 1);
    lcd.print("C=");
    lcd.print(real_U_C);
     time = millis();
   } 
  
  // вывод времени и даты!  
  lcd.setCursor(8,0);
  lcd.print(RTC.get(DS1307_HR,true)); // печатаем час
  lcd.setCursor(10,0);
  lcd.print(":"); // печатаем разделитель
  lcd.setCursor(11,0);
  lcd.print(RTC.get(DS1307_MIN,false)); // печатаем минуты
  lcd.setCursor(13,0);
  lcd.print(":"); // печатаем разделитель
  lcd.setCursor(14,0);
  lcd.print(RTC.get(DS1307_SEC,false)); // печатаем секунды
if (RTC.get(DS1307_DATE,false)<=9)//если едициц дней меньше-равно 9, то выводим на 1 шаг правее
  { lcd.setCursor(0, 0);
    lcd.print(" ");
    lcd.setCursor(1, 0);
    lcd.print (RTC.get(DS1307_DATE,false));}
  else // иначе (т.е. если единиц дней больше 9, то выводим на 1 шаг левее
  { lcd.setCursor(0, 0);
    lcd.print (RTC.get(DS1307_DATE,false));}
    
  //Отображение текущего месяца
  lcd.setCursor(2, 0); //указываем место печати названия месяца
  switch (RTC.get(DS1307_MTH,false)) // в зависимости от значения месяца печатаем название
  {
    case 1:    lcd.print("-01");    break;
    case 2:    lcd.print("-02");    break;
    case 3:    lcd.print("-03");    break;
    case 4:    lcd.print("-04");    break;
    case 5:    lcd.print("-05");    break;
    case 6:    lcd.print("-06");    break;
    case 7:    lcd.print("-07");    break;
    case 8:    lcd.print("-08");    break;
    case 9:    lcd.print("-09");    break;
    case 10:   lcd.print("-10");    break;
    case 11:   lcd.print("-11");    break;
    case 12:   lcd.print("-12");    break;
  }
} 
	 
	 
	//****************обработчик прерывания********************
	
ISR(TIMER2_COMPA_vect) 
	
{  
           
  if (cntr<=99)     
 {
   /*для фазы A */
  Uism_A = analogRead(ADC1); // считываем значения с аналогового порта 1
  Uism_A -= Ucor; // убираем подьем синусоиды на 2 вольт
  Uism_A *= Uism_A;// возводим значение в квадрат
  Usumm_A += Uism_A; // склдываем квадраты измерений
  /* для фазы B */
  Uism_B = analogRead(ADC2); // считываем значения с аналогового порта 2
  Uism_B -= Ucor; // убираем подьем синусоиды на 2 вольт
  Uism_B *= Uism_B;// возводим значение в квадрат
  Usumm_B += Uism_B; // склдываем квадраты измерений 
 /* для фазы С */  
  Uism_C = analogRead(ADC3); // считываем значения с аналогового порта 3
  Uism_C -= Ucor; // убираем подьем синусоиды на 2 вольт
  Uism_C *= Uism_C;// возводим значение в квадрат
  Usumm_C += Uism_C; // склдываем квадраты измерений  
  
  cntr++; // увеличиваем счетчик на 1 с каждым тактом!
                }
          else  
          {
                   TIMSK2 = 0b00000000; // останавливаем таймер
          }
      }           

 

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

ну сделайте массив для каждой фазы и заносите измерения в п/прог. прерывания в массив, а потом с 89 строки спокойно все посчитайте

только память подсчитайте чтоб хватило

DimaP.
Offline
Зарегистрирован: 21.04.2013

переписал я прогу немного вот что получилось


// Подключаем стандартную библиотеку LiquidCrystal
#include <LiquidCrystal.h>

//Подключение библиотеки для DS1307
// Инициализируем объект-экран, передаём использованные 
// для подключения контакты на Arduino в порядке:
// RS, E, DB5, DB6, DB7, DB8
LiquidCrystal lcd(4, 5, 10, 11, 12, 13);

/* переменные работающие в обработчике прерывания */
volatile int Umass_A [99]; //масив переменных для хранения мгновенных напряжений фазы А

volatile int Umass_B [99]; //масив переменных для хранения мгновенных напряжений фазы B

volatile int Umass_C [99]; //масив переменных для хранения мгновенных напряжений фазы C

long Uism_A = 0; // переменная для хранения измеренного напряжения и квадрата фазы А
long Usumm_A = 0; // переменная для хранения сумм квадратов фазы А 
long Uism_B = 0; // ------В-----
long Usumm_B = 0;//------В------
long Uism_C = 0; // -------С-----
long Usumm_C = 0;// --------С------
volatile int cntr = 0; // счетчик в обработчике прерывания

/* подключаем аналоговые входы */
int ADC0 = 0; // аналоговый вход 0 для переменной Ucor!
int ADC1 = 1; // вход измерения фазы А
int ADC2 = 2; // вход измерения фазы B
int ADC3 = 3; // вход измерения фазы С
int Ucor = 0; // переменная будет хранить напряжение корректировки!!!

/*переменные для расчета реальных величин!!*/
int real_U_A = 0; //переменная расчета рельной величины для фазы А
float sqrtUsum_A = 0.0; //переменная расчете квадратного корня для фазы A
int real_U_B = 0; //переменная расчета рельной величины для фазы В
float sqrtUsum_B = 0.0; //переменная расчете квадратного корня для фазы В
int real_U_C = 0; //переменная расчета рельной величины для фазы С
float sqrtUsum_C = 0.0; //переменная расчете квадратного корня для фазы С

/* переменные массивов*/

unsigned long timeOut = 0;// переменная для хранения времени!!!
unsigned long time = 0;


void setup()  
{ 
    TIMSK2 = 0b00000000;         // запрещение прерывания по совпадению таймера/счетчика Т2  
    TCCR2A = 0b00000100;       // режим работы СТС
    TCCR2B = 0b00000011;     // предделитель на 32
    ASSR &= ~(1<<AS2);    // Выбор источника синхронизации таймера(от системного генератора
                                         
    OCR2A = 100;           // срабатывание таймера 16000000/32/100=5000 раз в секунду 100 раз за секунду
    
                    
     lcd.begin(16, 2);
    
}


void loop() 
{    
  
  if(millis() - timeOut >100)// ждем 0,25 секунды и...
 
  {
    Ucor = analogRead (ADC0); // сохраняем напряжение коррекции
    
    TCNT2 = 0x00; // перезарежаем таймер
    /* обнуляем суммы напряжений*/ 
    Usumm_A = 0; 
    Usumm_B = 0;
    Usumm_C = 0;
    
    TIMSK2 |= (1<<OCIE2A); // разрешаем прерывание по совпадению
    timeOut = millis();
  }
  
    
  
  
  
  /* расчет реальных величин*/
   if (cntr==100)
  {
  /* Uism_A -= Ucor; 
  Uism_A *= Uism_A;// возводим значение в квадрат
  Usumm_A += Uism_A;   */
   
  /* Uism_B -= Ucor; // убираем подьем синусоиды на 2 вольт
  Uism_B *= Uism_B;// возводим значение в квадрат
  Usumm_B += Uism_B; // склдываем квадраты измерений   */
     
 /* Uism_C -= Ucor; // убираем подьем синусоиды на 2 вольт
  Uism_C *= Uism_C;// возводим значение в квадрат
  Usumm_C += Uism_C; // склдываем квадраты измерений  */
  
  
  
  for ( int i =0; i<=100; i++)
  {  
    Uism_A =  Umass_A [i];
    Uism_A -= Ucor;// убираем подьем синусоиды на 2 вольт
    Uism_A *= Uism_A;// возводим значение в квадрат
    Usumm_A += Uism_A;// склдываем квадраты измерений
    
  }
   
  
   
    sqrtUsum_A = sqrt(Usumm_A); //вычисляем квадратный корень из суммы квадратов
    real_U_A = 0.104 * sqrtUsum_A; //вычисляем реальное напряжение для фазы А
    /*для фазы В */
    sqrtUsum_B = sqrt(Usumm_B); //вычисляем квадратный корень из суммы квадратов
    real_U_B = 0.104 * sqrtUsum_B; //вычисляем реальное напряжение для фазы В
    /*для фазы С */
    sqrtUsum_C = sqrt(Usumm_C); //вычисляем квадратный корень из суммы квадратов
    real_U_C = 0.104 * sqrtUsum_C; //вычисляем реальное напряжение для фазы С
 
    cntr = 0;
  }
	



 
    lcd.setCursor(0, 1);
    // печатаем вторую строку
    lcd.print("A=");
    lcd.print(real_U_A);
    lcd.setCursor(5, 1);
    lcd.print("B=");
    lcd.print(Usumm_A);
    
     time = millis();
     
  
}
	 
	//****************обработчик прерывания********************
	
ISR(TIMER2_COMPA_vect) 
	
{  
           
  if (cntr<=99)     
 {
   /*для фазы A */
  Umass_A [cntr] = analogRead(ADC1); // считываем значения с аналогового порта 1 и сохранием в массив
  
  /* для фазы B */
  Umass_B [cntr] = analogRead(ADC2); // считываем значения с аналогового порта 2 и сохранием в массив
  
 /* для фазы С */  
  Umass_C [cntr] = analogRead(ADC3); // считываем значения с аналогового порта 3 и сохранием в массив
  
  
  cntr++; // увеличиваем счетчик на 1 с каждым тактом!
                }
          else  
          {
                   TIMSK2 = 0b00000000; // останавливаем таймер
         

 

DimaP.
Offline
Зарегистрирован: 21.04.2013

но погрешность все равно выше чем в примере когда вычисления производятся в обработчике ISR

самое интересное меняю настроики таймера, замедляю его и точность вырастает, до 1 процента!!

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

сумму квадратов только для фазы А находите, это для отладки или забыли остальные фазы дощитать(101 строка)

DimaP.
Offline
Зарегистрирован: 21.04.2013

это пока только для отладки

DimaP.
Offline
Зарегистрирован: 21.04.2013

наверное это из за функции analogRead которая тратит время на перключение каналов ацп

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

ну тогда вместо аналогреад попробуйте напрямую с АЦП считывать

DimaP.
Offline
Зарегистрирован: 21.04.2013

помните  axill писал 

Кстати если и время преобразования через analogRead будет дольше, если почитать даташит, то там различается время первого преобразования и время последующего. analogread каждый раз переключает канал на ADC, а это значит, что она каждый раз инициирует первое измерение - самое длинное. Разница почти в два раза - 25 циклов против 13. Когда мы измеряем всего один канал у нас нет потребности в переключении. Но конечно не всегда эта разница в скорости критична, но стоит все просчитать. Что не маловажно - по даташиту требуется, чтобы для 10 битного режима ADC если мы хотим качественное преобразование то частота работы ADC не должна превышать 200кГц, а это как раз уже может наложить ограничения на скорость измерений!

DimaP.
Offline
Зарегистрирован: 21.04.2013

Вот как раз то этого я еще не научился делать!!

там ведь число  разбивается на 8 разрядов и 2 ADCH и ADCL соответственно а как из них получить число как при использовании analogRead не понимаю!!да и настройки для новичка в программировании сложноватые!

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

ну у вас изначально стояла задача просто вольтметр сделать...Как вариант увеличить до макс частоту и если можно точность(если можно), ну и попробовать напрямую к АЦП обращаться без библиотеки

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

вот например как

void ADC_ISR()org IVT_ADDR_ADC{
*p = ADCL;
*(p+1) = ADCH;        //для 10разрядов переписать
p++;
k++;
if(k>maxp)TOIE0_bit = 0;
}

p - это указатель на элемент массива

т.е я явно не задавал массив, а задавал его начала base

объявлениеe указателя:  int *p;

чтобы указатель стал на первый элемент пишем p = base // реальный адрес в памяти, с которого начнется массив

записать в первый элемент: *p = ADCL; *(p+1) = ADCH

в следующий:    p++; \\ если р=100, то станет 102... у нас указатель на 2 байтное число

                        *p = ADCL; *(p+1) = ADCH 

ну и т.д.

 

 

step962
Offline
Зарегистрирован: 23.05.2011

Посмотрите на строки 11-15 своего нового скетча.

Потом посмотрите на строку 100.

Потом - на строку 146.

После этого ответьте на вопрос: с каким количеством измеренных значений вы работаете - 98, 101 или 100...

DimaP.
Offline
Зарегистрирован: 21.04.2013
volatile int Umass_A [99];

в этой строке я указал массив переменных от 0 до 99 итого 100!

for ( int i =0; i<=100; i++)

в этой строке накасячил соглассен цикл будет выводить значения от 0 до 100 а это 101 значение

 if (cntr<=99)     
 {
   /*для фазы A */
  Umass_A [cntr] = analogRead(ADC1); // считываем значения с аналогового порта 1 и сохранием в массив
  

  
  
  cntr++; // увеличиваем счетчик на 1 с каждым тактом!
                }

ну а здесь вроде бы тоже логично(вроде, если что попправте меня) запускаем таймер и первое значение записанное в массив будет с индексом 0 а последнее 99!

step962
Offline
Зарегистрирован: 23.05.2011

DimaP. пишет:

в этой строке я указал массив переменных от 0 до 99 итого 100!

Вы, может быть, и указали 100 элементов, но любой компилятор воспримет это как объявление массива с 99 элементами (имеющими номера от 0 до 98). Шилдт вам в помощь:

Одномерные массивы

DimaP.
Offline
Зарегистрирован: 21.04.2013

step962 пишет:

Шилдт вам в помощь:

Одномерные массивы

и в правду ведь помогло, проблема то была в том что накосячил я с объявлением массива , а потом и с записью данных, и выводом массива тоже косяка упорол, сейчас подкоректировал код, точность выросла до 0.7 % Теперь все четко!

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

на 3 канала хватает времени в ISR c аналогреад?

DimaP.
Offline
Зарегистрирован: 21.04.2013

Над 2 остальными какналами буду работать сегодня надо ведь еще аппаратную часть доработать!

DimaP.
Offline
Зарегистрирован: 21.04.2013

Проверка показала что с analogRead функцией вычисления по фазе А дают плавающие значения в диапазоне 1 вольта, а вот фаза B дает уже погрешность в 3-4 вольта, фазу С не проверял, но наверняка такой же результат!

DimaP.
Offline
Зарегистрирован: 21.04.2013

Michal пишет:

вот например как



void ADC_ISR()org IVT_ADDR_ADC{
*p = ADCL;
*(p+1) = ADCH;        //для 10разрядов переписать
p++;
k++;
if(k>maxp)TOIE0_bit = 0;
}

p - это указатель на элемент массива

т.е я явно не задавал массив, а задавал его начала base

объявлениеe указателя:  int *p;

чтобы указатель стал на первый элемент пишем p = base // реальный адрес в памяти, с которого начнется массив

записать в первый элемент: *p = ADCL; *(p+1) = ADCH

в следующий:    p++; \\ если р=100, то станет 102... у нас указатель на 2 байтное число

                        *p = ADCL; *(p+1) = ADCH 

ну и т.д.

 

 

Просто дело в том что программа Arduino IDE не хочет кущать такой код!!!

Я не понимаю

вот у нас есть 8 битное число записанное в ADCH. A так же 2 битное записанное ADCL. причем при считывании мы должны писать его первым!!

Т.е когда АЦП измерил напряжение мы в этих регистрах получаем 2 числа, а что дальще с ними они так же и остаются 2 разными числами, мы их должны сложить или умножить??

И еще вопрос когда мы устанавливаем вход с которого мы будим считывать в регистре ADMUX мы же можем только 1 канал установить как в настройках включить другие каналы, чтобы измерять 3 фазы?

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

про АЦП меги статья собранная с даташита там более менее описан ацп

про результат преобразования: в ADMUX есть бит ADLAR. Смысл - выравнивает данные влево или вправо(в моем примере данные вправо выравнены), т.е получаем обычное число: в ADCL - младшая часть, ADCH - старшие 2 бита.

на счет чо делать с данными: я под меги в ардуиновском иде не пешу и тут я не советчик, но в С (как  я привел пример), да и  др. языках, можно адресоваться к ячейкам памяти через указатели. Т.е. в указателе хранится адрес на то( в нашем примере на число типа int) что мы хотим записать или считать с памяти. Значение указателя командой p++ увеличивается на число равное размеру данных на которые он указывает(у нас на 2).

Т.о. для заполенния массива нужно:

int *p; - это указатель в С на число типа int

1. задать начало его - конкретное значение адреса: p = 0x100;

2. пишем в текущую ячейку памяти:

                                         *p = ADCL;  - здесь пишем младшую часть

                                         *(p+1) = ADCH  -  старшую

3. меняем адрес на следующий елемент массива:    p++,     т.е. если было 0х100, станет 0х102

4. проверяем на конец или кол-во элементов массива, если все нормально идем на П.2

К примеру, 3 значения с АЦП:

Указатель     Адр   Данные
============================
p=100           100   ADCL1       *p
                101   ADCH1       *(p+1) 
p=102           102   ADCL2
                103   ADCH2
p=104           104   ADCL3
                105   ADCL3

для считывания 2 байт просто пишем Uizm = *p;  Uizm должно быть определено как 2 байтное

как менять канал АЦП: см. статью. Просто в Admux меняете соответствующее поле и со следующего перобразования подключается выбранный канал

DimaP.
Offline
Зарегистрирован: 21.04.2013

Пробовал я использовать аналоговые входы на прямую вот что получилось


word read_adc(byte adc_input);
/* переменные работающие в обработчике прерывания */
volatile int Umass_A;
volatile int cntr;
/* подключаем аналоговые входы */
#define U_a             1



/* переменные массивов*/

unsigned long timeOut = 0;// переменная для хранения времени!!!
unsigned long time = 0;



void setup()  
{ 
    TIMSK2 = 0b00000000;         // запрещение прерывания по совпадению таймера/счетчика Т2  
    TCCR2A = 0b00000100;       // режим работы СТС
    TCCR2B = 0b00000011;     // предделитель на 32
    ASSR &= ~(1<<AS2);    // Выбор источника синхронизации таймера(от системного генератора
                                         
    OCR2A = 100;           // срабатывание таймера 16000000/32/100=5000 раз в секунду 100 раз период
 
 ADMUX = (0<<REFS1)|(1<<REFS0)|(0<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
 //вкл. ацп, режим одиночного преобр., разрешение прерывания, F преобр. = FCPU/128 125кГц
 ADCSRA = 0b10001111;
                 
    Serial.begin(9600);
}


void loop() 
{    
  
  if(millis() - timeOut >300)// ждем 0,25 секунды и...
 
  {
    timeOut = millis();
   TCNT2 = 0x00; // перезарежаем таймер
  TIMSK2 |= (1<<OCIE2A); // разрешаем прерывание по совпадению
  cntr=0;
  }


Serial.println(cntr);
if(cntr == 100)
{
  
  
}
  
}


//функция для считывания с заданного аналогоого порта

word read_adc(byte adc_input)
{            
 word i;
 
 // ADC initialization
 // ADC Clock frequency: 125 kHz
 
 // ADC Auto Trigger Source: None
 ADMUX=0b0100000;
 ADCSRA=0b10000111;   // 0x10000111 - Enable, CLK/128
 
 ADMUX=adc_input;           
 
 // Delay needed for the stabilization of the ADC input voltage
 delayMicroseconds (50);
         
 // 3 холостых чтения
 for (i=0; i<3; i++)
 {
  // Start the AD conversion (ADSC)
  ADCSRA|=0x40;             
  
  // Wait for the AD conversion to complete (ADIF)
  while ((ADCSRA & 0x10)==0);
 
  ADCSRA|=0x10; 
  
  i=ADCW;     
 } // for
 
 // Читать значение АЦП
 i=ADCW&0xFFFE;
 
 // ADC off
 ADCSRA=0x00;
 ADMUX=0x00;

 return i;
} // read_adc


	 
	//****************обработчик прерывания********************
	
ISR(TIMER2_COMPA_vect) 
	
{  
           
  if (cntr<=99)     
 {
   cntr++; // увеличиваем счетчик на 1 с каждым тактом!
   /*для фазы A */
  Umass_A = read_adc(U_a); // считываем значения с аналогового порта 1 и сохранием в массив
  
  
  
  
                }
          else  
          {
                   TIMSK2 = 0b00000000; // останавливаем таймер
          }
      }           

 

опыт показал что функция которая должна была работать не работает!!!

подскажите пожауйста где я ошибся??

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

попробуйте без п/п препывания своей ф-ей почитать значения