Таймер в PIC
В микроконтроллерах есть полезная вещь – таймер. Таймер можно использовать как счётчик или с его помощью формировать импульсы заданной длины (ШИМ). С использованием таймера можно, например, построить часы или генератор.
В микроконтроллера 16 семейства есть 3 таймера: TRM0, TRM1 и TRM2. Каждый из них больше подходит для определённого типа работы. Рассмотрим эти таймеры подробнее:
TRM0
- 8-битный таймер (считает от 0 до 255)
- тактируется от системной частоты или от внешнего источника
- считает по переднему или заднему фронту сигнала
- 8-битный предделитель
- прерывание генерируется при переполнении (при переходе от 255 к 0)
- таймер работает постоянно
Этот таймер можно использовать для генерации импульсов заданной длины или для подсчёта входящих импульсов.
Управление таймером осуществляется регистром OPTION_REG (OPTION в программе).
TRM1
- 16-битный таймер (0..65535)
- может тактироваться как от внешнего источника сигналов, так и от
- дополнительного часового кварца
- максимально предделитель — 1:8
- таймер считает только передние фронты сигнала
- таймер может использоваться модулем CCP
- таймер можно отключать
Применения аналогичные TMR0.
Управление таймером осуществляется регистром T1CON.
TRM2
- 8-битный таймер
- тактируется только от системной частоты
- предделитель 1:1 , 1:4 , 1:16
- таймер можно отключать
Этот таймер имеет другой принцип работы. Таймер считает импульсы от нуля до заданного PR2. После совпадения TRM2 и PR2 сигнал поступает на 4-битный постделитель и генерируется прерывание. Такая система позволяет генерировать частоты с минимальным шагом. Таймер может посылать сигналы на CCP в качестве базы тайминга ШИМа.
Управление таймером осуществляется регистром T2CON.
Управлением прерываниями осуществляется из регистра INTCON.
Пример
Перейдём к коду прошивки. В примере задействованы два счётчика TRM0 для счётчика входных импульсов и TRM1 для мигания 2-мя светодиодами.
Включим таймеры TRM0 для счётчика и TRM1 для мигания 2-мя светодиодами.
INTCON=0b11100000; // Настройка прерываний OPTION=0b00101000; // Настройка TMR0 T1CON =0b00110001; // Настройка TMR1 TMR1IE=1;
В основном коде программы только вывод значения счётчика на дисплей.
void main() { low_init(); // инициализация МК InitLCD(); // инициализация дисплея TMR0=0; // обнуляем таймер TMR0 LED=0; // обнуляем переменную отвечающею за светодиоды while(1==1) { IntToLCD(0,0,TMR0); // вывести на дисплей содержимое таймера delay(1000); // задержка } }
Основное же действие разворачивается в обработчике прерываний.
void interrupt isr(void) { if(T0IF) // при переполнение TMR0 { T0IF=0; // сбрасываем флаг о его переполнение } if(TMR1IF) // при переполнение TMR1 { LED++; // управление светодиодами if(LED>3) { LED=0; } PORTA=LED; TMR1IF=0; // сбрасываем флаг } }
В обработчике первого таймера TRM0: при его переполнение нечего полезного не происходит, только сбрасывается флаг переполнения. При переполнение второго таймера TRM1: светодиоды зажигаются по-новому (на них выводиться двоичный счётчик), и сбрасывается флаг переполнения второго таймера.
Ниже приведены фотография и видео работы таймеров из примера.
Работа таймеров
Alex_EXE | 19.04.2011 | Микроконтроллеры |
илья пишет 18.01.2014 в 22:04 #
в pic16f628a есть встроенный модуль ШИМ (CCP1) можете ли вы описать пример работы с ним для реализации на выводе цап и изменять на нем напряжение от 0 до 5 в
Alex_EXE пишет 19.01.2014 в 14:34 #
Ближайшее время по пикам обучающих материалов писать не собираюсь.
Chettus пишет 24.05.2014 в 23:28 #
2 Илья. Я могу сбросить свой пример на PIC16F887.
Александр пишет 27.02.2016 в 20:03 #
Алекс, если не секрет почему TRM а не TMR? никак не понимаю(
Alex_EXE пишет 02.03.2016 в 11:27 #
Видимо опечатка, позже поправлю. Спасибо, что заметили.
Alex пишет 19.09.2016 в 05:29 #
Здравствуйте
Объясните, пожалуйста
Если сбросить флаг переполнения таймера в начале программы прерывания, а потом ещё несколько команд написать, они будут выполняться? Просто иначе получается, что таймер опаздывает на время, которое требуется для выполнения этих команд