LGT8F328P таймеры (Arduino)

Микроконтроллер LGT8F328P содержит 4-е таймера, Timer_1 и Timer_3 16 бит, а Timer_0 и Timer_2 8 бит.

Использование таймеров позволяет вызывать прерывание микроконтроллера для выполнения определенного фрагмента кода через заранее установленное время. Например необходимо мигать светодиодом каждую секунду, таймер будет запускать каждую секунду фрагмент кода отвечающего за мигание светодиода, в независимости от действия основной программы.

Все таймеры содержат счетный регистр TCNT который считает тактовые импульсы до определенной величины (зависит от размера), при достижении предельного числа счетчик переполняется и сбрасывается обратно в ноль. Таймер устанавливает бит флага, давая знать, что переполнение произошло, при этом вызывается прерывание.

Источником тактового сигнала для таймера/счетчика может быть как тактовый сигнал используемый для всего микроконтроллера с использованием предделителя, так и сигнал, поступающий с внешнего входа.

Для того чтобы использовать эти таймеры нужно использовать регистры настроек. Каждый таймер содержат несколько таких регистров, как именно использовать эти регистры и режимы работы таймеров будет описано в этой статье.

Режим CTC (сброс при совпадении)

Режим работы таймера CTC (сброс при совпадении) это когда в регистр OCR микроконтроллера загружается число, а счетный регистр TCNT сравнивает свое значение с числом регистра OCR и при совпадении происходит прерывание и сброс счетного регистра TCNT. При этом в обработчик прерывания исполняет помещенный в него код.

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

Для примера использования таймера выберем 16 битный таймер Timer_1.

Для настройки таймера в данном примере используется 3 регистра:

  • TCCR1B — Регистр управления B

  • OCR1A — Регистр сравнения А выходных данных

  • TIMSK1 — Регистр маски прерываний счетчика/таймера

Пример скетча:

void setup() {  

pinMode(12, OUTPUT);  

noInterrupts();  

TCNT1 = 0;  

TCCR1A = 0;  

TCCR1C = 0;  

byte n = 5;  

// clksys / 1 = 1  

// clksys / 8 = 2  

// clksys / 64 = 3  

// clksys / 256 = 4  

// clksys / 1024 = 5  

// [CS12:CS10]  

TCCR1B = (1 << WGM12) | n;  

OCR1A = 9999;// 0-65535  

TIMSK1 |= (1 << OCIE1A); //

_ctc = f_sys / (2 * n * (1 + OCR1A)) // 32 000 000 / (2 * 1024 * (1 + 9999)) = 1.5625 Hz interrupts();

}

void loop() {}

ISR(TIMER1_COMPA_vect){digitalWrite(12, !digitalRead(12));}

Подключите светодиод (через резистор 200 Ом) к выходу D12. После загрузки скетча светодиод начнет мигать с частотой 1,5625 Гц.

TCCR1B

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

В регистре управления используем бит WGW12 и биты CS10:CS12.

WGW12 активирует режим СТС

CS10:CS12 предделитель который делит тактовую частоту микроконтроллера

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

OCR1A

16-и битный регистр сравнения, содержит два 8-и битных регистра: OCR1AL и OCR1AH объединены для
формирования 16-разрядного OCR1A.

TIMSK1

Бит регистра TIMSK1 OCIE1A  разрешают прерывания при совпадении с A (OCR1A).

ISR(TIMER1_COMPA_vect) — функция обработчика прерывания, в нее помещается код который необходимо исполнять в режиме прерывания.

Если имеется необходимость использовать таймер для генерации импульсов (меандр), в микроконтроллере имеются выходы таймера. Для Timer_1 это выходы D9 и D10.

При совпадении регистра сравнения OCIE1A и счетного регистра состояние выхода таймера меняется на противоположное, а счетный регистр TCNT1 сбрасывается.

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

Ниже показан пример скетча генерации меандра, таймер работает в режиме CTC

void setup() {  

pinMode(9, OUTPUT);  

noInterrupts();  

TCNT1 = 0;  

TCCR1A = 0;  

TCCR1C = 0;  

byte n = 5;  

// clksys / 1 = 1  

// clksys / 8 = 2  

// clksys / 64 = 3  

// clksys / 256 = 4  

// clksys / 1024 = 5  

// [CS12:CS10]  

TCCR1B = (1 << WGM12) | n;  

OCR1A = 9999;// 0-65535  

TCCR1A |= (1 << COM1A0);

// f_ctc = f_sys / (2 * n * (1 + OCR1A)) // 32 000 000 / (2 * 1024 * (1 + 9999)) = 1.5625 Hz interrupts();

}

void loop() {}

