Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Timer1 Compare B
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Рэльс
Здравствуйте! Хочу включить в свою программу прерывание по совпадению Б таймера 1

.include "m168def.inc"
................................

RESET:
........................................

;===========старт таймера 1=============
;
;=======================================
ldi temp, 9
sts OCR1AH, temp
ldi temp, 169
sts OCR1AL, temp ; загрузили регистры сравнения A
ldi temp, 0x1A
sts OCR1BH, temp
ldi temp, 0xDB
sts OCR1BL, temp ; загрузили регистры сравнения B
ldi temp, (1<<WGM12) ; сброс при совпадении, таймер остановлен
sts TCCR1B, temp
................................
lds temp, TIMSK1
cbr temp, 0b00000010 ; запрещаем прерывание "совпадение А"
sbr temp, 0b00000100 ; разрешаем прерывание "совпадение B"
sts TIMSK1, temp
...............................
; ===запускаем таймер===
clr temp ; = =
sts TCNT1H, temp ; =очищаем счетные регистры
sts TCNT1L, temp ; =очищаем счетные регистры
lds temp, TCCR1B ; = =
cbr temp, 0b00000101
sbr temp, 0b00000010 ;запуск таймера 1 16 МГц / 8 = 2 МГц =
sts TCCR1B, temp ; ======================

В программе время от времени разрешаются прерывания по таймеру 1 "совпадение А" и "совпадение Б". Если я правильно понимаю, в зависимости от того, какое прерывание разрешено, счетные регистры TCNT1 сравниваются с регистрами сравнения OCR1A или OCR1B. В симуляторе AVR студии все прекрасно работает, а в железе срабатывает только прерывание "сравнение с А". "Сравнение с Б" не работает вообще, почему?
PS в книге Евстегнеева сказано
"Режим СТС (сброс при совпадении)
В этом режиме счетный регистр тоже функционирует как обычный суммирующий счетчик,...Однако максимально возможное значение счетного регистра и, следовательно, разрешающая способность счетчика определяются либо регистром сравнения блока A OCR1A, либо регистром захвата ICR1..."
тогда зачам вообще нужно прерывание Timer1 Compare B?
Александр1
Что-то не видно установок для TCCR1A (WGM10, WGM11).
Я так понимаю, что сейчас установлен СТС режим и макс значение счета определяется регистром OCR1A. А значение OCR1B у Вас больше. Может, поэтому совпадение Б и не происходит.
Я бы выбрал один из режимов 5,6,7 из табл 15-4 из "ATmega48PA/88PA/168PA/328P"
Сам сталкивался с подобными ситуациями. Нужно внимательно почитать документацию. В данном случае, надо просмотреть все регистры таймера 1, где какие биты и для чего они. Так меньше вероятность того, что что-то выпадет из вида.

А прерывание по совпадению Б установлено? И правильно ли установлен вектор прерывания? А то может там стоит команда NOP?
Рэльс
Цитата(Александр1 @ Jul 2 2015, 12:42) *
Что-то не видно установок для TCCR1A (WGM10, WGM11).
Я так понимаю, что сейчас установлен СТС режим и макс значение счета определяется регистром OCR1A. А значение OCR1B у Вас больше. Может, поэтому совпадение Б и не происходит.
Я бы выбрал один из режимов 5,6,7 из табл 15-4 из "ATmega48PA/88PA/168PA/328P"
Сам сталкивался с подобными ситуациями. Нужно внимательно почитать документацию. В данном случае, надо просмотреть все регистры таймера 1, где какие биты и для чего они. Так меньше вероятность того, что что-то выпадет из вида.

А прерывание по совпадению Б установлено? И правильно ли установлен вектор прерывания? А то может там стоит команда NOP?

Вы правы, установлен режим СТС
ldi temp, (1<<WGM12) ; сброс при совпадении, таймер остановлен
sts TCCR1B, temp

прерывание тоже установлено
.org 0x0016
jmp TIM1_COMPA ; Timer1 Compare A Handler
.org 0x0018
jmp TIM1_COMPB ; Timer1 Compare B Handler

Из даташита ясно, что в режиме СТС счетный регистр сравнивается с OCR1A. Про OCR1B ни слова, только на с 134 про него сказано "A match can be used to generate an Output Compare interrupt, or to generate a waveform output on the OC1x pin"
Александр1
Да, в разделе "15.9.2 Clear Timer on Compare Match (CTC) Mode" речь идет только о OCR1A. Может быть и Б будет срабатывать, но у Вас значение OCR1B задано больше, чем OCR1A, поэтому событие Б должно произойти позже, а счетчик уже сбросится.
Если все равно не получается, то надо пробовать использовать PWM: режимы 5,6,7 из табл 15-4, или 8,9 и 14,15, если требуется изменение частоты. Там максимальное счетное значение определяется OCR1A или ICR1.
ILYAUL
Есть такое понятие - Free timer. Вот его и используйте
Рэльс
Цитата(Александр1 @ Jul 3 2015, 06:56) *
Да, в разделе "15.9.2 Clear Timer on Compare Match (CTC) Mode" речь идет только о OCR1A. Может быть и Б будет срабатывать, но у Вас значение OCR1B задано больше, чем OCR1A, поэтому событие Б должно произойти позже, а счетчик уже сбросится.

