Страница 3 из 7

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 16:56:57
kote52
[uquote="Dimon456",url="/forum/viewtopic.php?p=3991365#p3991365"]А что целиком код был? Жаль, не видал.
Я то же не программист, у меня образование 5 классов церковно-приходской, и вообще не понимаю в этих "иероглифах", какой-то "птичий язык".
Ну да ладно, мой код.
СпойлерИ так задача - запускать АЦП между импульсами ШИМ.

Код: Выделить всё

volatile uint16_t rezultat2;

// глубина буфера усреднения. чем больше, тем сильнее фильтрация и медленнее работа
// очень хорошо, если число кратно степени двойки (т.е. 1, 2, 4, 8, 16, 32, 64 и т.д.)
#define AVERAGE_DEPTH	8	
// функция получает результат очередного замера и возвращает отфильтрованное значение
__inline static uint16_t get_average (uint16_t val){
  static uint16_t buf[AVERAGE_DEPTH];
  static uint8_t cur;
  uint32_t sum = 0;

  buf[cur++] = val;
  if(cur >= AVERAGE_DEPTH) cur = 0;

  for(uint8_t i=0; i < AVERAGE_DEPTH; i++) sum += buf[i];

  return sum / AVERAGE_DEPTH;
}


// Timer1 output compare A interrupt service routine
ISR(TIMER1_COMPA_vect)
{
// Start the AD conversion
ADCSRA|=(1<<ADSC);
while ((ADCSRA & (1<<ADIF))==0);
ADCSRA|=(1<<ADIF);
 rezultat2 = get_average(ADCW);
 
 timer++;        //таймер шим 1кГц	
}

// Voltage Reference: AVCC pin
#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0<<ADLAR))

#define PERIOD_kHz 7999UL     //настроим Т1 на 1мс (1 кГц) = 8000000/1000Гц=8000-1=7999
#define IGLA   400                //Импульс 40.0%

int main()
{

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: Fast PWM top=ICR1
// OC1A output: Disconnected
// OC1B output: Inverted PWM
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 1 ms
// Output Pulse(s):
// OC1B Period: 1 ms Width: ... ms
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);

TCNT1=0;

ICR1=0x1F3F;	// 1F3F(7999) - 1кГц - 1.0000 ms

OCR1A=0;

OCR1B = (PERIOD_kHz*(1000-IGLA))*0.001;	// 40%

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (1<<OCIE1A) | (0<<TOIE1);

// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: AVCC pin
// ADC Auto Trigger Source: ADC Stopped
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
// ADC4: On, ADC5: On
DIDR0=(0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
ADMUX= 0 | ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);
ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);

sei();
   
while (1)
      {
      // Place your code here
      }
 }
Комментарии к коду:
Режим ШИМ Fast PWM top=ICR1
По какой то причине, а может и к лучшему режим выхода ШИМ OC1B output: Inverted PWM
значит ШИМ заполняется, скажем так, с конца а не сначала.
Соответственно когда TCNT1 будет равен 0 ШИМ будет выключен,
отсюда формируем прерывание Compare A Match Interrupt по совпадению OCR1A=0

И запускаем модуль АЦП, хорошо что один канал надо всего измерять.
От точки входа в прерывание, даже не от точки входа, а от момента когда произошло переключение ШИМ с высокого на низкий уровень, до функции get_average(ADCW) проходит ~110us, судя по измерениям в протеусе, значит %заполнения ШИМ не должен превышать 88%, в противном случае ШИМ перекроет измерение АЦП, и оно будет не корректным.[/uquote]
Привет! Изучаю таймеры. вот тут нарыл эту тему, мне в отличии от автора нужно не измерять напряжение когда ШИМ периода 0, просто флаг ставить правда когда период ШИМ сигнала в 1, а не в 0, и возводить флаг 1.
И у меня возникло несколько вопросов, почему вы рекомендуете режим ШИМ Fast PWM top=ICR1, а не Fast PWM top=OCR1A и как сделать это при выходе ШИМ OC1B output: Inverted PWM. Как понять что у нас сейчас в периоде ШИМ сигнала стоит высокий уровень, и сказать об этом флагом?
Автор тут что то начудил конечно с if(OCR1B>0 && OCR1B<PWR), ясное дело что OCR1B не увидишь изменения, тут лучше следить за TCNT1. но каким образом? Приходит на мой юный ум что то:

Код: Выделить всё

interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
if (TCNT1 > 0 && TCNT1 < PWR) {flag = 0;     //в момент когда Toff пднимемн флаг в 
      } else {flag = 1;}
}
...но это тоже полная ерись...
Вы ему советуете измерять чтобы ШИМ не привышал 88% понято дело почему, в этом периоде сначала идет низкий уровень, и максимум из ~110us на измерение можно выжать 8 измерений на 1ms. А как понять что у нас уже высокий уровень ШИМ ведь период начинается с низкого, и если мы это поняли то поднимает флаг, как только низкий уровень, то опустили флаг? Можно конечно поменять выход на OC1B output: Non Inverted PWM, но задача остается для меня не решенной как это реализовать?

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 17:20:17
Starichok51
kote52 писал(а):но это тоже полная ерись
и ерись через "и" тоже полная ересь ...

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 17:35:14
kote52
[uquote="Starichok51",url="/forum/viewtopic.php?p=4080014#p4080014"]
kote52 писал(а):но это тоже полная ерись
и ерись через "и" тоже полная ересь ...[/uquote]
а как прерывание по переполнению, прерывание наступило и что, у меня 50% высокий уровень 50% низкий. От чего мне отталкиваться, или от какой переменной?

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 17:56:37
Starichok51
а за каким хреном понадобился тебе этот флаг?
а где и как ты собрался проверять этот флаг?
и как ты собрался использовать этот флаг?

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 18:21:16
kote52
[uquote="Starichok51",url="/forum/viewtopic.php?p=4080039#p4080039"]1.а за каким хреном понадобился тебе этот флаг?
2.а где и как ты собрался проверять этот флаг?
3.и как ты собрался использовать этот флаг?[/uquote]
1. лично для меня флаг понадобился сделать к примеру 1000 импульсов, или 2000 насчитать... прошел верхний уровень периода ШИМ , счетчик инкрементирую...
2. как и где лучше проверить, это к вам вопрос по реализации, у меня скудно мыслей по этому поводу, но хотел бы научиться
могу конечно написать что то такое:

Код: Выделить всё

while(1){
if(flag==1) {cnt++;}
}
3. далее отсчитал 2000 импульсов и выключил ШИМ. Но у меня задача стоит научиться считать эти импульсы, в тот момент когда он начался, и понимать тот момент когда он закончился, т.е. как вы говорите жесткая привязка по времени... по переполнению я так понимаю на метод не дает такой полноты понимания?

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 19:33:19
Dimon456
kote52 писал(а):почему вы рекомендуете режим ШИМ Fast PWM top=ICR1, а не Fast PWM top=OCR1A
потому что OCR1A занят под прерывание.
kote52 писал(а):Как понять что у нас сейчас в периоде ШИМ сигнала стоит высокий уровень, и сказать об этом флагом?
Это не удобно, при высокой частоте ШИМ вы не успеете этот флаг в главном цикле отследить.

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 19:53:45
kote52
[uquote="Dimon456",url="/forum/viewtopic.php?p=4080083#p4080083"]
kote52 писал(а):Как понять что у нас сейчас в периоде ШИМ сигнала стоит высокий уровень, и сказать об этом флагом?
Это не удобно, при высокой частоте ШИМ вы не успеете этот флаг в главном цикле отследить.[/uquote]
т.е. если нужно пульнуть 200 импульсов частотой 1кГц, с заполнение 50% - проще это сделать в цикле for, или программный шим - "ногодрыг", и посчитать успеем заодно. Ну 1кГц частота не большая... мне интересно было сделать это, как то более правильно, рассуждая с точки зрения программирования под AVR, и получить от вас форумчане красивый пример для своей копилки. Вот например соседней теме "ATmega + 12bit ADC очень красивая дискуссия, и самое главное примеры. Особо других мест нет, где учиться))

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 20:03:01
Starichok51
kote52, если тебе нужно насчитать определенное число импульсов ШИМ, то можно применить прерывание по переполнению таймера, который вырабатывает эту ШИМ.
считай в прерывании количество переполнений. насчитаешь нужное число, отключишь ШИМ.

Добавлено after 1 minute 33 seconds:
да, и посмотри почту, я там тебе отправил предупреждение о нарушении правил форума.
будешь продолжать нарушать- дам бан.

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 20:18:07
kote52
[uquote="Starichok51",url="/forum/viewtopic.php?p=4080098#p4080098"]kote52,
считай в прерывании количество переполнений. насчитаешь нужное число, отключишь ШИМ.[/uquote]
Хорошо, я прислушаюсь к вашим словам! А если мне нужно сделать какое либо действие когда высокий уровень, по длительности - это 500us, а не просто считать период равный 1ms, т.е. = 1 переполнению.