Бит COM1A0 регистра TCCR1A определяет режим работы таймера. Если установлен бит COM1A0 то состояние на выходе OC1A меняется на противоположное при совпадении.

В этом примере если подключить светодиод (через резистор 200 Ом) к выходу D9, то после загрузки скетча он начнет мигать с частотой 1,5625 Гц.

Нормальный режим работы таймера

В нормальном режиме работы таймера можно использовать регистр сравнения OCR1A, при равенстве счетного регистра TCNT1 и регистра сравнения OCR1A происходит прерывание, но в отличии от режима СТС счетный регистр TCNT1 не сбрасывается, а увеличивает свое значение до максимального 65535 и только после этого происходит его сброс и новое прерывание.

Для нормальной работы этого режима в регистре масок прерывания TIMSK1 используются биты OCIE1A и TOIE1.

Бит OCIE1A разрешает прерывание по совпадению, а бит TOIE1 разрешает прерывание по переполнению.

При этом прерывания происходят два раза за один цикл заполнения счетного регистра TCNT1.

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

Пример скетча

void setup() {  

pinMode(12, OUTPUT);  

noInterrupts();  

TCNT1 = 0;  

TCCR1A = 0;  

TCCR1C = 0;  

byte n = 5;  

// clksys / 1 = 1  

// clksys / 8 = 2  

// clksys / 64 = 3  

// clksys / 256 = 4  

// clksys / 1024 = 5  

// [CS12:CS10]  

TCCR1B = n;  

OCR1A = 9999;// 0-65535  

TIMSK1 |= (1 << OCIE1A) | (1 << TOIE1);

interrupts();

}

void loop() {}

ISR(TIMER1_COMPA_vect){  digitalWrite(12, !digitalRead(12));  }

При обнулении счетного регистра светодиод подключенный к D12 (через резистор 200 Ом) загорается, как только значение счетного регистра станет равным значению регистра сравнения, светодиод погаснет и не будет светится пока значение счетного регистра не достигнет максимального значения.

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

Период работы прерывания при переполнении счетного регистра равен:

Tпереполнения = 1/(f sys / (2 * N * 65536))

Период работы прерывания при совпадении равен:

Tсовпадения = 1/(f_sys / (2 * n * (1 + OCR1A)))

В скетче установлен предделитель на 1024, значит:

Tпереполнения = 1/(32 000 000 / (2 * 1024 * 65536)) = 4,19424 с

Период работы прерывания при совпадении при OCR1A = 9999:

Tсовпадения = 1/(32 000 000 / (2 * 1024 * (1 + 9999))) = 0,64 с

Если например не использовать режим работы таймера прерывание и сбор при переполнении, то подключенный светодиод к D12 (через резистор 200 Ом), будет загораться при совпадении значений счетного регистра и регистра сравнения, а после переполнения счетного регистра и новом совпадении значений счетного регистра и регистра сравнения гаснуть.

void setup() {  

pinMode(12, OUTPUT);  

noInterrupts();  

TCNT1 = 0;  

TCCR1A = 0;  

TCCR1C = 0;  

byte n = 5;  

// clksys / 1 = 1  

// clksys / 8 = 2  

// clksys / 64 = 3  

// clksys / 256 = 4  

// clksys / 1024 = 5  

// [CS12:CS10]  

TCCR1B = n;  

OCR1A = 20000;// 0-65535  

TIMSK1 |= (1 << OCIE1A);

interrupts();

}

void loop() {}

ISR(TIMER1_COMPA_vect){  digitalWrite(12, !digitalRead(12));  }

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

Если например не использовать режим работы таймера при совпадении значений счетного регистра и регистра сравнения, то подключенный светодиод к D12 (через резистор 200 Ом), будет загораться при переполнении счетного регистра, а после гаснуть при новом переполнении счетного регистра.

void setup() {  

pinMode(12, OUTPUT);  

noInterrupts();  

TCNT1 = 0;  

TCCR1A = 0;  

TCCR1C = 0;

byte n = 5;  

// clksys / 1 = 1  

// clksys / 8 = 2  

// clksys / 64 = 3  

// clksys / 256 = 4  

// clksys / 1024 = 5  

// [CS12:CS10]  

TCCR1B = n;  

TIMSK1 |= (1 << TOIE1);

interrupts();

}

void loop() {}

ISR(TIMER1_OVF_vect){  digitalWrite(12, !digitalRead(12));  }

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

В нормальном режиме работы таймера можно использовать выход таймера, например если к D9 (через резистор 200 Ом) подключить светодиод, то при совпадении значений счетного регистра и регистра сравнения подключенный светодиод будет загораться и гаснуть при новом при совпадении значений счетного регистра и регистра сравнения.

