ШИМ в ATmega16

Обсуждаем контроллеры компании Atmel.
Ответить
Открыл глаза
Сообщения: 49
Зарегистрирован: Ср мар 26, 2014 17:33:08

Сообщение Aviator_93 »

Всем доброго дня. Не могу разобраться, как рассчитываются таймеры, для формирования ШИМ-сигнала. Имеется ATmega16, в нем есть 16 битный таймер-счетчик с предделителем 1024, в режиме FAST PWM 10-bit, сама ATmega работает на частоте 9,6 МГц, разумеется от кварца. На выводе МК, мне необходимо получить, сигнал частотой 100 Гц. Вот, как я рассчитываю:
Считаем частоту работы таймера 9600000/1024=9375 Гц
Получается за 1 секунду таймер тактируется 9375 раз, исходя из этого, выходит, что один такт таймера выполняется за 0,106 мс, а нам нужно 10 мс (100 Гц => 10 мс), вот и выходит, что для получения 10 мс нужно, что бы прошло 94 такта таймера.
Правильны ли мои рассуждения?
Реклама
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Похожи на правильные.
Aviator_93 писал(а):что бы прошло 94 такта таймера
или тогда вам нафиг не нужен 16-битный счётчик, или подбирайте делитель так, чтобы диапазон значений был как можно ближе к концу (к 65536). В этом случае можно точнее подогнать частоту. Сейчас вы будете регулировать её с точностью 1/100я, а то 1/65536я (или какая там получится). Есть разница? :)
Реклама
Открыл глаза
Сообщения: 49
Зарегистрирован: Ср мар 26, 2014 17:33:08

Сообщение Aviator_93 »

или тогда вам нафиг не нужен 16-битный счётчик, или подбирайте делитель так, чтобы диапазон значений был как можно ближе к концу (к 65536)
Спасибо, потом получше подберу. А в 16-битном таймере-счетчике, который работает в FAST PWM 10-bit режиме, максимальный размер счетного регистра 0xFFFF или 0x03FF?
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

На то он и 16-битный, что 0xFFFF
Aviator_93 писал(а):FAST PWM 10-bit режиме
Это какой такой? В смысле почему 10 бит? Так же, в 16-битном он и работает.
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 49
Зарегистрирован: Ср мар 26, 2014 17:33:08

Сообщение Aviator_93 »

В даташите ATmega16 приведены, все возможные настройки 16-битного таймера-счетчика
Изображение графа TOP это максимальный счетный регистр или что-то другое? Если, нет, тогда что?
Реклама
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Aviator_93 писал(а):графа TOP это максимальный счетный регистр или что-то другое?
Да, максимальный, но вам нужен режим CTC, тогда этот TOP вы сможете настраивать как угодно, соответственно счётчик будет считать столько, сколько хотите тактов. Этим и частоту можно точно настроить, даже если кварц немного неточен будет.
Реклама
Открыл глаза
Сообщения: 49
Зарегистрирован: Ср мар 26, 2014 17:33:08

Сообщение Aviator_93 »

но вам нужен режим CTC
На сколько, я понимаю это режим сброс по совпадению. Его обязательно использовать? Возможно, я немного неправильно поставил свой вопрос. Мне необходимо, что бы сигнал на выходе, 10 мс находился в логической 1 и 10 мс отсутствовал. Вот, я и взглянул в сторону Fast PWM
Изображение
т. е. у нас есть максимальное значение счетного регистра top, пусть будет 0x3FF, и есть две точки k и n. В точке n сигнал подается на выход, а в точке k сигнал снимается, т. к. мы выше рассчитали сколько тактов потребуется на 10 мс, то можно сказать при top=0x3FF, точка k = 0x3A1 (0x3FF-0x5E), а точка n=0x343 (0x3FF-0x5E-0x5E).
В коде у меня получилось вот так:

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

ISR(TIMER1_OVF_vect)
{
	TCNT1H = 0x03;
	TCNT1L = 0x43;

	PORTD |= (1 << 7);		
}

ISR(TIMER1_COMPA_vect)
{
	PORTD &= ~(1 << 7);
}

int main(void)
{
	DDRD |= (1 << 7);

	TCCR1A &= ~(1 << WGM13);
	TCCR1A |= (1 << WGM12);
	TCCR1A |= (1 << WGM11);
	TCCR1A |= (1 << WGM10);
	
	TCCR1B |= (1 << CS12);
	TCCR1B &= ~(1 << CS11);
	TCCR1B |= (1 << CS10);
	
	TCNT1H = 0x03;
	TCNT1L = 0x43;
		
	OCR1AH = 0x03;
	OCR1AL = 0xA1; 	
				
	TIMSK |= (1 << OCIE1A);
	TIMSK |= (1 << TOIE1);	
	
	sei();

    	while(true)
    	{
       
    	}
}
И вообще по логике, я правильно мыслю или где-то чего-то упустил?
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Да всё вы правильно мыслите, только немного ошиблись с терминами:
Aviator_93 писал(а):Мне необходимо, что бы сигнал на выходе, 10 мс находился в логической 1 и 10 мс отсутствовал.
Это значит период у вас будет 20мс, а частота, соответственно, 50Гц.
Aviator_93 писал(а):Его обязательно использовать?
Это тот же Fast PWM, только с настраиваемым TOP. Рассчитываете делитель на счётчик так, чтобы полный период был поближе к концу. Например делите не 8, получите частоту на входе счётчика 1.2МГц, и, досчитав до 24000 он сбросится, тем самым дав вам период в 50Гц. А в регистр ШИМа (как он там называется) заносите половинное число (чтобы был меандр), это будет 12000

И да, в коде вам совершенно не нужны прерывания. Настраиваете счётчик один раз, дальше он сам работает, на то он и аппаратный счётчик.
Открыл глаза
Сообщения: 49
Зарегистрирован: Ср мар 26, 2014 17:33:08

Сообщение Aviator_93 »

только немного ошиблись с терминами
А тогда все понятно, большое спасибо за помощь, буду исправляться
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Угу. Прерывания убрать не забудьте :)
Ответить

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