Дело в том что прерывания по совпадению А и Б разрешаются не одновременно, то есть если разрешено "совпадение Б", то "совпадение А" запрещается и наоборот.
RabidRabbit
Используйте режим WGM1 = 1100 (WGM13 = 1, WGM12 = 1, WGM11 = 0, WGM10 = 0) и задайте в ICR1 значение 65535, тогда у Вас будет работать и то и другое прерывание, в которых Вы будете сбрасывать TCNT1 в 0. А в режиме WGM1 = 0100 (который Вы используете) счётчик будет считать только да OCR1A, так что Александр1 Вам всё правильно объяснил, до OCR1B значение TCNT1 просто не доберётся.
Рэльс
Провеля тут лабораторную работу.
В режиме СТС оба прерывания работают, но есть нюансы.
Значение OCR1A должно бать больше OCR1B, поскольку, как и сказано в даташите, таймер в этом режиме считает до OCR1A. Поэтому либо до запуска прерывания TIM1_COMPB, либо в обработчике необходимо очистить счетные регистры TCNT1. Иначе после завершения этого прерывания счет начнется не с нуля, а с OCR1B.
Ныанс второй. Разрешено прерывание TIM1_COMPA.
ldi temp, (1<<OCIE1A)
sts TIMSK1, temp
TIM1_COMPB как видно, запрещено. Но в регистрах OCR1B у нас какая-то цифра, и она менньше цифры в OCR1A. Как только таймер досчитает до OCR1B, в регистре TIFR1 установится бит OCF1B (флаг прерывания TIM1_COMPB). Само прерывание не сработает - оно ведь запрещено, и таймер благополучно досчитает до OCR1A и выполнится прерывание TIM1_COMPA. Но как только где-то дальше в программе я разрешу прерывание TIM1_COMPB, оно исполнится мгновенно - ведь его флаг в регистре TIFR1 установлен. Логично в прерывании TIM1_COMPA сбросить этот флаг. Я пытался сделоть это так
clr temp
sts TIFR1, temp
и так
clr temp
out TIFR1, temp
но флаг OCF1B стоит как вкопаный. Как его сбросить?
Александр1
Цитата(Рэльс @ Jul 8 2015, 10:53) *
... флаг в регистре TIFR1 установлен. Логично в прерывании TIM1_COMPA сбросить этот флаг. Я пытался сделоть это так
clr temp
sts TIFR1, temp
и так
clr temp
out TIFR1, temp
но флаг OCF1B стоит как вкопаный. Как его сбросить?

Внимательно читайте datasheet! Там, как говорил нам преподаватель литературы, красной нитью через все произведение biggrin.gif (т.е. неоднократно во всех перефирийных модулях и не только) написано: сброс флага производится ЗАПИСЬЮ ЕДИНИЦЫ в этот разряд. Мне тоже не совсем понятно зачем так. Возможно, специфика работы МК такова. Но коль уж так есть, то и выполнять следует так как написано, тогда все будет работать сразу и быстро.
Еще. Команда sts занимает в памяти программ больше места (в 2 раза) чем команда out. Поэтому, в данном случае я пользуюсь командой out, а команду sts использую при обращении к RAM, где храню данные, когда не хватает регистров общего назначения.


Цитата(Рэльс @ Jul 8 2015, 10:53) *
Но как только где-то дальше в программе я разрешу прерывание TIM1_COMPB, оно исполнится мгновенно - ведь его флаг в регистре TIFR1 установлен. Логично в прерывании TIM1_COMPA сбросить этот флаг.

Опять же, в описании некоторых модулей МК перед запуском модуля или перед разрешением прерывания рекомендуется проверить состояние этого модуля: произвести считывание какого-то регистра, сбросить флаги, что-то установить/обнулить и т.д. Поэтому в процессе работы МК, разрешая какое-то прерывание или запуская новый модуль, логично начать его работу "с чистого листа", т.е правильно произвести установки в управляющих регистрах: мало ли что там было.
Рэльс
Спасибо Вам и вашему преподавателю! Все теперь работает!
avrx
При работе с этим же таймером столкнулся с такой особенностью, что при входе в прерывание по совпадению А, сбрасывается бит I в регистре SREG, с чем это связано?
alexeyv
Сброс бита I - это запрещение всех прерываний внутри обработчика прерывания. Если необходимы вложенные прерывания то необходимо целенаправленно разрешить. После выхода из прерывания состояние бита восстанавливается. Так то это одно из начальных знаний о МК.
demiurg1978
Флаг I в регистре SREG сбрасывается аппаратно при входе в прерывание. Его можно включить в самом прерывании, если это требуется. Заново флаг I устанавливается аппаратно командой RETI. Если прерывание не требуется, выход по команде RET.

gaw.ru - Там описана архитектура МК AVR
Вольфганг Трамперт - AVR-RISC микроконтроллеры фирмы ATMEL. Очень хорошая книга. Написана несколько лет назад. Многие МК уже устаревшие. Но основное актуально.
avrx
Спасибо большое за информацию sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.