AVR Mega8 Timer2 в режиме генератора частоты

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
dandan
Нашел транзистор. Понюхал.
Сообщения: 180
Зарегистрирован: Ср дек 22, 2010 12:40:17

AVR Mega8 Timer2 в режиме генератора частоты

Сообщение dandan »

Уже неделю бьюсь, не могу найти ошибку.
Таймер 2 включен в режиме СТС (СОМ2=01, WGM21=1, делитель=256)
На ноге PB3 генерируется сигнал с частотой в зависимости от значения в регистре OCR2.
Беда в том, что при изменении этого регистра, для изменения частоты, первый период после изменения регистра OCR2 с сигналом происходят какие-то глюки - импульс на ноге PB3 может иметь какой-то произвольный интервал, то очень короткий, то длинный, как результат плавное изменение частоты не получается.

Помогите в чем может быть проблема. Спасибо.
Реклама
dandan
Нашел транзистор. Понюхал.
Сообщения: 180
Зарегистрирован: Ср дек 22, 2010 12:40:17

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение dandan »

Получается, хрень какая-то: когда я в процессе работы таймера меняю значение в регистре сравнения OCR2 (устанавливаю новую частоту) таймер досчитывает до старого значения регистра OCR2, инвертирует выход, не сбрасывает счетчик и продолжает считать до нового значения OCR2, дойдя до него уже сбрасывает счетчик и потом уже работает нормально.

Это глюки или настройка таймера не правильная?
Реклама
Аватара пользователя
Roman Venom
Сверлит текстолит когтями
Сообщения: 1135
Зарегистрирован: Сб июл 11, 2009 18:42:21
Откуда: Украина, г.Николаев

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение Roman Venom »

код выложи.
Успех - императив!
dandan
Нашел транзистор. Понюхал.
Сообщения: 180
Зарегистрирован: Ср дек 22, 2010 12:40:17

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение dandan »

Так это 8 битный таймер.

Сигнал получается такой:
Изображение
Здесь видно два места где уменьшалась частота (изменялся регистр OCR2).

Код:
Инициализация таймера:
LDI R16,0b00011110
OUT TCCR2,R16

Этот кусок берет из таблицы значения частоты по индексу в R4 и записывает в OCR2
LDI R30,Low(Tab4*2)
LDI R31,High(Tab4*2)
CLR R16
ADD R30,R4
ADC R31,R16
LPM
OUT OCR2,R0

Короче прошел пошагово - так и есть при изменении OCR2 он помнит предыдущее его значении и при совпадении с ним инвертирует выход но не сбрасывает счетчик.
Что делать?
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение vitalik_1984 »

это может объясняться двумя причинами:
1 ошибка в коде
2 все в порядке просто архитектура таймера такая: если пытаешься рядом со значением совпадения таймера присвоить новое значение или если присваиваешь значение на один больше(в случае уменьшения значений счетчика) или меньше на один,то может не произойти события СОВПАДЕНИЯ таймера.
Хотя можно и такое упущение расценивать как недостаток в коде:)
В поисках истины человек развивается.
Реклама
Аватара пользователя
aleksey_gregul
Встал на лапы
Сообщения: 130
Зарегистрирован: Ср дек 29, 2010 17:30:34

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение aleksey_gregul »

dandan писал(а):но не сбрасывает счетчик. Что делать?
Разрешите прерывание TIMER2 COMP и сбросьте его в прерывании.
Я бы перегружал OCR2 тоже именно в прерывании, до сброса таймера.
Реклама
dandan
Нашел транзистор. Понюхал.
Сообщения: 180
Зарегистрирован: Ср дек 22, 2010 12:40:17

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение dandan »

aleksey_gregul писал(а):
dandan писал(а):но не сбрасывает счетчик. Что делать?
Разрешите прерывание TIMER2 COMP и сбросьте его в прерывании.
Я бы перегружал OCR2 тоже именно в прерывании, до сброса таймера.
Думал так попробовать, а потом подумал, разницы же нет когда менять OCR2 в прерывании или другом месте.
Странно, что в даташите об этом ничего не сказано.

