Fork me on GitHub

PICSim.js - сторожевой таймер и спящий режим

Сторожевой таймер (Watchdog Timer - «сторожевой пёс») в PIC микроконтроллерах не требует внешних компонентов и представляет из себя обычный счётчик, непрерывно тактируемый от автономного RC-генератора. Сторожевой таймер можно глобально включать/отключать в битах конфигурации #pragma config WDTE = OFF|ON - если включён WDTE = ON, то в случае переполнения счётчика обычно происходит аппаратный сброс микроконтроллера, хотя также возможен особый случай использования сторожевого таймера - чтобы вывести микроконтроллер из спящего режима.

Зачем нужен сторожевой таймер ? Программы в микроконтроллерах напрямую взаимодействуют с железом и иногда случаются внештатные ситуации, когда по тем или иным причинам программа может зависнуть - причиной тому может быть как аппаратный сбой, так и ошибка программиста. В таких случаях нужно идти и ручками выдергивать питание или нажимать кнопочку сброса. Альтернативой этому как раз и является использование сторожевого таймера, который сбросит микроконтроллер автоматически если что-то пошло не так.

hex | picsim.js

/*
  xc8 --chip=16f648A main.c
*/

#include <xc.h>
#include <stdint.h>

#pragma config WDTE = ON

int main() {

  // The WDT has a nominal time-out period of 18 ms (with no prescaler).
  // If longer time-out periods are desired, a postscaler with a division ratio
  // of up to 1:128 can be assigned to the WDT under
  // software control by writing to the OPTION register. Thus,
  // time-out periods up to 2.3 seconds can be realized

  OPTION_REGbits.PS0 = OPTION_REGbits.PS1 = OPTION_REGbits.PS2 = 1; // 1:128; 2.3 sec
  OPTION_REGbits.PSA = 1; // prescaler is assigned to watchdog

  // looks like STATUS [TO, PD] are not implemented in original PICSim - always 0
  PORTB = STATUS;
  PORTA = TRISB = TRISA = 0;

  RA0 = 0;
  for (uint16_t i = 333; --i;); // simple delay
  RA0 = 1;

  while(1) {
    // CLRWDT();
    // do something useful
  }

  return 0;
}

Минимальный период срабатывания сторожевого таймера у PIC16F648A микроконтроллера 18 миллисекунд, максимальный 0.018*128=2.304 секунды. Так как в данном примере программист забыл программно очищать счётчик сторожевого таймера специальной командой CLRWDT(); то через каждые 2.3 секунды микроконтроллер сбрасывается и в результате светодиод RA0 мигает. Если раскомментировать // CLRWDT(); светодиод RA0 конечно же будет светиться непрерывно. Причину сброса микроконтроллера по идее можно узнать по состоянию флагов TO, PD в регистре STATUS, хотя похоже в picsim это не реализовано.

screenshot

Что касается спящий режима, то он позволяет значительно снизить энергопотребление. Для перехода а спящий режим у PIC микроконтроллеров предусмотрена специальная команда SPEEP(), после которой тактирование микроконтроллера прекращаются, текущее состояние всех регистров в том числе и портов ввода-вывода сохраняется и потребление энергии сводится к минимуму - обычно единицы микроампер. Выйти из спящего режима можно либо по прерыванию либо при срабатывании сторожевого таймера.

hex | picsim.js

/*
  xc8 --chip=16f648A main.c
*/

#include <xc.h>
#include <stdint.h>

#pragma config WDTE = ON

int main() {

  OPTION_REGbits.PS1 = OPTION_REGbits.PS2 = 1;
  OPTION_REGbits.PS0 = 0; // 1:64; 1.152 sec
  OPTION_REGbits.PSA = 1; // prescaler is assigned to watchdog

  PORTB = TRISB = 0;

  uint8_t last_led = 0;

  while(1) {
    SLEEP();
    last_led <<= 1;
    if (!last_led) {
      last_led = 1;
    }
    PORTB = last_led;
  }

  return 0;
}

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

screenshot

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

Далее попробуем линейку PIC18 микроконтроллеров и начнём с символьного LCD дисплея на базе контроллера HD44780.

links

social