Авторизация


...

Кто на сайте?

Сейчас 57 гостей и ни одного зарегистрированного пользователя на сайте

Статистика

-Посетители : 26583
-Материалы : 210

Пользователь сайта продает...

  PIC18F25K22

Пользователь сайта покупает...

Программные таймеры

Автор: Alex Просмотров: 3623


Давайте разберём это на примере.
Что нам нужно ? Нам нужно создать переменную, которая будет счётчиком ,и флаг состояния таймера.
Можно объявить 2 переменных. Одна будет счётчик(например unsigned int), другая - типа bit. Но мы пойдём немного другим путём. Мы будем использовать старший бит переменной как бит состояния. Т.е. знак переменной у нас будет состоянием таймера. Но, тут есть один минус. Разрешение нашего таймера сократиться ровно в 2 раза, т.к. один бит будет занят. Т.е., если переменная = 2 байтам, то считать мы сможем только до 32767.

Создаём 2-х байтную знаковую переменную. Именно знаковую, т.к. знак у нас - состояние таймера.

 

  signed int volatile cnt;

Далее, нам необходимо создать обработчик прерываний от любого, имеющегося на "борту" МК, таймера.
Возьмём за основу 1-й таймер. Тактовая частота МК = 20Мгц. Таймер настраиваем на 1 мс.

Возьмём за основу 1-й таймер. Тактовая частота МК = 20Мгц. Таймер настраиваем на 1 мс.

  void interrupt _isr(void){
if(TMR1IF){      // Если событие от таймера
TMR1IF=0;           // Сбрасываем флаг события
TMR1-=5000;       // Переустанавливаем таймер на 5000 тактов (при 20Мгц - 1мс.).
}
}

Системные тики имеем. Теперь нам нужно их считать, т.е. сделать обработчик нашего программного таймера.
Сделаем проверку флага состояния, и, если таймер запущен, уменьшим счётчик на единицу.
Добавляем в ОП системного таймера такой код

  if(cnt < 0)     // Если таймер запущен
cnt++;             // Уменьшаем его счётчик на единицу.

Проверяем переменную на отрицательность (старший бит переменной). Тем самым, мы проверяем состояние таймера, и, если переменная отрицательна(<0) - уменьшаем счётчик таймера на еденицу.
Увеличение, как Вы заметили, переменной cnt - не ошибка. Счётчик у нас будет считать от -n до 0. Где n-это устанавливаемое значение таймера. Поэтому мы делаем инкремент переменной(это и есть уменьшение счётчика таймера на единицу).
Программный таймер и его обработка созданы. Осталось всё это применить на деле.
В процедуре main() инициализируем системный таймер(TMR1) и разрешаем прерывания.

  TMR1ON=1;         // Включить TMR1
TMR1IF=0;          // Сбросить флаг от TMR1
TMR1IE=1;          // Разрешить прерывания от TMR1
TMR1=-5000;      // Установить TMR1 на 5000 тактов/

PEIE=1;                // Разрешаем прерывания от перефирии
GIE=1;                 // и глобально

Далее зацикливаем программу

  while(1){              // Бесконечный цикл

}

В этом цикле установим программный таймер на 500 тиков и будем ждать окончания его счёта. По окончанию счёта, проинвертируем один из ПИНов порта.

  while(1){              // Бесконечный цикл
cnt = -500;          // Установка таймера на 500 тиков
while(cnt< 0)        // Ждём отсчёта таймера, т.б. когда он не будет < 0
continue;              //
RB0=!RB0;           // Инверсия RB0
}

И у нас получится мигалка с частотой в 1Гц
Скачать пример (49,56К)

Естественно, для мигания светодиода зацикливать программу, в ожидании окончания отсчёта таймера, глупо. Но мы можем не зацикливать программу, а просто проверять флаг состояния и мигать светодиодом. А программа, после проверки флага будет продолжать работать дальше.
Например, установим таймер, будем его проверять и продолжать выполнять программу дальше. Если проверка прошла, перезапустим таймер заново и проинвертируем пин светодиода.

  cnt = -500;                // Предустановка таймера на 500 тиков
while(1){                    // Бесконечный цикл
if(cnt >= 0){          // Если таймер отсчитал, т.е. значение счётчика не отрицательное
cnt = -500;       // Устанавливаем таймер заново на 500 тиков
RB0 = !RB0;      // и проинвертируем RB0
}
/*** Тут программа продолжает работу ****/
NOP();
NOP();
NOP();

/****************************************/
}


В итоге, результат получился как и в предыдущем примере, но программа не зациклена, она продолжает свою работу. А LED инвертируется, только когда отсчитает таймер. В том и прелесть программных таймеров, что они считают "в фоне", а проверяем их только по необходимости.
Скачать пример (48,97К)

Для справочки, кусочек дизасма:

  40: if(cnt>=0){          // Если таймер отсчитал, т.е. значение счётчика не отрицательное
033    1BA1 BTFSC  0x21, 0x7
034    283B GOTO  0x3b
41: cnt = -500;         // Устанавливаем таймер заново на 500 тиков
035    300C MOVLW 0xc
036    00A0 MOVWF 0x20
037    30FE MOVLW 0xfe
038    00A1 MOVWF 0x21
42: RB0=!RB0;       // и проинвертируем RB0
039    3001 MOVLW 0x1
03A    0686 XORWF 0x6, F

Заметьте, компилятор не делает никаких ужасных вычислений, он просто проверяет старший бит переменной.

 

  Используемый софт для примеров:
Компилятор HI-TECH PICC
Среда разработки MPlab
Отладчик Proteus

Обсуждение статьи тут

Случайные статьи....

Prev Next

Многофункциональное устройство для дачи

21-08-2011 Александр Милевский

Многофункциональное устройство для дачи

 Данное устройство нельзя назвать законченным. В настоящий момент хочу добиться функций необходимых именно мне. Это дальность связи между основным блоком и приемником. Блоки будут укомплектованы радиомодулями RFМ12BM с дальностью связи до 3 км. В настоящий момент тестирую каналы связи и...

Отладка программ .

24-04-2011 Super User

Отладка программ .

аже будучи  уверенным, что в написанной Вами программе нет ошибок, как правило, все равно в последующем приходиться  ее корректировать.  Да и невозможно учесть все «тонкости», будь ты хоть «супер» программист.  Сейчас трудно даже представить,  на сколько затянулся бы процесс разработки...

Управление ИК 5 каналов.

03-01-2012 Tamerlan

Управление ИК 5 каналов.

PIC12F675 Передатчик и приёмник ИК канал код RC5. Одно нажатие кнопки включает выход, второе нажатие выключает. По деталям транзистор можно использовать кт3102 ( я нашёл смд неизвестного происхождения работает), фотоприёмник какой был в магазине, он идёт со встроенным усилителем.В прошивке...

ПП стат. индикации 7-сиг. индикатора (1 порт, 2 знака).

06-06-2012 Super User

В этой подпрограмме показан один из способов статического подключения к микроконтроллеру  двух семисегментных индикаторов на один порт. В ПП не задействовано прерывание. Индикаторы применены с дешифратором  4 -7 (в семисегметный код).


Все права принадлежат ChipMK.ru. При копировании материала ссылка обязательна. 2011-2017 © ChipMK.ru

ChipMk.ru Яндекс.Метрика
PRCY.ru