Таймеры/счётчики в AVR
-
watchmaker
- Поставщик валерьянки для Кота
- Сообщения: 2183
- Зарегистрирован: Вс ноя 15, 2009 23:13:59
- Откуда: Харьков
- Контактная информация:
Re: Таймеры/счётчики в AVR
Вопрос по таймеру в ATtiny25. Пока всё в Протеусе, реальное железо будет позже.
Выставляю биты CTC1, PWM1A, COM1A1, заношу все необходимые данные, таймер запускается.
По даташиту в таком случае выход OC1A (PB1) должен выдавать шим-сигнал, инверсный выход !OC1A (PB0) должен молчать (not connected).
До запуска таймера на PB0 стояла единица.
В тот момент, когда таймер запускается, на PB0 появляется ноль, после остановки - снова единица. Должно ли так быть в реальном железе?
Перевожу таймер в Normal mode (PWM1A = 0) - такой проблемы нет.
Выставляю биты CTC1, PWM1A, COM1A1, заношу все необходимые данные, таймер запускается.
По даташиту в таком случае выход OC1A (PB1) должен выдавать шим-сигнал, инверсный выход !OC1A (PB0) должен молчать (not connected).
До запуска таймера на PB0 стояла единица.
В тот момент, когда таймер запускается, на PB0 появляется ноль, после остановки - снова единица. Должно ли так быть в реальном железе?
Перевожу таймер в Normal mode (PWM1A = 0) - такой проблемы нет.
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
- Реклама
-
watchmaker
- Поставщик валерьянки для Кота
- Сообщения: 2183
- Зарегистрирован: Вс ноя 15, 2009 23:13:59
- Откуда: Харьков
- Контактная информация:
Re: Таймеры/счётчики в AVR
Опять расхождение Proteus vs реальное железо. ATtiny25/45/85, Proteus 8.17SP2, WinAVR.
Пишу так:
void pwm_init(unsigned char prescaler, unsigned char divider, unsigned char width)
{
OCR1A=width;
OCR1C=divider-1;
TCCR1=BIT(CTC1)|BIT(COM1A1)|BIT(PWM1A)|(prescaler & 0xF);
}
Вся остальная инициализация в начале мейна и тут не играет роли.
Задаю divider=16, prescaler=1, width=4. Тактирование от часового кварца 32768 Гц. Должна выдаваться частота 2048 Гц, в железе всё чётко, в Протеусе же частота существенно выше - пищалка на выходе пищит более высоким тоном, как будто divider на единицу меньше. Глюк в библиотеке и я чего-то не понимаю?
Пишу так:
void pwm_init(unsigned char prescaler, unsigned char divider, unsigned char width)
{
OCR1A=width;
OCR1C=divider-1;
TCCR1=BIT(CTC1)|BIT(COM1A1)|BIT(PWM1A)|(prescaler & 0xF);
}
Вся остальная инициализация в начале мейна и тут не играет роли.
Задаю divider=16, prescaler=1, width=4. Тактирование от часового кварца 32768 Гц. Должна выдаваться частота 2048 Гц, в железе всё чётко, в Протеусе же частота существенно выше - пищалка на выходе пищит более высоким тоном, как будто divider на единицу меньше. Глюк в библиотеке и я чего-то не понимаю?
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
Re: Таймеры/счётчики в AVR
Харьков, ну так давай проект в Протеусе, а мы проверим. Не верить же тебе на слово.
Баги в Протеусе имеются но, как правило, в хитрых режимах. Типа, sleep, wdt...
Баги в Протеусе имеются но, как правило, в хитрых режимах. Типа, sleep, wdt...
-
watchmaker
- Поставщик валерьянки для Кота
- Сообщения: 2183
- Зарегистрирован: Вс ноя 15, 2009 23:13:59
- Откуда: Харьков
- Контактная информация:
Re: Таймеры/счётчики в AVR
Как раз со слипом проблем не встречал. Весь проект довольно специфический (и ещё не совсем готовый).
Вытащил необходимый кусочек и вставил в отдельный файл. Файл переименовать в *.pdsprj, не распаковывать.
По даташиту fPWM = fTCK1 / (OCR1C + 1), поэтому в функции явно вычитаю единицу перед записью в регистр.
Должно выдать 2048 Гц (32768 / 16). В железе реально 2048 Гц, в Протеусе существенно больше, как будто единица вычитается ещё раз.
Получится проверить на более старых или более новых версиях Протеуса без перекомпиляции прошивки?
Вытащил необходимый кусочек и вставил в отдельный файл. Файл переименовать в *.pdsprj, не распаковывать.
По даташиту fPWM = fTCK1 / (OCR1C + 1), поэтому в функции явно вычитаю единицу перед записью в регистр.
Должно выдать 2048 Гц (32768 / 16). В железе реально 2048 Гц, в Протеусе существенно больше, как будто единица вычитается ещё раз.
Получится проверить на более старых или более новых версиях Протеуса без перекомпиляции прошивки?
- Вложения
-
- test-tiny.zip
- (15.72 КБ) 101 скачивание
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
Re: Таймеры/счётчики в AVR
Всех С Новым Годом!
Ребята подскажите как налету менять частоту на Timer2 в atmega328p? Пытаюсь вывести звук с вывода OCR2B
На счет регистра 0<<COM2B1 - когда надо я его включаю. Беспокоит частота которая не меняется, меняется только скважность, длинна периода остается неизменной, хотя в регистр OCR2A все записывается верно.
Ребята подскажите как налету менять частоту на Timer2 в atmega328p? Пытаюсь вывести звук с вывода OCR2B
Спойлер
Timer2 настроеКод: Выделить всё
ISR (TIMER2_COMPA_vect) {
}
// Clock source: System Clock
// Clock value: 250,000 kHz
// Mode: Fast PWM top=OCR2A
// OC2A output: Disconnected
// OC2B output: Non-Inverted PWM
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (1<<WGM20);
TCCR2B=(1<<WGM22) | (1<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(0<<OCIE2B) | (0<<OCIE2A) | (0<<TOIE2);Спойлер
Где то в программе когда надо установить новую частоту, делаю такКод: Выделить всё
TIMSK2&=~(1<<OCIE2A);
TCCR2B = (0<<CS22) | (0<<CS21) | (0<<CS20); //Timer2 No clock source (Timer/Counter stopped)
TCNT2 = 0x00;
if(toneNote & U_BIT_TONE) {
toneNote = toneNote ^ (U_BIT_TONE);
OCR2A = (unsigned char)toneNote;
OCR2B = (unsigned char)toneNote >> 1; //50%
TCCR2B= (1<<CS22) | (0<<CS21) | (0<<CS20); //Timer2 250kHz clkT2S/64 (from prescaler)
} else {
OCR2A = (unsigned char)toneNote;
OCR2B = (unsigned char)toneNote >> 1; //50%
TCCR2B= (0<<CS22) | (1<<CS21) | (1<<CS20); //Timer2 500kHz clkT2S/32 (from prescaler)
}
TIMSK2|=(1<<OCIE2A);- Реклама
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Таймеры/счётчики в AVR
kote52, Mode: Fast PWM top=OCR2A - это будет, когда WGM2[2:0] = 111
А вы WGM22 обнуляете, когда присваиваете значение CS2[2:0] регистру TCCR2B
И получается у вас WGM2[2:0] = 011, что соответствует Fast PWM top=OxFF
А вы WGM22 обнуляете, когда присваиваете значение CS2[2:0] регистру TCCR2B
И получается у вас WGM2[2:0] = 011, что соответствует Fast PWM top=OxFF
Белая и Пушистая
Re: Таймеры/счётчики в AVR
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4667254#p4667254"]И получается у вас WGM2[2:0] = 011, что соответствует Fast PWM top=OxFF[/uquote]
В Протусе прогнал, было TCCR2B 0b00001100 после инициализации, как начал проигрывать мелодию изменилось 0b00000011. Какой выход? Писать полность вместе с WGM22?
В Протусе прогнал, было TCCR2B 0b00001100 после инициализации, как начал проигрывать мелодию изменилось 0b00000011. Какой выход? Писать полность вместе с WGM22?
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Таймеры/счётчики в AVR
kote52, вариант 1 - да, писать вместе с WGM22
Вариант 2 - определить дефайны для всех режимов обоих регистров TCCR и присваивать дефайны. Плюс - все биты собраны в одном месте и забыть где то доприсвоить бит мала вероятность
Вариант 3 - использовать битовую арифметику при присвоении CS2x - сначала обнулить три бита CS, потом поднять нужные. Но с точки зрения кода это больше операций.
Для себя я б остановилась на дефайнах (или вообще на отдельной функции установки частоты и включения/выключения звука. Тогда все настройки таймера будут собраны в одном месте и битики не будут теряться)
Вариант 2 - определить дефайны для всех режимов обоих регистров TCCR и присваивать дефайны. Плюс - все биты собраны в одном месте и забыть где то доприсвоить бит мала вероятность
Вариант 3 - использовать битовую арифметику при присвоении CS2x - сначала обнулить три бита CS, потом поднять нужные. Но с точки зрения кода это больше операций.
Для себя я б остановилась на дефайнах (или вообще на отдельной функции установки частоты и включения/выключения звука. Тогда все настройки таймера будут собраны в одном месте и битики не будут теряться)
Белая и Пушистая
Re: Таймеры/счётчики в AVR
Уважаемые форумчане, подскажите пожалуйста в чем проблема?
Настроика таймеров в atmega328p
При таких настройках на выходе OCR1B и OCR2B имею импульс в 4uS.
Отключаем Таймер1, все нормально, импульсов нет. Таймер1 управляет через RC цепь TL494, Таймер0 и Таймер2 полевиками, как быть когда нужно вообще убрать сигнал в 0 на OCR1B и OCR2B, отключать
или я даташит не дочитал
Настроика таймеров в atmega328p
Спойлер
привожу настройку только таймеров, порты там все стандартно на выходКод: Выделить всё
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 250,000 kHz
// Mode: Fast PWM top=OCR0A
// OC0A output: Disconnected
// OC0B output: Non-Inverted PWM
// Timer Period: 1 ms
// Output Pulse(s):
// OC0B Period: 1 ms Width: 0 us
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(1<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A=0xF9;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 16000,000 kHz
// Mode: Fast PWM top=ICR1
// OC1A output: Non-Inverted PWM
// OC1B output: Non-Inverted PWM
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 0,032 ms
// Output Pulse(s):
// OC1A Period: 0,032 ms Width: 1,6282 us
// OC1B Period: 0,032 ms Width: 1,6282 us
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x01;
ICR1L=0xFF;
OCR1AH=0x00;
OCR1AL=0x1A;
OCR1BH=0x00;
OCR1BL=0x1A;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 250,000 kHz
// Mode: Fast PWM top=OCR2A
// OC2A output: Disconnected
// OC2B output: Non-Inverted PWM
// Timer Period: 1 ms
// Output Pulse(s):
// OC2B Period: 1 ms Width: 0 us
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (1<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (1<<WGM20);
TCCR2B=(1<<WGM22) | (1<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2A=0xF9;
OCR2B=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(0<<OCIE2B) | (0<<OCIE2A) | (0<<TOIE2);Спойлер
Код: Выделить всё
TCCR0A&=~(0<<COM0B1);
TCCR0A&=~(0<<COM0B0);
TCCR2A&=~(0<<COM2B1);
TCCR2A&=~(0<<COM2B0);
- Starichok51
- Модератор
- Сообщения: 19053
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Таймеры/счётчики в AVR
0<<COM0B1 - ноль ничего не изменит в регистре.
если нужно сбросить бит, то следует писать
TCCR0A&=~(1<<COM0B1);
ну, и для остальных строк то же самое.
если нужно сбросить бит, то следует писать
TCCR0A&=~(1<<COM0B1);
ну, и для остальных строк то же самое.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Re: Таймеры/счётчики в AVR
[uquote="Starichok51",url="/forum/viewtopic.php?p=4683827#p4683827"]TCCR0A&=~(1<<COM0B1);
ну, и для остальных строк то же самое.[/uquote]
да ваша правда, дал маху, ну а что с импульсами то, подскажите?
ну, и для остальных строк то же самое.[/uquote]
да ваша правда, дал маху, ну а что с импульсами то, подскажите?
- Starichok51
- Модератор
- Сообщения: 19053
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Таймеры/счётчики в AVR
а что можно подсказать, если не известно, что программа делает и что она должна делать?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Re: Таймеры/счётчики в AVR
[uquote="Starichok51",url="/forum/viewtopic.php?p=4683877#p4683877"]а что можно подсказать, если не известно, что программа делает и что она должна делать?[/uquote]
да я вроде выше описал "Таймер1 управляет через RC цепь TL494, Таймер0 и Таймер2 полевиками, как быть когда нужно вообще убрать сигнал в 0 на OCR1B и OCR2B." Зачем мне приоткрытые полевики? нет можно конечно оставить так, и отключать ногу от таймера как писал выше... но я хотел разобрать в причине появления этого импульса 4 uS, я накосячил, или же в работу тамеров 0 и 2 влияет как то таймер1?
да я вроде выше описал "Таймер1 управляет через RC цепь TL494, Таймер0 и Таймер2 полевиками, как быть когда нужно вообще убрать сигнал в 0 на OCR1B и OCR2B." Зачем мне приоткрытые полевики? нет можно конечно оставить так, и отключать ногу от таймера как писал выше... но я хотел разобрать в причине появления этого импульса 4 uS, я накосячил, или же в работу тамеров 0 и 2 влияет как то таймер1?
- VNS
- Говорящий с текстолитом
- Сообщения: 1627
- Зарегистрирован: Пт дек 10, 2021 12:48:46
- Откуда: Тюмень
Re: Таймеры/счётчики в AVR
При использовании ШИМ и значении OCRn = 0 на выводе всегда будет "иголка"… убирается она только путём перевода вывода на вход при значении OCRn = 0, при других значениях вывод переводится на выход. При этом затвор транзистора не должен оставаться без подтяжки к общей шине.
Re: Таймеры/счётчики в AVR
[uquote="VNS",url="/forum/viewtopic.php?p=4683918#p4683918"]При использовании ШИМ и значении OCRn = 0 на выводе всегда будет "иголка"[/uquote]
Уважаемый VNS мне это известно, но не 4 микросекунды же иголка должна быть? и почему нет иголок когда отключаю Таймер1 вообще(настройки по нолям для Т1)?
Уважаемый VNS мне это известно, но не 4 микросекунды же иголка должна быть? и почему нет иголок когда отключаю Таймер1 вообще(настройки по нолям для Т1)?
Последний раз редактировалось kote52 Вт фев 18, 2025 14:08:29, всего редактировалось 1 раз.
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Таймеры/счётчики в AVR
VNS, не обязательно на вход. Можно просто выключать режим ШИМ-выхода через конфигурационные биты COMххх
Белая и Пушистая
- Starichok51
- Модератор
- Сообщения: 19053
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Таймеры/счётчики в AVR
kote52, нужна правильная настройка самих портов.
порты, на которые подключаются выходы сравнения (OCRху), нужно настроить как выходы и записать туда ноль.
и когда ты отключаешь выходы сравнения от портов, то там сразу установятся нули.
порты, на которые подключаются выходы сравнения (OCRху), нужно настроить как выходы и записать туда ноль.
и когда ты отключаешь выходы сравнения от портов, то там сразу установятся нули.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Re: Таймеры/счётчики в AVR
Спасибо всем откликнувшимся!
Но эти иглы должны пропасть когда Out A или B будут Inverted PWR. А у меня получается низкий уровень на 4uS. Опять же если у отключаю Таймер 1, все в норме!
Но эти иглы должны пропасть когда Out A или B будут Inverted PWR. А у меня получается низкий уровень на 4uS. Опять же если у отключаю Таймер 1, все в норме!
-
watchmaker
- Поставщик валерьянки для Кота
- Сообщения: 2183
- Зарегистрирован: Вс ноя 15, 2009 23:13:59
- Откуда: Харьков
- Контактная информация:
Re: Таймеры/счётчики в AVR
Вопрос по таймеру 1 в ATtiny85. Использую его, чтобы издавать звук.
Задаю параметры таймера в OCR1B и OCR1C, потом выставляю биты PWM1B, COM1B1, CTC1 и настройки prescaler. Затем меняю OCR1B и OCR1C (иногда и prescaler) на лету, вычитывая их из PROGMEM. Проверяю в Протеусе - в эти регистры иногда пишется что попало, если перед записью не остановить таймер: TCCR1=0. Причём если начинает глючить, то продолжает, пока не остановишь таймер полностью. В железе пока этого глюка не замечал. Очередной баг Протеуса или более глубокая проблема?
Проблема началась после смены выхода OC1A на OC1B с соответствующими изменениями в регистрах (в дальнейшем планируется использовать и OC0B).
Если это окажется важно, чип тактируется от встроенного генератора 128 кГц.
Вот так работает всегда:
А без первой строки чудит:
Задаю параметры таймера в OCR1B и OCR1C, потом выставляю биты PWM1B, COM1B1, CTC1 и настройки prescaler. Затем меняю OCR1B и OCR1C (иногда и prescaler) на лету, вычитывая их из PROGMEM. Проверяю в Протеусе - в эти регистры иногда пишется что попало, если перед записью не остановить таймер: TCCR1=0. Причём если начинает глючить, то продолжает, пока не остановишь таймер полностью. В железе пока этого глюка не замечал. Очередной баг Протеуса или более глубокая проблема?
Проблема началась после смены выхода OC1A на OC1B с соответствующими изменениями в регистрах (в дальнейшем планируется использовать и OC0B).
Если это окажется важно, чип тактируется от встроенного генератора 128 кГц.
Вот так работает всегда:
Код: Выделить всё
void pwm_init(unsigned char prescaler, unsigned char divider, unsigned char width)
{
TCCR1=0;
OCR1B=width;
OCR1C=divider - 1;
GTCCR=BIT(PWM1B)|BIT(COM1B1);
TCCR1=BIT(CTC1)|(prescaler & 0xF);
}Код: Выделить всё
void pwm_init(unsigned char prescaler, unsigned char divider, unsigned char width)
{
OCR1B=width;
OCR1C=divider - 1;
GTCCR=BIT(PWM1B)|BIT(COM1B1);
TCCR1=BIT(CTC1)|(prescaler & 0xF);
}Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
-
watchmaker
- Поставщик валерьянки для Кота
- Сообщения: 2183
- Зарегистрирован: Вс ноя 15, 2009 23:13:59
- Откуда: Харьков
- Контактная информация:
Re: Таймеры/счётчики в AVR
И ещё вопрос. Существуют ли AVR микроконтроллеры, которые имеют четыре таймера (или больше) с ШИМ-выходами? Функциональность нужна идентичная таймеру 1 в tiny85 - выбор предделителя 2⁰, 2¹, 2² и т. д. и деление частоты на любой коэффициент от 2 до 255 (реально нужны от 30 до 242). Из остального - минимум 8 к флэш, 256 байт оперативной и три линии ввода вывода без учёта ШИМ-выходов (если тактировать от кварца - и без учёта линий под кварц).
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...