И если так делать, то тогда теряется весь смысл режима СТС. Можно просто по переполнению устанавливать счетчик таймера в нужное значение (чем и задавать частоту) и инвертировать выход. Что я в результате и сделал.
Но в этом случае портится точность сигнала, ведь в момент прерывания по переполнению может работать другое прерывание и тогда изменение фронта сигнала немного сместиться.
dandan
Нашел транзистор. Понюхал.
Сообщения: 180
Зарегистрирован: Ср дек 22, 2010 12:40:17

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение dandan »

aleksey_gregul писал(а):
dandan писал(а):но не сбрасывает счетчик. Что делать?
Разрешите прерывание TIMER2 COMP и сбросьте его в прерывании.
Я бы перегружал OCR2 тоже именно в прерывании, до сброса таймера.
Попробовал менять OCR2 в прерывании по совпадению. Результат тот-же. Не работает оно нормально.


И еще. Если порт настроен на выход то установка 1 в PIN инвертирует его. В Протеусе это работает, а в железе нет. В чем подвох?
Аватара пользователя
aleksey_gregul
Встал на лапы
Сообщения: 130
Зарегистрирован: Ср дек 29, 2010 17:30:34

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение aleksey_gregul »

dandan писал(а):Думал так попробовать, а потом подумал, разницы же нет когда менять OCR2 в прерывании или другом месте.
Есть небольшая разница. Вы попробуйте вместе со сбросом таймера.
dandan писал(а):И если так делать, то тогда теряется весь смысл режима СТС.
Но в этом случае портится точность сигнала ... фронта сигнала немного сместиться.
А в режиме СТС этого не будет. Пин будет меняться аппаратно, что у Вас и происходит.
Сброс таймера в прерывании (при Вашем прескалере) не изменит момента смены пина.
Чтобы понять, почему нужно перегружать OCR2 и попутно сбрасывать таймер, прочтите выдержку из даташита.

If the interrupt is enabled, the interrupt handler routine can be
used for updating the TOP value. However, changing the TOP to a value close to BOTTOM
when the counter is running with none or a low prescaler value must be done with
care since the CTC mode does not have the double buffering feature. If the new value
written to OCR2 is lower than the current value of TCNT2, the counter will miss the
Compare Match. The counter will then have to count to its maximum value (0xFF) and
wrap around starting at 0x00 before the Compare Match can occur.

Попробуйте и расскажите результат. Самому интересно стало.
dandan
Нашел транзистор. Понюхал.
Сообщения: 180
Зарегистрирован: Ср дек 22, 2010 12:40:17

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение dandan »

aleksey_gregul, спасибо за ответ.
То, что счетчик может проскочить новое устанавливаемое значение OCR и будет считать до 255 это понятно и это можно предвидеть и корректировать TCNT. Я пробовал это делать.

Тут дело в другом. При изменении OCR счетчик помнит старое значение OCR и при достижении его инвертирует выход. Затем считает дальше и при достижении нового (уже записанного если оно больше старого) значения OCR снова инвертирует выход и сбрасывает TCNT на 0. Счетчик действительно так работает, я проходил пошагово.
Получается, что новое, записанное в OCR значение, вступает в силу при совпадении TCNT со старым значением OCR, но зачем при этом инвертируется выход?

Вы предлагаете в прерывании по совпадению устанавливать новое значение OCR. Это не помогает и счетчик все равно досчитав до старого значения инвертирует выход и продолжает считать дальше.
В этом же прерывании еще сбросить счетчик? Так он же уже сброшен? TCNT=0 Или как его еще сбросить.
Аватара пользователя
aleksey_gregul
Встал на лапы
Сообщения: 130
Зарегистрирован: Ср дек 29, 2010 17:30:34

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение aleksey_gregul »

dandan писал(а):Короче прошел пошагово - так и есть при изменении OCR2 он помнит предыдущее его значении и при совпадении с ним инвертирует выход но не сбрасывает счетчик.
Что делать?
Значит я Вас неправильно понял?
Сброс сброшенного счетчика никому (при Вашем прескаллере) не помешает.
Он сможет помочь в цитируемой ситуации.

Есть такое понятие double buffering. Просто прожужжите 1 такт(с учетом прескаллера). Но не получите корявого импульса.
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение ploop »

И еще. Если порт настроен на выход то установка 1 в PIN инвертирует его. В Протеусе это работает, а в железе нет. В чем подвох?
Вчера проверил это в железе на Mega48 - работает.
Аватара пользователя
aleksey_gregul
Встал на лапы
Сообщения: 130
Зарегистрирован: Ср дек 29, 2010 17:30:34

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение aleksey_gregul »