[uquote="Starichok51",url="/forum/viewtopic.php?p=4080098#p4080098"]я там тебе отправил предупреждение о нарушении правил форума.[/uquote]
Видел, я учту!

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 21:23:35
Starichok51
если ШИМ выведена в порт, то проверяешь пин этого порта на высокий уровень. или на низкий уровень.
только проверять нужно достаточно часто, чтобы попадать несколько раз за один период ШИМ.

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вс авг 22, 2021 21:49:37
Dimon456
Starichok51 писал(а):то проверяешь пин этого порта на высокий уровень. или на низкий уровень.
Шикарный план.
Можно все на одном таймере сделать, если знать как работает таймер, не зачем проверять пин порта.
Код дать?

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Пн авг 23, 2021 04:12:58
kote52
[uquote="Dimon456",url="/forum/viewtopic.php?p=4080153#p4080153"]Можно все на одном таймере сделать, если знать как работает таймер, не зачем проверять пин порта.
Код дать?[/uquote]
Я бы для себя хотел прояснить как возможно сделать!
И в разговоре выше с Вами и Starichok51 я руководствовался этой иллюстрацией для режима Fast PWR:
Изображение

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Пн авг 23, 2021 12:45:33
neid
Ух, ничего себе тема моя ожила! А меня чуть ли гнобили(( но Dimon456, хочу сказать тогда его метод сработал, так и оставил, доделал ЗУ, уже трудится в сервисе у друга. И kote52, прав, это работает когда в периоде идет Toff(картинку приводил). А вот когда в периоде Ton, так и не добился замера. Поэтому выбирал из замеров, самое минимальное значение и относил его Toff, а что самое мальсимальное из замеров относил Ton.

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Пн авг 23, 2021 14:44:47
COKPOWEHEU
[uquote="kote52",url="/forum/viewtopic.php?p=4080218#p4080218"]Я бы для себя хотел прояснить как возможно сделать![/uquote]
Я, наверное, чего-то пропустил. Но что вызывает вопросы?
По прерыванию TIMERx_COMPY для прямого ШИМ попадаете на низкий уровень на выходе, по TIMERx_OVF - на высокий. Для инверсного ШИМ соответственно наоборот.
АЦП можно запустить сразу в прерывании таймера, но есть опасность что переходные процессы еще не закончатся - тогда можно запускать по прерыванию второго канала, который настроить со смещением от первого. А можно просто провести серию замеров, первый проигнорировать а остальные усреднить. Но тут надо посчитать сколько замеров АЦП успеет сделать гарантировано, не попав на высокий выходной уровень и сколько ждать от спада ШИМ до начала замера.

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Пн авг 23, 2021 15:32:11
kote52
[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4080360#p4080360"]По прерыванию TIMERx_COMPY для прямого ШИМ попадаете на низкий уровень на выходе, по TIMERx_OVF - на высокий. Для инверсного ШИМ соответственно наоборот.[/uquote]
Можно хотя бы условно примитивный код, у меня сейчас еще больше вопрос возникло, чем ответов)) то что мы попали, на высокий или низкий уровень - и что? нам надо понимать - что начался высокий уровень и сделать замер к примеру если про ацп речь уж. Это возможно?
[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4080360#p4080360"]А можно просто провести серию замеров, первый проигнорировать а остальные усреднить. Но тут надо посчитать сколько замеров АЦП успеет сделать гарантировано, не попав на высокий выходной уровень и сколько ждать от спада ШИМ до начала замера.[/uquote]
Примерно тож самое написал авто темы neid.

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вт авг 24, 2021 00:06:51
COKPOWEHEU
[uquote="kote52",url="/forum/viewtopic.php?p=4080377#p4080377"]Можно хотя бы условно примитивный код, у меня сейчас еще больше вопрос возникло, чем ответов)) то что мы попали, на высокий или низкий уровень - и что?[/uquote]
А чего вы хотите добиться?
Если синхронизироваться с ШИМом - пожалуйста, вот вам два прерывания на начало и конец импульса.
Примерно тож самое написал авто темы neid.
Могу только повторить: скорее всего, я с какого-то момента потерял нить рассуждения. ТС вроде бы хотел измерять по нижнему уровню ШИМа. Значит по TIMERx_COMPy можно запускать преобразование. Ну а там по алгоритму: можно просто выкинуть первое и ограничиться вторым. А можно складывать пока не наступит TIMERx_OVF - тогда посчитать среднее арифметическое из того что успело намериться.

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вт авг 24, 2021 08:45:30
Dimon456
kote52 писал(а):Можно хотя бы условно примитивный код,
Вы сами выше примитивный код приложили, чем не устраивает?

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вт авг 24, 2021 10:11:41
kote52
[uquote="Dimon456",url="/forum/viewtopic.php?p=4080153#p4080153"]Можно все на одном таймере сделать, если знать как работает таймер, не зачем проверять пин порта.
Код дать?[/uquote]
Вы вроде хотели научить как можно реализовать, вот и ждем вас чтоб постигнуть того что еще не знаем сами! Вам слово!

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вт авг 24, 2021 10:53:25
Dimon456
kote52 писал(а):Вы вроде хотели научить
Я научить ... у меня образование 5 классов церковно-приходской, какой с меня учитель, пусть другие учат. Могу просто код дать.

Re: Фильтр АЦП atmega 8 по нижней границе

Добавлено: Вт авг 24, 2021 11:08:19
kote52
Dimon456, Давай те код, буду вникать так! Вообще есть мысли смотреть регистр TIFR1 помойму OCF1A - Флаг прерывания по событию "совпадение А" таймера/счетчика Т