Если установлен бит COM1A0 то состояние на выходе OC1A (D9) меняется на противоположное при совпадении.

void setup() {  

pinMode(D9, OUTPUT);  

noInterrupts();  

TCNT1 = 0;  

TCCR1A = 0;  

TCCR1C = 0;  

byte n = 5;  

// clksys / 1 = 1  

// clksys / 8 = 2  

// clksys / 64 = 3  

// clksys / 256 = 4  

// clksys / 1024 = 5  

// [CS12:CS10]  

TCCR1A = (1 << COM1A0);  

TCCR1B = n;  

OCR1A = 9999;

interrupts();

}

void loop() {}

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

Режим PWM (ШИМ)

Широтно-импульсная модуляция  (PWM) — процесс управления мощностью методом пульсирующего включения и выключения потребителя энергии.

Основной причиной применения ШИМ является стремление к повышению КПД при построении вторичных источников питания электронной аппаратуры и в других узлах, например, ШИМ используется для регулировки яркости подсветки LED-мониторов и дисплеев в телефонах, КПК и т. п.

По сути выходной PWM сигнал в LGT8F328P это импульсный сигнал с изменяемой длительностью импульсов. Если взять период следования импульсов за 100 %, то длительность импульсов может меняться от 0 до 100%, а так как Timer_1 16 бит, то заполнение длительности импульса периода следования импульса может меняться от 0 до 65535 значений, то есть от 0 до 100%.

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

Режим FPWM

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

Режим работы FPWM определяется несколькими регистрами, а в частности регистром захвата ICR1 и регистром сравнения OCR1A.

В регистр ICR1 записывается значение которое сравнивается с счетным регистром TCNT1 и при равенстве происходит изменение состояния  на выводе OC1A (D9), в данном случае появляется лог. 1, в регистре ICR1 указываем максимальное значение (зависит от разрядности).

В регистр OCR1A записывается значение которое сравнивается с счетным регистром TCNT1 и при равенстве происходит изменение состояния  на выводе OC1A (D9), в данном случае появляется лог. 0.

void setup() {  

pinMode(D9, OUTPUT);  

noInterrupts();  

TCNT1 = 0;  

TCCR1A = 0;  

TCCR1C = 0;  

byte n = 1;  

// clksys / 1 = 1  

// clksys / 8 = 2  

// clksys / 64 = 3  

// clksys / 256 = 4  

// clksys / 1024 = 5  

// [CS12:CS10]  

TCCR1A = (1 << COM1A1) | (1 << WGM11);  

TCCR1B = (1 << WGM13) | (1 << WGM12) | n;  

ICR1 = 65535;  

OCR1A = 5000;

interrupts();

}

void loop() {}

Бит COM1A1 делает активным выход OC1A (D9), а биты WGM11 WGM12 WGM13 активируют режим FPWM.

Частота PWM в этом режиме определяется:

Fpwm = f sys / (N * (1 + ICR1))

Если предделитель установлен на 1, а регистр ICR1 имеет значение 65535, то:

Fpwm = 32 000 000 / (1 * (1 + 65535)) = 488,28125 Hz

Аналогично можно использовать выход Timer_1 OC1B (D10), использование которого определяет бит COM1B1, при этом используется регистр сравнения OCR1B.

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

void setup() {  

pinMode(D10, OUTPUT);  

noInterrupts();  

TCNT1 = 0;  

TCCR1A = 0;  

TCCR1C = 0;  

byte n = 1;  

// clksys / 1 = 1  

// clksys / 8 = 2  

// clksys / 64 = 3  

// clksys / 256 = 4  

// clksys / 1024 = 5  

// [CS12:CS10]  

TCCR1A = (1 << COM1B1) | (1 << WGM11);  

TCCR1B = (1 << WGM13) | (1 << WGM12) | n;  

ICR1 = 65535;  

OCR1B = 1000;

interrupts();

}

void loop() {}

Так же в этом режиме PWM имеется возможность инверсии выходного сигнала. Биты COM1A1 COM1A0 определяют режим работы выходного сигнала.

LGT8F328P таймеры (Arduino) Arduino, Электроника, Программирование, Длиннопост

Читать дальше...

TECHNO BROTHER

1.7K поста12.5K подписчика

Добавить пост

Правила сообщества

1-Мы А-политическое сообщество. 2-Запрещено оскорбление: Администрации Пикабу, сообщества, участников сообщества а также родных, близких выше указанных.

3-Категорически запрещается разжигание межнациональной розни или действий, направленных на возбуждение национальной, расовой вражды, унижение национального достоинства, а также высказывания о превосходстве либо неполноценности пользователей по признаку их отношения к национальной принадлежности или политических взглядов. Мат - Нежелателен. Учитесь выражать мысли без матерщины