PIC12F675 se despierta inmediatamente del comando de suspensión

1

Estoy tratando de construir un controlador de energía para un dispositivo que funciona con batería. Elijo PIC12F675. La idea es poner la foto en modo de reposo. Despiértalo con el temporizador Watchdod aproximadamente cada segundo. Compruebe los estados de los pines, decida si desea encender o apagar. El código de decisión está funcionando como se esperaba. Pero el PIC no duerme. Parece que PIC salta la macro SLEEP (). Antes de hacer esta pregunta, hice una investigación profunda y probé todo lo que encontré. Así que aquí están las configuraciones:

                          ----------
                      Vdd |1      8| GND/VSS
  Dock test pin(out)  GP5 |2      7| GP0 (in) Batt Measure
  Power Fet Drive(out)GP4 |3      6| GP1 (in) Batt Measure reference voltage
  Charge Status  (in) GP3 |4      5| GP2 (in) Dock sense
                          ----------

Todos los pines son io. Sin cristal externo, sin reinicio. Sin pin flotante.

No observo ninguna condición de sueño, tampoco hay condición de reinicio.

La pregunta es: ¿qué estoy haciendo mal que el PIC12F675 no está durmiendo?

Plataforma de programación: MPLABX + XC8 (última versión-Gratis) + pickit3 Config.h

#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = ON       // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = ON      // Power-Up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

#define _XTAL_FREQ  4000000        // this is used by the __delay_ms(xx) and __delay_us(xx) functions

main.c

unsigned int Read_ADC_Value(void)
{
    unsigned int ADCValue;

    ADCON0bits.GO = 1;              // start conversion
    while (ADCON0bits.GO);          // wait for conversion to finish
    ADCValue = ADRESH << 8;         // get the 2 msbs of the result and rotate 8 bits to the left
    ADCValue = ADCValue + ADRESL;   // now add the low 8 bits of the resut into our return variable
    return (ADCValue);              // return the 10bit result in a single variable
}

unsigned int Check_Dock() {
    GPIO5 = HIGH;   
    __delay_ms(5);
    unsigned int result = GPIO2;
    GPIO5 = LOW;    
    return result;
}

unsigned int Read_Batt(){
    unsigned int adc=Read_ADC_Value();
    float voltage = ADCSTEP * adc * 200.0; 
    return (unsigned int)(voltage); 
}

void main(void) {

    //Configure Watchdog to approx 1 sec
    CLRWDT();
    OPTION_REGbits.PSA = 1; //postscaler is for wdt   
    OPTION_REGbits.PS = 0x110; //postscaler 1:64

    OPTION_REGbits.nGPPU = 0; //pullups enabled
    WPU = 0xff; //enable pullups 

    TRISIObits.TRISIO0 = INPUT;   //AN0-GPIO0 - input - analog okuma için pil değeri.   
    TRISIObits.TRISIO1 = INPUT;   //AN1 -Vref    
    ANS2=0; TRISIObits.TRISIO2 = INPUT;   //GP2 <- Dock sense low=docked high=undocked
    ANS3=0; TRISIObits.TRISIO3 = INPUT;   //Charge Status   -> GP3
    TRISIObits.TRISIO4 = INPUT;    
    TRISIObits.TRISIO5 = OUTPUT;  //Dock test pin   <- GP5
    GPIO5 = LOW; //do not output anything       

    //Setup analog
    ANSELbits.ANS0 = INPUT;       //analog input 0 is used 
    ADCON0bits.ADON = 1;          //adc is on
    ADCON0bits.CHS = 0x00;        //an0 is tied to the sampler
    ADCON0bits.VCFG = 1;          //1=>use vRref pin as voltage reference, 0=> use vdd
    ADCON0bits.ADFM = 0x01;       //ADC results are right-justifed
    ANSELbits.ADCS = 0x011;       //Conversion clock = FRC internal: measurement can take till 6usec

    INTCON = 0; //disable every interrupt
    PIE1=0;
    PIR1=0;
    INTCONbits.GIE = 0;

    //Program Loop
    while (1) {
        SLEEP();
        NOP();
        INTCONbits.GPIF=0;

        unsigned char sta = 0;
        if(Read_Batt() <= BATTLOWTHRESHOLD){
            //Batt low turn everything off
            sta++;
        }         

        unsigned int isCharging = GPIO3; //0:not charging; 1: charging;
        sta+=isCharging;

        unsigned int isnotDocked = Check_Dock();         
        if(isnotDocked) { //0:docked; 1:flying   
            NOP();
        }else{
            sta++;
        }

        if(sta) {
            //disable fet
            TRISIObits.TRISIO4 = INPUT; 
            WPU4=1; //enable port pullup
        } else {
            TRISIObits.TRISIO4 = OUTPUT; 
            GPIO4 = LOW; //enable fet
        }
    }//End of: Main loop
}
    
pregunta Mert Gülsoy

1 respuesta

7

Tienes un pequeño error tipográfico ;-)

OPTION_REGbits.PS = 0x110; //postscaler 1:64

Debería ser:

OPTION_REGbits.PS = 0b110; //postscaler 1:64
                     ^
                     |

Al configurarlo en 0x110, elegiste un prescaler 1: 1, lo que significa que el watchdog se activaría cada 18 ms de forma predeterminada.

    
respondido por el Roger Rowland

Lea otras preguntas en las etiquetas