Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATMEGA8535. Странности с TIMER1, OCR1A
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
demiurg1978
Делаю регулятор мощности. Детектор нуля вырабатывает импульсы с частотой 100 Гц. Выход детектора на внешнее прерывание. При срабатывании внешнего прерывания запускается TIMER1, отсчитывает угол открывания симистора. При совпадении останавливается TIMER1 и запускается TIMER0 который выдает пачки импульсов частотой 40 кГц. В общем, многоимпульсное управление симистором.

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

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

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

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

//========================================================================
#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 ();
}
//========================================================================
domowoj
А каким образом определяете угол открывания, значение OCR1A.
demiurg1978
В данный момент пока в лоб. Переменный резистор подключен ко входу АЦП. Исходим из того, какой кварц стоит. Пусть 16 МГц. При делителе 64 10 мс таймеру нужно оттикать 2500 раз. Так как у нас обратная зависимость значения таймера к углу, точнее, времени открывания (0 - полная мощность, 2500 нулевая), то формула получается следующая: 2500 - (ацп*2500/1024). Я пока решил сделать при делителе 8, то есть значение теперь 20000, формула: 20000 - (ацп*20000/1024)/
domowoj
Т.е. 10000, записанные в регистр сравнения, соответствуют 90градусам.
domowoj
Цитата(demiurg1978 @ Jun 28 2016, 00:16) *
(0 - полная мощность, 2500 нулевая)
При таком раскладе одна дискрета мощности у вас 0,04%,
так что 0 или 1 записан в регистр сравнения, разницы ни какой.
Вы на детектировании нуля теряете больше (если AVR182 пользуетесь).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.