И еще.
Неправильно подсовывать таймеру новое значение когда попало и ожидать от него мгновенной реакции. Дайте ему отработать свой цикл. Чтобы форма сигнала не портилась.
И именно в конце цикла подсуньте новое значение. Но напомните ему при этом вручную, что считать уже пора по-новой.
Надеюсь поняли?
dandan
Нашел транзистор. Понюхал.
Сообщения: 180
Зарегистрирован: Ср дек 22, 2010 12:40:17

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение dandan »

aleksey_gregul писал(а):И еще.
Неправильно подсовывать таймеру новое значение когда попало и ожидать от него мгновенной реакции. Дайте ему отработать свой цикл. Чтобы форма сигнала не портилась.
И именно в конце цикла подсуньте новое значение. Но напомните ему при этом вручную, что считать уже пора по-новой.
Надеюсь поняли?
Понял но не совсем.
Подсовывать новое значение пробовал в прерывании на совпадении. Это не повлияло ни на что.
А что значит вручную сбросить таймер? Как это реализовать? Выключить-включить делитель?
Попробовал установкой бита PRS2 (сброс прескаллера), тоже самое досчитывает до прошлого значения OСR и инвертирует выход.
Аватара пользователя
aleksey_gregul
Встал на лапы
Сообщения: 130
Зарегистрирован: Ср дек 29, 2010 17:30:34

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение aleksey_gregul »

dandan писал(а): А что значит вручную сбросить таймер? Как это реализовать?
В прерывании в TCNT2 записать ноль;
dandan писал(а):Выключить-включить делитель?
Этого делать нельзя! поплывет сам делитель. Это применимо только при измерениях сигналов.
dandan писал(а):тоже самое досчитывает до прошлого значения OСR и инвертирует выход.
И это правильно. Иначе - в выходном сигнале появится период сигнала с непредсказуемо завышенной частотой. И только после этого пойдет сигнал с правильной частотой. Если Вам это не мешает, ради Бога!
А так, как я предложил- получите просто запаздывние в реакции Вашего генератора на 1 такт выходного сигнала. Зато гарантировано частота до изменения стабильна и равна заданной. И после изменения тоже стабильна и равна заданной. (без попадания в спектр ни единого такта с непредсказуемой частотой)
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение vitalik_1984 »

aleksey_gregul писал(а):
dandan писал(а):Думал так попробовать, а потом подумал, разницы же нет когда менять OCR2 в прерывании или другом месте.
Есть небольшая разница. Вы попробуйте вместе со сбросом таймера.
dandan писал(а):И если так делать, то тогда теряется весь смысл режима СТС.
Но в этом случае портится точность сигнала ... фронта сигнала немного сместиться.
А в режиме СТС этого не будет. Пин будет меняться аппаратно, что у Вас и происходит.
Сброс таймера в прерывании (при Вашем прескалере) не изменит момента смены пина.
Чтобы понять, почему нужно перегружать OCR2 и попутно сбрасывать таймер, прочтите выдержку из даташита.

If the interrupt is enabled, the interrupt handler routine can be
used for updating the TOP value. However, changing the TOP to a value close to BOTTOM
when the counter is running with none or a low prescaler value must be done with
care since the CTC mode does not have the double buffering feature. If the new value
written to OCR2 is lower than the current value of TCNT2, the counter will miss the
Compare Match. The counter will then have to count to its maximum value (0xFF) and
wrap around starting at 0x00 before the Compare Match can occur.

Попробуйте и расскажите результат. Самому интересно стало.
Во во именно это я и хотел сказать:) может немного корявый перевод на память.
В поисках истины человек развивается.
dandan
Нашел транзистор. Понюхал.
Сообщения: 180
Зарегистрирован: Ср дек 22, 2010 12:40:17

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение dandan »

