Перейти к содержанию
    

ATMEGA8535. Странности с TIMER1, OCR1A

Делаю регулятор мощности. Детектор нуля вырабатывает импульсы с частотой 100 Гц. Выход детектора на внешнее прерывание. При срабатывании внешнего прерывания запускается TIMER1, отсчитывает угол открывания симистора. При совпадении останавливается TIMER1 и запускается TIMER0 который выдает пачки импульсов частотой 40 кГц. В общем, многоимпульсное управление симистором.

 

Проблема: При срабатывании внешнего прерывания запускается TIMER1, в регистр OCR1A загружается значение угла. Если значение нуле, то нет прерывания по совпадению при нуле. Начиная от единицы МК ведет себя корректно. Импульсы смотрю осциллографом. Притом, совершенно случайно заметил следующее, я выключил макетную плату и появились импульсы, пока было достаточное питание на МК. То есть, что получилось. Сработало внешнее прерывание, запустился TIMER1, и так как теперь нет перезапуска таймера следующим внешним прерыванием, то TIMER1 перевалил и сработало прерывание по совпадению при нуле.

 

Как победить? Пока решение только одно. Если значение нуль, то принудительно запускаем генератор пачки импульсов.

 

На картинке тестовая программа. В регистр совпадения принудительно загружается значение на 5 мс, то есть получается меандр из пачек импульсов.

 

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

//========================================================================
#pragma inline = forced
void set_timer1_on (void)
{
  if (opening_angle != 0)
  {
     set_bit (TIFR, OCF1A);
     TCNT1 = 0;
     OCR1A = opening_angle;
     set_bit (TIMSK, OCIE1A);
     set_bit (SFIOR, PSR10);
     TCCR1B = (1<<CS11);
  }
  else
  {
     Start_10_kGz ();
  }
}

#pragma inline = forced
void set_timer1_off (void)
{
  clr_bit (TIMSK, OCIE1A);
  TCCR1B = 0;
}

#pragma vector = TIMER1_COMPA_vect
__interrupt void TIMER1_COMPA_handler (void)
{
  set_timer1_off ();
  Start_10_kGz ();
}
//========================================================================

post-79709-1467044661_thumb.jpg

Изменено пользователем demiurg1978

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В данный момент пока в лоб. Переменный резистор подключен ко входу АЦП. Исходим из того, какой кварц стоит. Пусть 16 МГц. При делителе 64 10 мс таймеру нужно оттикать 2500 раз. Так как у нас обратная зависимость значения таймера к углу, точнее, времени открывания (0 - полная мощность, 2500 нулевая), то формула получается следующая: 2500 - (ацп*2500/1024). Я пока решил сделать при делителе 8, то есть значение теперь 20000, формула: 20000 - (ацп*20000/1024)/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.е. 10000, записанные в регистр сравнения, соответствуют 90градусам.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

(0 - полная мощность, 2500 нулевая)
При таком раскладе одна дискрета мощности у вас 0,04%,

так что 0 или 1 записан в регистр сравнения, разницы ни какой.

Вы на детектировании нуля теряете больше (если AVR182 пользуетесь).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...