Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с таймером на Atmega168
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
CatMurr
Итак, есть девайс, Atmega168. Задачу можно свести к следующему минимуму:

Необходимо установить режим FastPWM и дрыгать ножкой - устанавливать низкий уровень по совпадению с регистром сравнения, высокий по переполнению счетного регистра таймера. Используется Timer1 16bit.

Проблема заключается в том, что по идее в режиме FastPWM таймер должен дотикать до FF, сбросить счетчик в 0, выдать прерывание по переполнению, и продолжить по кругу. При отладке программы в симуляторе avrstudio, таймер тикает до FF, затем тикает обратно до 0, и только тогда выдает прерывание, как в режиме PWM Phase Correct.

Инициализация следующая:

COM1A1..0 = 00
COM1B1..0 = 00
WGM13..0 = 0101 ; FastPWM 8bit
CS12..0 = 001 ; без предделителя
OCIE1A = 1 ; прерывание по совпадению
TOIE1 = 1 ; прерывание по переполнению

В OCR1A пришу, например, 0x003F.

Притом флаги OCF1A и TOV1 вообще не выставляются по соответствующим событиям, но прерывания исправно отрабатываются. Итого имеем PWM Phase Correct при настройках для FastPWM.

Где собака зарыта? Глюк в симуляторе, или (скорее всего), я что-то делаю неправильно?

Проект на всякий случай прилагаю.
Diusha
Попробуйте WGM=1110, а 0х00FF загоните в ICR1. У меня нормально работает.

Цитата(CatMurr @ Dec 26 2010, 18:16) *
COM1A1..0 = 00
COM1B1..0 = 00

При этом ножка дрыгаться не будет

Цитата(CatMurr @ Dec 26 2010, 18:16) *
Притом флаги OCF1A и TOV1 вообще не выставляются по соответствующим событиям, но прерывания исправно отрабатываются.

Раз прерывания обрабатываются, значит флаги выставляются, с чего Вы взяли, что нет?

Цитата(CatMurr @ Dec 26 2010, 18:16) *
Итого имеем PWM Phase Correct при настройках для FastPWM.

А это откуда следует?
CatMurr
Цитата(Diusha @ Dec 26 2010, 19:20) *
При этом ножка дрыгаться не будет

Не будет дрыгаться ножка OC1A/OC1B, я дергаю другой ногой по прерываниям.

Цитата(Diusha @ Dec 26 2010, 19:20) *
Раз прерывания обрабатываются, значит флаги выставляются, с чего Вы взяли, что нет?

При симуляции программа уходит на вектор прерывания, но флаги в регистрах не выставляются. Глюк симулятора?

Цитата(Diusha @ Dec 26 2010, 19:20) *
А это откуда следует?

Получаем не "single-slope operation", как в FastPWM, а "double-slope", с частотой в два раза меньше, чем при FastPWM => PWM Phase Correct.
Diusha
Цитата(CatMurr @ Dec 26 2010, 19:42) *
При симуляции программа уходит на вектор прерывания, но флаги в регистрах не выставляются. Глюк симулятора?

Глюк симулятора. А может фича. Может он просто не отображает, что они устанавливаются. Флаги установлены очень короткое время: с момента события до перехода по вектору, сбрасываются автоматически.

Цитата(CatMurr @ Dec 26 2010, 19:42) *
Получаем не "single-slope operation", как в FastPWM, а "double-slope", с частотой в два раза меньше, чем при FastPWM => PWM Phase Correct.

Думаю, тоже глюк симулятора
Попробуйте живьем
777777
Какой компилятор? В AVR Studio все исправно работает в режиме FastPWM. Флаги OCF1A и TOV1 ты не увидишь потому что они очищаются при входе в прерывание.

ЗЫ. А зачем SEI перед выходом из прерывания?
CatMurr
Цитата(777777 @ Dec 26 2010, 20:57) *
Какой компилятор? В AVR Studio все исправно работает в режиме FastPWM. Флаги OCF1A и TOV1 ты не увидишь потому что они очищаются при входе в прерывание.

Не осознал вопроса. Что значит "какой компилятор?". В avrstudio есть несколько компиляторов под ассемблер?

Цитата(777777 @ Dec 26 2010, 20:57) *
А зачем SEI перед выходом из прерывания?

Почему то сбрасывается флаг I в регистре SREG при входе по вектору прерывания. По идее не должен.

Вообще надо попробовать на железе без SEI перед выходом.

Завтра доберусь до осциллографа, выясню точно, получается ли FastPWM или PhaseCorrect.
ae_
Цитата(CatMurr @ Dec 27 2010, 02:24) *
...
Почему то сбрасывается флаг I в регистре SREG при входе по вектору прерывания. По идее не должен.
...
Вообще надо попробовать на железе без SEI перед выходом.

1) по идее - как раз должен. при переходе на любой вектор прерывания флаг I сбрасывается автоматически.
2)
>> SEI ; разрешили прерывания
>> RETI ; выход из прерывания
посмотрите в хелпе, чем различаются инструкции RET и RETI.
777777
Цитата(CatMurr @ Dec 26 2010, 21:24) *
Не осознал вопроса. Что значит "какой компилятор?". В avrstudio есть несколько компиляторов под ассемблер?