aleksey_gregul писал(а):
dandan писал(а): А что значит вручную сбросить таймер? Как это реализовать?
В прерывании в TCNT2 записать ноль;
В прерывании там уже "0", какой смысл его писать снова? (у меня делитель 256)
aleksey_gregul писал(а):
dandan писал(а):тоже самое досчитывает до прошлого значения OСR и инвертирует выход.
И это правильно. Иначе - в выходном сигнале появится период сигнала с непредсказуемо завышенной частотой. И только после этого пойдет сигнал с правильной частотой. Если Вам это не мешает, ради Бога!
Ничего подобного. Так было бы, если бы он инвертировал выход и сбрасывал счетчик, далее считал уже до нового значения OСR.
Но при совпадении со старым значением OСR счетчик не сбрасывается, прерывание по совпадению не генерируется, только зачем-то инвертируется выход. Затем счетчик считает дальше и при совпадении с уже установленным OСR работает нормально. В результате получаем короткие скачки как на графике длительностью равной разнице между новым и старым значением OСR.
Аватара пользователя
aleksey_gregul
Встал на лапы
Сообщения: 130
Зарегистрирован: Ср дек 29, 2010 17:30:34

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение aleksey_gregul »

dandan писал(а):Ничего подобного. Так было бы, если бы он инвертировал выход и сбрасывал счетчик, далее считал уже до нового значения OСR.
Но при совпадении со старым значением OСR счетчик не сбрасывается, прерывание по совпадению не генерируется, только зачем-то инвертируется выход.
Странно!
Вы в чем это проверяете?
Специально создал проектик. У меня совсем противоположные. При совпадении со старым значением OСR счетчик не сбрасывается и не инвертируется выход!
Протеус как-то странно симулит! Частота должна падать, что в студии и вижу, а в протеусе все наоборот.
Изображение
Только я програмлю на С в ИАР_е.

Код: Выделить всё

#include <iom8.h>
#include <stdio.h>
#include <inavr.h>
#define XTALL		8.0
#define delay_us(us)	__delay_cycles (XTALL * us);
#define delay_ms(ms)	delay_us (1000 * ms)

volatile unsigned char ch=10;

void inittimer2(void)
{
 TCCR2 = 0x00; //stop
 ASSR  = 0x00; //set async mode
 TCNT2 = 0x00; //setup
 OCR2  = 10;
 TIMSK = 0x80; //timer interrupt sources 
 TCCR2 = 0x1E; //start
 __enable_interrupt();
}

#pragma vector = TIMER2_COMP_vect // âûïîëíÿåòñÿ 12.56us
__interrupt void t2handler(void)//
{
TCNT2=0;
OCR2=ch;
}

void main( void )
{
PORTB = 0x00;
DDRB  = 0xFF;
inittimer2();
while(1)
{
delay_ms(10);
ch=ch+10;
}
}
dandan
Нашел транзистор. Понюхал.
Сообщения: 180
Зарегистрирован: Ср дек 22, 2010 12:40:17

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение dandan »

aleksey_gregul писал(а): TCCR2 = 0x1E; //start
Странно, у Вас
1E это 00010110 - это не режим СТС (судя по даташиту это режим NORMAL, считает до 0хFF)

у меня 00011110.

Прохожу пошагово в AVR Studio, симулирую в Протеусе - работает одинаково.
Аватара пользователя
aleksey_gregul
Встал на лапы
Сообщения: 130
Зарегистрирован: Ср дек 29, 2010 17:30:34

Re: AVR Mega8 Timer2 в режиме генератора частоты

Сообщение aleksey_gregul »

После более детального исследования происходящих процессов, выяснилось, что и прерывания наступают и таймер сбрасывается и пин меняется абсолютно одновременно (по крайней мере, если прерывания разрешены). За исключением одного НО.
Вводит в заблуждение понятие COMPARE. По привычке мы ожидаем, что само событие должно произойти именно в момент совпадения состояния счетчика с записанным в OCR2 числом. Но, в отладчике аврстудии, а я симулировал в "Avr Simulator" все происходит немножко по другому. При досчете таймера до OCR2, ничего не происходит. И как только таймер сменит свое зачение, наступает момент смены пина, обнуления таймера и генерирования прерывания. Т.Е. к примеру, в OCR2=5. Таймер досчитал до пяти и ничего не произошло. Но как только таймер досчитает до 6, тут же все и произойдет. Не знаю, как там в железе, но в "Avr Simulator" именно так.
Т.е. В прерывании ресетить таймер - действительно лишнее. А вот перегружать OCR2 следует именно в прерывании. В майне, только готовить для него данные.
С неразрешенными прерываниями не проверял. Возможно, ситуация изменится на ту, которую Вы описываете. Я без прерываний перегружать регистры таймера не буду и поэтому далее экспериментировать просто влом.
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»