Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.71/14: Рейтинг темы: голосов - 14, средняя оценка - 4.71
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,044
1

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

26.06.2016, 21:09. Просмотров 2871. Ответов 7
Метки нет (Все метки)

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

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

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

Пока именно так и сделал, при нуле принудительно запускаю генератор пачек импульсов. Но мне хотелось бы понять, почему нет прерывания при нуле сразу после запуска 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_homdler (void)
{
set_timer1_off ();
Start_10_kGz ();
}
//========================================================================
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.06.2016, 21:09
Ответы с готовыми решениями:

Не могу разобраться со Звуком и OCR1A
Не могу разобраться со формированием звука, накатал код, а он работает не так как задумывалось)) ...

Старший байт в двухбайтовом регистре OCR1A
В одном единственном месте программы есть обращение к регистру OCR1A, младший байт присваивается...

режим Fast PWM, когда TOP задается регистром OCR1A
Добрый день, есть такой fast pwm режим для 16 битного таймера (например, в mega8), когда...

atmega32A Timer1
возможно ли получить две разных частоты (меиндр) на выводах OC1A и OC1B? чего-то туплю, как для...

timer1 - 16 bit
Здравствуйте! Тренируюсь в avr studyo 5 c симулятором на tiny2313 по М.С. Голубцову. Курс...

7
u37
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,113
26.06.2016, 22:43 2
Там что-то было, связанное с 0. Кажется, отлавливается не факт наличия равенства, а факт установления равенства (edge). Поэтому 0 и не срабатывает.
К слову, это и хорошо - открывать сразу по переходу через 0 вредно. Во-первых, тиристор не откроется при 0 напряжении. Во-вторых, ваш датчик 0 срабатывает раньше перехода через 0, а потому установка таймера "0" должна вызвать включение тиристора в самом конце предыдущего полупериода. Это не страшно, тиристор выключится при переходе через 0, но еслиб тиристоров было двое и работали по принципу "переключения", то это привело бы к "бум".
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
30.06.2016, 10:01 3
Вот-вот. Похоже, с моей музыкальной пищалкой тоже самое.
Таймер в режиме CTC проверяет не наличие равенства, а момент равенства. В некоторых ситуациях может перевалить, и поэтому приходилось писать подпорку, которая во время простоя основного цикла проверяет, не случилось ли у нас так, что таймер уже перевалил за значение OCR. Потому как перевалил - может уже и не определить.

Мне пока не удалось понять, как эту проблему решить. Похоже, это фича, и ничего с ней не сделать.
В моем случае я просто завел на TIMER0 постоянную частоту срабатывания, загрузив в начале инициализации в OCR0 нужное мне значение и забыв о нем, а все отсчеты веду массивом софтовых таймеров.
Не знаю, подойдет ли в данном случае такое решение.
0
yiv91
0 / 0 / 0
Регистрация: 31.01.2013
Сообщений: 1,625
30.06.2016, 20:26 4
Цитата Сообщение от sdv_cybork
Таймер в режиме CTC проверяет не наличие равенства, а момент равенства. В некоторых ситуациях может перевалить, и поэтому приходилось писать подпорку, которая во время простоя основного цикла проверяет, не случилось ли у нас так, что таймер уже перевалил за значение OCR. Потому как перевалил - может уже и не определить.
Я не понял, почему этот момент может быть упущен. СТС может работать либо на вывод ноги, либо генерить прерывание. В первом случае это аппаратное событие и происходит независимо от исполняемого кода. Во втором, если совпадение подымает запрос на прерывание, он так и остается поднятым, пока не будут разрешены прерывания, то есть, либо это команда SEI, либо возврат из прерывания по команде RETI, и после этого он сразу же ринется обрабатывать хандлер по OCR. Как оно может перевалить и не заметить?
0
30.06.2016, 20:26
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
30.06.2016, 21:37 5
Цитата Сообщение от yiv91
В первом случае это аппаратное событие и происходит независимо от исполняемого кода.
Вот как раз в этом случае и проблема, если слишком часто сменять значение регистра OCR.
Например, в случае музыкальной пищалки, когда можно ШИМом генерить синусоиду. Лучше завести константу в OCR и не трогать ее. Чтоб была фиксированная частота дискретизации.
0
yiv91
0 / 0 / 0
Регистрация: 31.01.2013
Сообщений: 1,625
01.07.2016, 10:51 6
Угу, кажется, понимаю. Если счетчик приближается к значению OCR, а мы в это время его уменьшаем на значение меньшее, чем насчитал таймер, то он считает дальше, и совпадения не происходит.

В нашем массовом изделии используется аппаратный ШИМ на максимальной частоте 31 кГц. Перезапись OCR происходит очень интенсивно. Выход ШИМа проходит через ФНЧ с частотой среза 50 Гц, и никаких артефактов не было замечено, тысячи изделий работают нормально. Как вы думаете - их нет, или они настолько мелкие, что не создают заметных ошибок? У нас эта тема никогда даже не упоминалась, тк. не было повода.
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
01.07.2016, 23:41 7
Не могу судить без представления задачи, т.к. еще не профессионал. Но полагаю, что скорее такие сбои довольно мелкие и не создают проблем.
0
Yurkom
0 / 0 / 0
Регистрация: 23.05.2007
Сообщений: 792
02.07.2016, 13:11 8
Цитата Сообщение от yiv91
...Если счетчик приближается к значению OCR, а мы в это время его уменьшаем на значение меньшее, чем насчитал таймер, то он считает дальше, и совпадения не происходит.
Если мне не изменяет память, OCRx имеет промежуточный регистр, и обновляется немедленно только в режимах CTC, во всех остальных режимах - ждет достижения счетчиком крайних значений (TOP или BOTTOM).
0
02.07.2016, 13:11
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.07.2016, 13:11

Настройка Timer1 на ATtiny2313
Стараюсь настроить Timer1 на время 0.01секунды при частоте 4Мгц , но при моделировании в Proteus...

Atmega8 не работает Timer1
Не могу понять в чем проблема, Timer0 запустил и работает, а первый вообще не работает. Не могу...

Timer1 считает до 32768, а не до 65536
Нужен больший диапазон, т.е. чтобы измерять можно было до 50 тысяч единиц, а на деле получается,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.