Search code examples
cembeddedpic

How to implement SLEEP mode on a PIC12F675 microcontroller?


I am working on a project where I need to conserve power (I am using two AA batteries) by putting a PIC12F675 microcontroller into low-energy consumption mode. Specifically, I want to set up the microcontroller to wake up every five hours, take a measurement, and then go back to sleep to conserve energy. Can anyone provide guidance on how to achieve this?

I am looking for advice on how to put the PIC12F675 into low-energy consumption mode, as well as how to set up a timer or interrupt to wake up the microcontroller every five hours. Any code examples or suggested approaches would be greatly appreciated.

I have a project that can perform the required tasks, but I want to reduce power consumption since it is a battery-powered system. To achieve this, I plan to implement sleep mode and watchdog timer. However, I am new to programming microcontrollers and have not been able to find any guidance on the internet. I would appreciate any advice on how to use sleep mode and watchdog timer for power saving purposes, or any recommended resources for beginners in microcontroller programming.

EDIT: I have already implemented the SLEEP method with the following code:

#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 disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#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 = OFF      // Brown-out Detect Enable bit (BOD disabled)
#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)

// X8 compiler header include
#include <xc.h>
#define _XTAL_FREQ 4000000

void main(void) {
    // Clear the WDT
    CLRWDT();
    
    // Enable interrupts
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;
    
    // Setup GPIO pin
    TRISIO0 = 0;
    
    while(1) {
        SLEEP();
        // Main program loop
        GPIO0 = 1;
        __delay_ms(1000);
        GPIO0 = 0;
        for(int i = 0; i<7826; i++){
            SLEEP();
        }
        // Clear the WDT periodically
        CLRWDT();
    }
}

Is there any way to modify this code to further improve battery life?


Solution

  • I would start simple: Use a Testboard where you can control a LED with a GPIO. Make sure you can control the LED with your code, with something like a loop that just toggles the LED with a short pause (to check if your code runs, LED pin is correct, Pin is set as output, ...). After you are sure you can control the LED, you can set up the WDT

    After you set up the WDT and go to sleep in the main loop, toggle the LED, go to sleep again. The WDT should be work just fine once setup, as long as you return to sleep fast enough.

    #include <xc.h>
    
    void main(void)
    {
      //Put to code to setup GPIOs here
      //Put to code to setup WDT here
      while(1)
      {
        SLEEP();
        //Put code to toggle LED here
      }
    }
    

    After you have that, you put the SLEEP() macro / instruction in a for loop with a counter of 7826 (well, a bit lower till you are sure everything else works as testing with such a long delay is annoying). Please keep in mind that the WDT timer source is far from precise, it has a huge tolerance. That also means your 5h will be of. You could use a RTC if you need higher precision, but then you don't need the WDT but can use a alarm function of the RTC.