Таймеры/счётчики в AVR

Обсуждаем контроллеры компании Atmel.
watchmaker
Поставщик валерьянки для Кота
Сообщения: 2183
Зарегистрирован: Вс ноя 15, 2009 23:13:59
Откуда: Харьков
Контактная информация:

Re: Таймеры/счётчики в AVR

Сообщение watchmaker »

Вопрос по таймеру в ATtiny25. Пока всё в Протеусе, реальное железо будет позже.
Выставляю биты CTC1, PWM1A, COM1A1, заношу все необходимые данные, таймер запускается.
По даташиту в таком случае выход OC1A (PB1) должен выдавать шим-сигнал, инверсный выход !OC1A (PB0) должен молчать (not connected).
До запуска таймера на PB0 стояла единица.
В тот момент, когда таймер запускается, на PB0 появляется ноль, после остановки - снова единица. Должно ли так быть в реальном железе?

Перевожу таймер в Normal mode (PWM1A = 0) - такой проблемы нет.
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
Реклама
watchmaker
Поставщик валерьянки для Кота
Сообщения: 2183
Зарегистрирован: Вс ноя 15, 2009 23:13:59
Откуда: Харьков
Контактная информация:

Re: Таймеры/счётчики в AVR

Сообщение watchmaker »

Опять расхождение 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 на единицу меньше. Глюк в библиотеке и я чего-то не понимаю?
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
Реклама
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Таймеры/счётчики в AVR

Сообщение OKF »

Харьков, ну так давай проект в Протеусе, а мы проверим. Не верить же тебе на слово.
Баги в Протеусе имеются но, как правило, в хитрых режимах. Типа, sleep, wdt...
watchmaker
Поставщик валерьянки для Кота
Сообщения: 2183
Зарегистрирован: Вс ноя 15, 2009 23:13:59
Откуда: Харьков
Контактная информация:

Re: Таймеры/счётчики в AVR

Сообщение watchmaker »

Как раз со слипом проблем не встречал. Весь проект довольно специфический (и ещё не совсем готовый).
Вытащил необходимый кусочек и вставил в отдельный файл. Файл переименовать в *.pdsprj, не распаковывать.
По даташиту fPWM = fTCK1 / (OCR1C + 1), поэтому в функции явно вычитаю единицу перед записью в регистр.
Должно выдать 2048 Гц (32768 / 16). В железе реально 2048 Гц, в Протеусе существенно больше, как будто единица вычитается ещё раз.

Получится проверить на более старых или более новых версиях Протеуса без перекомпиляции прошивки?
Вложения
test-tiny.zip
(15.72 КБ) 101 скачивание
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
Реклама
Эиком - электронные компоненты и радиодетали
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Таймеры/счётчики в AVR

Сообщение kote52 »

Всех С Новым Годом!
Ребята подскажите как налету менять частоту на 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);
На счет регистра 0<<COM2B1 - когда надо я его включаю. Беспокоит частота которая не меняется, меняется только скважность, длинна периода остается неизменной, хотя в регистр OCR2A все записывается верно.
Реклама
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Таймеры/счётчики в AVR

Сообщение Just_Fluffy »

kote52, Mode: Fast PWM top=OCR2A - это будет, когда WGM2[2:0] = 111
А вы WGM22 обнуляете, когда присваиваете значение CS2[2:0] регистру TCCR2B
И получается у вас WGM2[2:0] = 011, что соответствует Fast PWM top=OxFF
Белая и Пушистая
Реклама
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Таймеры/счётчики в AVR

Сообщение kote52 »

[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4667254#p4667254"]И получается у вас WGM2[2:0] = 011, что соответствует Fast PWM top=OxFF[/uquote]
В Протусе прогнал, было TCCR2B 0b00001100 после инициализации, как начал проигрывать мелодию изменилось 0b00000011. Какой выход? Писать полность вместе с WGM22?
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Таймеры/счётчики в AVR

Сообщение Just_Fluffy »

kote52, вариант 1 - да, писать вместе с WGM22
Вариант 2 - определить дефайны для всех режимов обоих регистров TCCR и присваивать дефайны. Плюс - все биты собраны в одном месте и забыть где то доприсвоить бит мала вероятность
Вариант 3 - использовать битовую арифметику при присвоении CS2x - сначала обнулить три бита CS, потом поднять нужные. Но с точки зрения кода это больше операций.
Для себя я б остановилась на дефайнах (или вообще на отдельной функции установки частоты и включения/выключения звука. Тогда все настройки таймера будут собраны в одном месте и битики не будут теряться)
Белая и Пушистая
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Таймеры/счётчики в AVR

Сообщение kote52 »

Уважаемые форумчане, подскажите пожалуйста в чем проблема?
Настроика таймеров в 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);
При таких настройках на выходе OCR1B и OCR2B имею импульс в 4uS.
СпойлерИзображение
Отключаем Таймер1, все нормально, импульсов нет. Таймер1 управляет через RC цепь TL494, Таймер0 и Таймер2 полевиками, как быть когда нужно вообще убрать сигнал в 0 на OCR1B и OCR2B, отключать
Спойлер

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

