Китайская Arduino Uno работа тамера-счетчика T0 в режиме Normal 32 или 64 kHz

russmakse
Offline
Зарегистрирован: 12.12.2016

Здраствуйте уважаемые форумчане!!!

На днях столкнулся с такой проблемой а именно решил запилить парочку практических работ по работе с таймерами в режимах Normal, СTC, Fast PWM, Phase Correct PWM, Phase and Frequency Correct PWM. 

Итак режим Normal

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL

ISR(TIMER0_OVF_vect){										// Прерывание по переполнению
						if( PINB & ( 1 << PB0 ) ){			// Условие если на выходе 1
						PORTB &= ~( 1 << PB0 );}			// То сбросить бит
						else {						// Иначе
						PORTB |= ( 1 << PB0 );}				// Установить бит
}

int main(void)
{
				DDRB = (1<<PB0);                             // Настройка порта на выход
				TCCR0B |= (0<<CS12) | (0<<CS11) | (1<<CS10); // Настройка претделителя таймера T0
				TIMSK0 |= (1 << TOIE1);                      // Разрешение прерываний по переполнению таймера
				TCNT0 = 0;                                   // Выставляем начальное значение счетчика
				sei();                                       // Глобальное разрешение прерывания
				while (1);                                   // Бесконечный цикл
				return 0;
  
}

Компилирую в AVRStudio 5, загружаю hex файл в Arduino Uno с помощью Xloadera (http://russemotto.com/xloader/) проверяю с помощью осцилографа частоту на на ножке

Проверяю все настройки предделитель не включен по расчетной формуле 64 кГц, складывается такое ощущение что включен делитель, проверяю fuse-bit у Atmega328p  с помощью AVRISP MK2 

Вроде бы все норм смущает только значение Extended, на форумах пишут что значение должно быть 

Low Fuse 0xFF

High Fuse 0xDE

Extended Fuse 0x05

Меняю extended прошиваю, читаю снова значение меняется на старое причем если прошить и проверить запись то пишет итс ОКей читаешь востонавливает обратно

Может здесь задача здесь и тривиальная но все таки хотелось бы знать пути решения, может и проблем ни каких нет вообще и он должен работать с такой частотой 32 кГц

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

russmakse, Вы падаете в прерывание 16E6/255 раз в секунду. При каждом входе вы можете либо опустить, либо поднять лапу. Стало быть полный цикл получается за два входа.  Итого 32кГц

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

По частоте Вам уже объяснили, я бы хотел добавить по строкам 6-9.

Вам ведь там нужно просто инвертировать нулевой бит порта B (он же 8-ой цифровой пин Ардуино). Я правильно понял? Если правильно, то так и пишите:

PINB |= (1 << PB0);

всё инвертируется. Зачем так длинно-то?

russmakse
Offline
Зарегистрирован: 12.12.2016

Я считал так:

Тактовая частота микроконтроллера Fcpu = 16000000 Гц Требуемое время 1/64000 Гц = 0,000015625 с Период тактового сигнала микроконтроллера Tcpu = 1/Fcpu = 1/16000000 Гц= 0,0000000625 с Период тактового сигнала таймера Т0 равен Tt0 = (1/Fcpu)/k = k/Fcpu = 1/16000000 Гц = 0,0000000625 с -- где k это предделитель. n = t/Tto = 0,000015625 с0,0000000625 с = 250 TCNT0 = 256 - n = 256-250 = 6 - это начально значение я не заморачивался взял ноль

Вы могли бы чуть подробней, спасибо заранее, клинит мальца

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, Вы посчитали параметры таймера для того, чтобы он выдал прерывание через время равное периоду! Так? А сами в течение этого времени держите HIGH, а потом в течение ещё такого же времени держите LOW. Вот и получается что Вы вдвое увеличили период или, что тоже самое, вдвое уменьшиили частоту. 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

russmakse, что за изврат? Зачем переводить герцы в микросекунды?  Просто разделите F_CPU/ 256  и ещё раз на 2 . Вот и весь расчёт.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

russmakse пишет:

клинит мальца

Если "мальца" - клинит, нужно любрикант использовать. Себя ты не бережешь! ;)

======

У тебя кажбый цикл таймера длится 256 тактов, предделитель ты выключил.

На каждое переполнение ты ПЕРЕКЛЮЧАЕШЬ 0 и 1, то есть цикл таймера - у тебя ПОЛпериода.

62.5 нс * 256 = 16 мкс - у тебя ПОЛ периода (0 и 1 по очереди),  А весь период - 32 мкс, что дает 31.25 КГц.

Частота появления переполнений - 62.5 КГц, но сигнал, что ты старательно строил, в ДВА раза ниже.

russmakse
Offline
Зарегистрирован: 12.12.2016

Спасибо большое, самое сложное искать ошибки которых нет, пояснение ЕвгенийП все поставило на свои места. dimax согласен изврат,  ЕвгенийП согласен можно проще с инверсией

russmakse
Offline
Зарегистрирован: 12.12.2016

wdrakula пишет:

russmakse пишет:

клинит мальца

Если "мальца" - клинит, нужно любрикант использовать. Себя ты не бережешь! ;)

Под**б защитан=))