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