TCCR0A&=~(0<<COM0B1); 
TCCR0A&=~(0<<COM0B0);

TCCR2A&=~(0<<COM2B1); 
TCCR2A&=~(0<<COM2B0);
или я даташит не дочитал
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Таймеры/счётчики в AVR

Сообщение Starichok51 »

0<<COM0B1 - ноль ничего не изменит в регистре.
если нужно сбросить бит, то следует писать
TCCR0A&=~(1<<COM0B1);
ну, и для остальных строк то же самое.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Таймеры/счётчики в AVR

Сообщение kote52 »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4683827#p4683827"]TCCR0A&=~(1<<COM0B1);
ну, и для остальных строк то же самое.[/uquote]
да ваша правда, дал маху, ну а что с импульсами то, подскажите?
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Таймеры/счётчики в AVR

Сообщение Starichok51 »

а что можно подсказать, если не известно, что программа делает и что она должна делать?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Таймеры/счётчики в AVR

Сообщение kote52 »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4683877#p4683877"]а что можно подсказать, если не известно, что программа делает и что она должна делать?[/uquote]
да я вроде выше описал "Таймер1 управляет через RC цепь TL494, Таймер0 и Таймер2 полевиками, как быть когда нужно вообще убрать сигнал в 0 на OCR1B и OCR2B." Зачем мне приоткрытые полевики? нет можно конечно оставить так, и отключать ногу от таймера как писал выше... но я хотел разобрать в причине появления этого импульса 4 uS, я накосячил, или же в работу тамеров 0 и 2 влияет как то таймер1?
Аватара пользователя
VNS
Говорящий с текстолитом
Сообщения: 1627
Зарегистрирован: Пт дек 10, 2021 12:48:46
Откуда: Тюмень

Re: Таймеры/счётчики в AVR

Сообщение VNS »

При использовании ШИМ и значении OCRn = 0 на выводе всегда будет "иголка"… убирается она только путём перевода вывода на вход при значении OCRn = 0, при других значениях вывод переводится на выход. При этом затвор транзистора не должен оставаться без подтяжки к общей шине.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Таймеры/счётчики в AVR

Сообщение kote52 »

[uquote="VNS",url="/forum/viewtopic.php?p=4683918#p4683918"]При использовании ШИМ и значении OCRn = 0 на выводе всегда будет "иголка"[/uquote]
Уважаемый VNS мне это известно, но не 4 микросекунды же иголка должна быть? и почему нет иголок когда отключаю Таймер1 вообще(настройки по нолям для Т1)?
Последний раз редактировалось kote52 Вт фев 18, 2025 14:08:29, всего редактировалось 1 раз.
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Таймеры/счётчики в AVR

Сообщение Just_Fluffy »

VNS, не обязательно на вход. Можно просто выключать режим ШИМ-выхода через конфигурационные биты COMххх
Белая и Пушистая
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Таймеры/счётчики в AVR

Сообщение Starichok51 »

kote52, нужна правильная настройка самих портов.
порты, на которые подключаются выходы сравнения (OCRху), нужно настроить как выходы и записать туда ноль.
и когда ты отключаешь выходы сравнения от портов, то там сразу установятся нули.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

Re: Таймеры/счётчики в AVR

Сообщение kote52 »

Спасибо всем откликнувшимся!
Но эти иглы должны пропасть когда Out A или B будут Inverted PWR. А у меня получается низкий уровень на 4uS. Опять же если у отключаю Таймер 1, все в норме!
watchmaker
Поставщик валерьянки для Кота
Сообщения: 2183
Зарегистрирован: Вс ноя 15, 2009 23:13:59
Откуда: Харьков
Контактная информация:

Re: Таймеры/счётчики в AVR

Сообщение watchmaker »

Вопрос по таймеру 1 в ATtiny85. Использую его, чтобы издавать звук.
Задаю параметры таймера в 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

Сообщение watchmaker »

И ещё вопрос. Существуют ли AVR микроконтроллеры, которые имеют четыре таймера (или больше) с ШИМ-выходами? Функциональность нужна идентичная таймеру 1 в tiny85 - выбор предделителя 2⁰, 2¹, 2² и т. д. и деление частоты на любой коэффициент от 2 до 255 (реально нужны от 30 до 242). Из остального - минимум 8 к флэш, 256 байт оперативной и три линии ввода вывода без учёта ШИМ-выходов (если тактировать от кварца - и без учёта линий под кварц).
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
Ответить

Вернуться в «AVR»