До сих пор я работал со многими другими микроконтроллерами, но не с семейством PIC. У меня проблемы с выходом из спящего режима с помощью сторожевого таймера на PIC10F200. Я программирую его на C, используя MPLAB X IDE v2.35. Все функции и макросы являются частью базовых библиотек микрочипа для процессора.
Вот минимальный пример моей проблемы:
#include <xc.h>
#pragma config CP = OFF // Code protection off
#pragma config MCLRE = OFF // GP3/MCLR pin fuction is digital I/O
#pragma config WDTE = ON // Watchdog Timer enabled
#define _XTAL_FREQ 4000000
void main(void) {
OPTION = 0 | nGPWU | nGPPU & ~T0CS & ~T0SE | PSA | PS2 | PS1 | PS0; // bits: 7: no wake-up on pin change; 6: no weak pullups; 5: internal clock; 4: incremnt low to high; 3: prescale on wdt (Timer0 if cleared); 2-0: clock division by 128
TRISGPIO = 0b00000000; // set all to output
while(1) {
GP0 = 1; GP1 = 1; GP2 = 1; SLEEP(); // set all high and sleep a bit
GP0 = 0; GP1 = 0; GP2 = 0; SLEEP(); // set all low and sleep a bit
}
}
По сути, это классический пример переключателя (мигающего светодиода) с использованием сторожевого таймера. Только штифты все время высокие. Что я сделал не так?
Ответ, наконец, пришел ко мне в виде Говардлонга. Сторожевой таймер действительно вызывает сброс каждый раз при входе в спящий режим. Однако можно сохранить переменные между сбросами после сна, используя persistent
ключевое слово в объявлении переменной.
Загвоздка в том, что таким образом переменная не может быть инициализирована обычным способом. Чтобы присвоить ему начальное значение, лучше всего обнаружить сброс при включении питания и инициализировать его исключительно после сброса. Его инициализация обычно приводит к проблеме типа курицы и яйца, когда вы хотите сохранить значение, но установить его на очень сброшенном уровне. Обратите внимание, что некоторые регистры также сбрасываются при сбросе WDT, и поэтому их необходимо устанавливать каждый раз!
Вот пример:
#include <xc.h>
#include <stdbool.h>
#pragma config CP = OFF // Code protection off
#pragma config MCLRE = OFF // Master Clear Enable (GP3/MCLR pin fuction is digital I/O, MCLR internally tied to VDD)
#pragma config WDTE = ON // Watchdog Timer enabled
#define _XTAL_FREQ 40000000
static persistent bool _bState; // Persistent so the C startup code doesn't initialise
void main(void) {
// Check STATUS bits for type of reset
if ( ! ( GPWUF==0 && nPD==0 && nTO==0 ) ) {
// NOT a WDT wakeup from sleep, so treat as a power on reset
_bState=false;
OSCCALbits.FOSC4=0;
}
// These SFRs must be re-written after every reset
OPTION = 0b11001100; // WDT is div-by-32 prescaled
TRISGPIO = 0b1011; // GP2 output
GP2=_bState;
_bState=!_bState;
SLEEP();
}
Олин Латроп
кон-ф-использование
ткросли
кон-ф-использование
Ложка