Как работают таймеры Arduino после сброса…

В Arduino на основе ATmega328 используются все три имеющихся в микроконтроллере таймера. Таймер 0 задействован в функциях «определения времени» (millis(), micros()). Таймер 1 и Таймер 2 вместе с Таймер 0 используются в процедурах analogWrite() для формирования на некоторых выводах микроконтроллера ШИМ импульсов.

Может быть полезным — знать в каком режиме работают таймеры после включения питания платы Arduino, или подачи сигнала сброса…

В «становлении» работы таймеров принимает участие процедура init(), описанная в файле wiring.c

void init()  {
	sei();
//---------------- Timer0 ------------------------	
// on the ATmega168, timer 0 is also used for fast hardware pwm
	sbi(TCCR0A, WGM01);
	sbi(TCCR0A, WGM00);
	// set timer 0 prescale factor to 64
	sbi(TCCR0B, CS01);
	sbi(TCCR0B, CS00);
	// enable timer 0 overflow interrupt
	sbi(TIMSK0, TOIE0);
//--------------------------------------------------
	// timers 1 and 2 are used for phase-correct hardware pwm
//---------------- Timer1 -------------------------
	TCCR1B = 0;
	// set timer 1 prescale factor to 64
	sbi(TCCR1B, CS11);
	sbi(TCCR1B, CS10);
	// put timer 1 in 8-bit phase correct pwm mode
	sbi(TCCR1A, WGM10);
//---------------- Timer2 -------------------------
	// set timer 2 prescale factor to 64
	sbi(TCCR2B, CS22);
	// configure timer 2 for phase correct pwm (8-bit)
	sbi(TCCR2A, WGM20);
//---------------- USART --------------------------
// the bootloader connects pins 0 and 1 to the USART; disconnect them
// here so they can be used as normal digital i/o; they will be
// reconnected in Serial.begin()
	UCSR0B = 0;
}

Выше приведенный текст — это «очищенная от иных, чем ATmega48/88/168/328 версий микроконтроллера» процедура init() — так легче в ней разобраться. Процедура init() «срабатывает» перед запуском процедуры setup() любого скетча, написанного для Arduino. Посмотрим, как она определяет работу таймеров микроконтроллера:

  • как ни странно, первым делом в системе разрешаются прерывания…
  • затем начинается настройка Таймера 0. Установкой битов WGM00 и WGM01 в регистре TCCR0A включается режим работы Fast PWM. В таком режиме счетчик TCNT0 непрерывно считает импульсы, увеличивая значение с 0 до 0xFF, затем сбрасывая его в 0 и т.д. Это позволяет использовать прерывания по переполнению счетчика для работы millis() и, одновременно, не мешает грузить в регистр OCR0A какое-либо значение, добиваясь формирования ШИМ импульсов на выводах микроконтроллера (процедура analogWrite()).
  • установка младших битов CS00 и CS01 регистра TCCR0B в единицу включает «предделитель» частоты на входе счетчика таймера в значение 64. Т.е. на вход счетчика идут импульсы с частотой 16МГц поделенной на 64, т.е. 250КГц (период следования равен 4 мкс). Сам счетчик TCNT0 байтовый, таким образом получаем период переполнений счетчика равный 1024 мкс — для millis() почти что «самое то!» — как это преобразуется в 1 мс описано тут.
  • в конце настройки Таймера 0 устанавливается маска прерываний от таймера на срабатывание по переполнению.
  • после нулевого, процедура init() занимается настройкой Таймера 1. В-общем, все тоже самое, что и с Таймером 0, с поправкой на использование режима Phase Correct PWM вместо Fast PWM. Отметим, что прерывания от Таймера 1 запрещены.
  • второй таймер в настройке аналогичен Таймеру 1 (со своей спецификой имен регистров). Прерывания от Таймера 2 также запрещены.
  • нижняя строчка процедуры «выключает» USART микроконтроллера, чтобы можно было пользоваться pin0 и pin1 как обычными цифровыми линиями. Вспомним, что эти линии в процессе загрузки программы принимают самое активное участие, как линии RxD и TxD USART.

Таким образом, после включения питания, перед началом работы скетча (его начальной процедуры setup()), таймеры микроконтроллера платы Arduino работают почти одинаково: «весело» считая 250 килогерцовые импульсы своими 8-битными счетчиками. При этом Таймер 0 после переполнения вызывает прерывание, которое обрабатывается ранее описанной процедурой. Все три таймера готовы к восприятию в регистры OCRnA байта формирующего ШИМ на некоторых выводах платы (об этом как-нибудь в следующий раз)…

Добавить комментарий

Ваш e-mail не будет опубликован.

Нажимая кнопку "Отправить" Вы даёте свое согласие на обработку введенной персональной информации в соответствии с Федеральным Законом №152-ФЗ от 27.07.2006 "О персональных данных".