Перейти к содержанию
    

Timer1 Compare B

Здравствуйте! Хочу включить в свою программу прерывание по совпадению Б таймера 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?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то не видно установок для TCCR1A (WGM10, WGM11).

Я так понимаю, что сейчас установлен СТС режим и макс значение счета определяется регистром OCR1A. А значение OCR1B у Вас больше. Может, поэтому совпадение Б и не происходит.

Я бы выбрал один из режимов 5,6,7 из табл 15-4 из "ATmega48PA/88PA/168PA/328P"

Сам сталкивался с подобными ситуациями. Нужно внимательно почитать документацию. В данном случае, надо просмотреть все регистры таймера 1, где какие биты и для чего они. Так меньше вероятность того, что что-то выпадет из вида.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то не видно установок для 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"

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, в разделе "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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, в разделе "15.9.2 Clear Timer on Compare Match (CTC) Mode" речь идет только о OCR1A. Может быть и Б будет срабатывать, но у Вас значение OCR1B задано больше, чем OCR1A, поэтому событие Б должно произойти позже, а счетчик уже сбросится.

Дело в том что прерывания по совпадению А и Б разрешаются не одновременно, то есть если разрешено "совпадение Б", то "совпадение А" запрещается и наоборот.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Используйте режим 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 стоит как вкопаный. Как его сбросить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... флаг в регистре TIFR1 установлен. Логично в прерывании TIM1_COMPA сбросить этот флаг. Я пытался сделоть это так

clr temp

sts TIFR1, temp

и так

clr temp

out TIFR1, temp

но флаг OCF1B стоит как вкопаный. Как его сбросить?

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

Еще. Команда sts занимает в памяти программ больше места (в 2 раза) чем команда out. Поэтому, в данном случае я пользуюсь командой out, а команду sts использую при обращении к RAM, где храню данные, когда не хватает регистров общего назначения.

 

 

Но как только где-то дальше в программе я разрешу прерывание TIM1_COMPB, оно исполнится мгновенно - ведь его флаг в регистре TIFR1 установлен. Логично в прерывании TIM1_COMPA сбросить этот флаг.

Опять же, в описании некоторых модулей МК перед запуском модуля или перед разрешением прерывания рекомендуется проверить состояние этого модуля: произвести считывание какого-то регистра, сбросить флаги, что-то установить/обнулить и т.д. Поэтому в процессе работы МК, разрешая какое-то прерывание или запуская новый модуль, логично начать его работу "с чистого листа", т.е правильно произвести установки в управляющих регистрах: мало ли что там было.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При работе с этим же таймером столкнулся с такой особенностью, что при входе в прерывание по совпадению А, сбрасывается бит I в регистре SREG, с чем это связано?

Изменено пользователем avrx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сброс бита I - это запрещение всех прерываний внутри обработчика прерывания. Если необходимы вложенные прерывания то необходимо целенаправленно разрешить. После выхода из прерывания состояние бита восстанавливается. Так то это одно из начальных знаний о МК.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Флаг I в регистре SREG сбрасывается аппаратно при входе в прерывание. Его можно включить в самом прерывании, если это требуется. Заново флаг I устанавливается аппаратно командой RETI. Если прерывание не требуется, выход по команде RET.

 

gaw.ru - Там описана архитектура МК AVR

Вольфганг Трамперт - AVR-RISC микроконтроллеры фирмы ATMEL. Очень хорошая книга. Написана несколько лет назад. Многие МК уже устаревшие. Но основное актуально.

Изменено пользователем demiurg1978

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо большое за информацию :)

Изменено пользователем avrx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...