|
|
  |
Timer1 Compare B |
|
|
|
Jul 2 2015, 07:34
|
Участник

Группа: Участник
Сообщений: 66
Регистрация: 23-05-12
Пользователь №: 71 976

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

Группа: Участник
Сообщений: 66
Регистрация: 23-05-12
Пользователь №: 71 976

|
Цитата(Александр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"
|
|
|
|
|
Jul 3 2015, 03:56
|
Местный
  
Группа: Участник
Сообщений: 465
Регистрация: 13-05-15
Из: Запорожье
Пользователь №: 86 663

|
Да, в разделе "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.
|
|
|
|
|
Jul 5 2015, 02:57
|
Участник

Группа: Участник
Сообщений: 66
Регистрация: 23-05-12
Пользователь №: 71 976

|
Цитата(Александр1 @ Jul 3 2015, 06:56)  Да, в разделе "15.9.2 Clear Timer on Compare Match (CTC) Mode" речь идет только о OCR1A. Может быть и Б будет срабатывать, но у Вас значение OCR1B задано больше, чем OCR1A, поэтому событие Б должно произойти позже, а счетчик уже сбросится. Дело в том что прерывания по совпадению А и Б разрешаются не одновременно, то есть если разрешено "совпадение Б", то "совпадение А" запрещается и наоборот.
|
|
|
|
|
Jul 8 2015, 07:53
|
Участник

Группа: Участник
Сообщений: 66
Регистрация: 23-05-12
Пользователь №: 71 976

|
Провеля тут лабораторную работу. В режиме СТС оба прерывания работают, но есть нюансы. Значение 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 стоит как вкопаный. Как его сбросить?
|
|
|
|
|
Jul 8 2015, 08:52
|
Местный
  
Группа: Участник
Сообщений: 465
Регистрация: 13-05-15
Из: Запорожье
Пользователь №: 86 663

|
Цитата(Рэльс @ Jul 8 2015, 10:53)  ... флаг в регистре TIFR1 установлен. Логично в прерывании TIM1_COMPA сбросить этот флаг. Я пытался сделоть это так clr temp sts TIFR1, temp и так clr temp out TIFR1, temp но флаг OCF1B стоит как вкопаный. Как его сбросить? Внимательно читайте datasheet! Там, как говорил нам преподаватель литературы, красной нитью через все произведение  (т.е. неоднократно во всех перефирийных модулях и не только) написано: сброс флага производится ЗАПИСЬЮ ЕДИНИЦЫ в этот разряд. Мне тоже не совсем понятно зачем так. Возможно, специфика работы МК такова. Но коль уж так есть, то и выполнять следует так как написано, тогда все будет работать сразу и быстро. Еще. Команда sts занимает в памяти программ больше места (в 2 раза) чем команда out. Поэтому, в данном случае я пользуюсь командой out, а команду sts использую при обращении к RAM, где храню данные, когда не хватает регистров общего назначения. Цитата(Рэльс @ Jul 8 2015, 10:53)  Но как только где-то дальше в программе я разрешу прерывание TIM1_COMPB, оно исполнится мгновенно - ведь его флаг в регистре TIFR1 установлен. Логично в прерывании TIM1_COMPA сбросить этот флаг. Опять же, в описании некоторых модулей МК перед запуском модуля или перед разрешением прерывания рекомендуется проверить состояние этого модуля: произвести считывание какого-то регистра, сбросить флаги, что-то установить/обнулить и т.д. Поэтому в процессе работы МК, разрешая какое-то прерывание или запуская новый модуль, логично начать его работу "с чистого листа", т.е правильно произвести установки в управляющих регистрах: мало ли что там было.
|
|
|
|
|
Jul 8 2015, 13:43
|
Участник

Группа: Участник
Сообщений: 66
Регистрация: 23-05-12
Пользователь №: 71 976

|
Спасибо Вам и вашему преподавателю! Все теперь работает!
|
|
|
|
|
Sep 8 2015, 16:29
|

Группа: Участник
Сообщений: 7
Регистрация: 26-05-10
Пользователь №: 57 552

|
При работе с этим же таймером столкнулся с такой особенностью, что при входе в прерывание по совпадению А, сбрасывается бит I в регистре SREG, с чем это связано?
Сообщение отредактировал avrx - Sep 8 2015, 16:29
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|