Не заметил сразу что ты написал про студию. Наверное версия старая, у них часто бывают глюки в симулятрое, у меня 4.18 b716.
Цитата(CatMurr @ Dec 26 2010, 21:24) *
Почему то сбрасывается флаг I в регистре SREG при входе по вектору прерывания. По идее не должен.

По идее как раз должен, при входе в прерывание он всегда сбрасывается. А при выходе восстанавливается слово состояния в котором он был установлен.
Diusha
Цитата(777777 @ Dec 27 2010, 08:21) *
А при выходе восстанавливается слово состояния в котором он был установлен.

Какое слово состояния? Просто при выполнении RETI устанавливается I (эквивалентно SEI + RET в одном флаконе)
CatMurr
Цитата(777777 @ Dec 27 2010, 08:21) *
Не заметил сразу что ты написал про студию. Наверное версия старая, у них часто бывают глюки в симулятрое, у меня 4.18 b716.

Студия 4.18 b716. За обновлениями слежу.

Цитата(777777 @ Dec 27 2010, 08:21) *
По идее как раз должен, при входе в прерывание он всегда сбрасывается. А при выходе восстанавливается слово состояния в котором он был установлен.

Да, Вы правы, при использовании RETI флаг I выставляется заново при выходе из прерывания. Наверное, ранее я использовал RET.

Сегодня утром погонял еще раз программку на симуляторе, затем посмотрел осциллографом. Выставил в регистре сравнения значение 0x3F, т.е. четверть периода (для наглядности).
Симулятор: таймер упорно считает до FF, затем вниз до 0. Частота на 8 мегагерцовом кварце (без использования предделителя) получается порядка 15 кГц, т.е. 8000000/(255*2)=15686 Гц.
Железо: частота 31,25 кГц (8000000/255), то есть настоящий FastPWM. Очевидно, что таймер по достижению FF сбрасывается в 0, иначе бы получили частоту в два раза меньше.
Налицо глюк симулятора?

777777
Цитата(CatMurr @ Dec 27 2010, 09:08) *
Студия 4.18 b716. За обновлениями слежу.

Железо: частота 31,25 кГц (8000000/255), то есть настоящий FastPWM. Очевидно, что таймер по достижению FF сбрасывается в 0, иначе бы получили частоту в два раза меньше.
Налицо глюк симулятора?

Я прогонял в симуляторе непосредственно вашу программу из первого поста и всё работало нормально, т.е. таймер по достижению FF сбрасывался в 0. Я даже не знаю, может кроме версии студии нужны еще версии файлов, которые использует симулятор с описанием процессора?

А вообще от симуляторов толку мало, например, если PWM вывести наружу (т.е. COM1A1..0 поставить не ноль) то симулятор все равно не показывает изменения выводов. Поэтому я обычно им не пользуюсь и сразу все делаю в железе.

Цитата(Diusha @ Dec 27 2010, 08:57) *
Какое слово состояния? Просто при выполнении RETI устанавливается I (эквивалентно SEI + RET в одном флаконе)

RETI не эквивалентен SEI + RET
При прерывании в стеке сохраняется не только адрес возврата, но и слово состояния. По команде RETI они извлекаются из стека и продолжается выполнение программы с прерванного места. Поскольку в слове состояния бит I был установлен (если бы не был установлен, то и прерывание бы не произошло), то он восстанавливается наравне со всеми остальными битами слова состояния.
Сергей Борщ
QUOTE (CatMurr @ Dec 26 2010, 18:42) *
При симуляции программа уходит на вектор прерывания, но флаги в регистрах не выставляются. Глюк симулятора?
Невнимательное чтение документации. Описания флага и методов его сброса. При переходе по вектору большинство флагов сбрасываются автоматически.
CatMurr
Выбрал другую отладочную платформу: AVR Simulator2, после чего таймер заработал как надо!
Ради интереса сравнил m168def.inc для Simulator и Simulator2 - разницы в описании конфигурационных регистров для таймера не нашел.

А вообще всем спасибо за помощь и советы!
Diusha
Цитата(777777 @ Dec 27 2010, 10:10) *
RETI не эквивалентен SEI + RET
При прерывании в стеке сохраняется не только адрес возврата, но и слово состояния. По команде RETI они извлекаются из стека и продолжается выполнение программы с прерванного места. Поскольку в слове состояния бит I был установлен (если бы не был установлен, то и прерывание бы не произошло), то он восстанавливается наравне со всеми остальными битами слова состояния.

Это где же Вы такое нашли? Во-первых, что Вы называете "словом состояния" применительно к меге168? wink.gif Может регистр SREG? Так сохранить его в целости во время обработки прерывания - полностью на совести программера. B стеке сохраняется только адрес возврата
А вся неэквивалентность RETI и SEI + RET только в количестве тактов.
RETI я использую и когда надо из обычной п/п выйти с одновременной установкой I
777777
Цитата(Diusha @ Dec 27 2010, 17:10) *
Это где же Вы такое нашли? Во-первых, что Вы называете "словом состояния" применительно к меге168? wink.gif Может регистр SREG?
Так сохранить его в целости во время обработки прерывания - полностью на совести программера. B стеке сохраняется только адрес возврата

Да, я все время забываю об этой экзотической особенности AVR. Собсно, если писать на С, то с этими вопросами можно не заморачиваться.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.