© Armstrong Subero 2018

Armstrong Subero, Programming PIC Microcontrollers with XC8, https://doi.org/10.1007/978-1-4842-3273-6_14

14. Watchdog Timer and Low Power

Armstrong Subero

(1)Moruga, Trinidad and Tobago

Low Power 8-Bit vs 32-Bit

One cannot write a book on 8-bit microcontrollers without writing a little about low power. The argument has always been that 8-bit microcontrollers are superior to 32-bit ones in relation to low power. The reason is simple. A 32-bit microcontroller has more transistors, thus it requires more power to work. The argument for the 32-bit microcontroller is that if it is a computationally intensive task, then the 32-bit microcontroller would have an advantage, as it will take less time to do the processing. I say that you don’t need to use a machete to peel an orange. Yes, it will get the job done, but it is not the right tool for the task—in fact, it is over-engineering. Being a good embedded systems designer means using the right tool for the task. Problem solving involves applying the most relevant tool for the task to the problem at hand. In many instances, we do not need the power of a 32-bit microcontroller and in such cases using an 8-bit microcontroller is the logical choice.

The PIC® microcontroller has Microchip’s Extreme Low Power (XLP) technology built-in. What this means is that there are modes on the PIC® microcontroller that allow it to enter a very low power state.

Sleep Mode

The PIC® microcontroller can be put into sleep mode by using the SLEEP instruction. When this happens, the microcontroller enters a low power mode and conserves power. We will write an application that utilizes the SLEEP instruction of the PIC16F1717 (see Listing 14-1). In this application, the microcontroller will turn an LED on for five seconds, and then go to sleep. The microcontroller will then be woken up by using an external interrupt on PINB0.

By waking up the microcontroller only when we want it to perform some function and then putting it back to sleep, we can reduce power consumption. This is important in cases where devices are battery powered. A remote control is a good application of this, since the user only uses it when he wants to turn something on or off and then puts it back down. In such cases, it is not feasible to keep the microcontroller energized, and putting the microcontroller into sleep and then having it turn on when the user pushes a button will save a considerable amount of power.

Using the Sleep function is not limited only to battery-powered devices. Another application of this circuit is in devices where there is an ecofriendly button. You too can make ecofriendly devices by having a device go into sleep mode after a certain period of inactivity. For example, after someone uses a printer, it may be unnecessary to have it running and consuming power. The printer can be made ecofriendly by powering down after a certain amount of time, which is done via timers that you already know about. The printer can then be turned on again using the ecofriendly button.

Listing 14-1 Sleep Demonstration
/*                
* File: Main.c
* Author: Armstrong Subero
* PIC: 16F1717 w/Int OSC @ 16MHz, 5v
* Program: 08_Sleep
* Compiler: XC8 (v1.38, MPLAX X v3.40)
* Program Version: 1.0
*
*
* Program Description: This demonstrates sleep mode on a PIC16F1717 using
* an external interrupt to wake from sleep mode
*
* Hardware Description: An LED is connected via a 10k resistor to PIN D1 and
* another LED is connected to PIN D2 and a switch is
* connected to PIN B0
*
* Created November 4th, 2016, 8:43 PM
*/


/*******************************************************************************
*Includes and defines
******************************************************************************/


#include "16F1717_Internal.h"

/*******************************************************************************
* Function: void initMain()
*
* Returns: Nothing
*
* Description: Contains initializations for main
*
* Usage: initMain()
******************************************************************************/


void initMain(){
// Run at 16 MHz
internal_16();


////////////////////////
/// Configure Ports
////////////////////////


// Set PIN D1 as output
TRISDbits.TRISD1 = 0;
TRISDbits.TRISD2 = 0;


// Turn off LED
LATDbits.LATD1 = 0;


// Set PIN B0 as input
TRISBbits.TRISB0 = 1;


// Configure ANSELB0
ANSELBbits.ANSB0 = 0;


// unlock PPS
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCK = 0x00;


// Enable weak-pullups global
OPTION_REGbits.nWPUEN = 0;


// Enable weak-pullup on PINB0
WPUBbits.WPUB0 = 1;


/////////////////////////
/// Configure Interrupts
////////////////////////


// Set Interrupt pin to pin B0
INTPPSbits.INTPPS = 0b01000;


// lock   PPS
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCK = 0x01;


// Trigger on falling edge
OPTION_REGbits.INTEDG = 0;


// Clear external interrupt flag
INTCONbits.INTF = 0;


//  Enable external interrupt
INTCONbits.INTE = 1;


// Enable global interrupt
ei();
}


/*******************************************************************************
* Function: Main
*
* Returns: Nothing
*
* Description: Program entry point
******************************************************************************/


void main(void) {
initMain();


int x;
while(1){


// Turn LED on for 5 seconds
LATDbits.LATD1 = 1;
__delay_ms(5000);


LATDbits.LATD1 = 0;

// Sleep
SLEEP();
}


return;

}

/*******************************************************************************
* Function: void interrupt isr(void)
*
* Returns: Nothing
*
* Description: Interrupt triggered on pushbutton press
******************************************************************************/


void interrupt isr(void){
// Clear interrupt flag
INTCONbits.INTF = 0;


// Toggle led
LATDbits.LATD2 = ~LATDbits.LATD2;
}

Watchdog Timer

The watchdog timer (WDT) is a type of timer onboard PIC® microcontrollers that periodically reset the device. What this means is that the watchdog timer, like any other timer, will count a particular period of time. When the CLRWDT (clear watchdog timer) command is issued, the watchdog timer will not reset the microcontroller. If a certain amount of time passes as determined by the user, and the WDT is not cleared, then the device will be reset.

The WDT is very important for systems that are inaccessible or are very difficult for a person to get to in case of a malfunction. For example, in space applications it would be impossible for a human to interact with a robot that is exploring the surface of a planet or the moon. In such cases, the onus is on the device to reset itself to ensure continual operation.

It is important to note that improper use of the watchdog timer can be the source of a lot of system bugs. For example, if you use another timer to reset the watchdog timer, the system will not reset as expected on failure, as the other timers will run independent of the CPU.

It is also important, when designing with the watchdog timer, to set the interval at which the timer resets to the shortest possible value. This will ensure that your system is back to proper operation as soon as possible.

The code example in Listing 14-2 shows how we use the watchdog timer. It is very similar to the sleep example, except we use the WDT to break the microcontroller out of an infinite while loop. To prove that the program is working, a heartbeat LED flashes and an external interrupt can be used to flash the WDT LED. The watchdog timer runs in the background and, when it is reset, it turns on another LED.

Listing 14-2 WDT Demonstration
/*                
* File: Main.c
* Author: Armstrong Subero
* PIC: 16F1717 w/Int OSC @ 16MHz, 5v
* Program: 09_Watchdog_Timer
* Compiler: XC8 (v1.38, MPLAX X v3.40)
* Program Version: 1.0
*
*
* Program Description: This demonstrates using the watchdog timer on a
* PIC16F1717 to break out of an infinite loop
*
*
* Hardware Description: An LED is connected via a 10k resistor to PIN D1 and
* another LED is connected to PIN D2 and a switch is
* connected to PIN B0
*
* Created November 4th, 2016, 9:04 PM
*/


/*******************************************************************************
*Includes and defines
******************************************************************************/


#include "16F1717_Internal.h"

/*******************************************************************************
* Function: void initMain()
*
* Returns: Nothing
*
* Description: Contains initializations for main
*
* Usage: initMain()
******************************************************************************/


void initMain(){
// Run at 16 MHz
internal_16();


////////////////////////
/// Configure Ports
////////////////////////


// Set PIN D1 as output
TRISDbits.TRISD1 = 0;
TRISDbits.TRISD2 = 0;


// Turn off LED
LATDbits.LATD1 = 0;


// Set PIN B0 as input
TRISBbits.TRISB0 = 1;


// Configure ANSELB0
ANSELBbits.ANSB0 = 0;


// unlock PPS
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCK = 0x00;


// Enable weak-pullups global
OPTION_REGbits.nWPUEN = 0;


// Enable weak-pullup on PINB0
WPUBbits.WPUB0 = 1;


/////////////////////////
/// Configure Interrupts
////////////////////////


// Set Interrupt pin to pin B0
INTPPSbits.INTPPS = 0b01000;


// lock   PPS
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCK = 0x01;


// Trigger on falling edge
OPTION_REGbits.INTEDG = 0;


// Clear external interrupt flag
INTCONbits.INTF = 0;


//  Enable external interrupt
INTCONbits.INTE = 1;


// Enable global interrupt
ei();


//////////////////////////////////
// Configure watchdog timer
//////////////////////////////////


// Set watchdog timeout for 2 seconds (prescale = 65536)
WDTCONbits.WDTPS = 0b01011;
}


/*******************************************************************************
* Function: Main
*
* Returns: Nothing
*
* Description: Program entry point
******************************************************************************/


void main(void) {
initMain();


int x;
while(1){


// If WDT timeout occurred turn on error LED
if (!STATUSbits.nTO){
}


// flash heartbeat LED
LATDbits.LATD2 = 1;
__delay_ms(1000);
LATDbits.LATD2 = 0;


for(;;){
// infinite loop
}


}

return;

}

/*******************************************************************************
* Function: void interrupt isr(void)
*
* Returns: Nothing
*
* Description: Interrupt triggered on pushbutton press
******************************************************************************/


void interrupt isr(void){
// Clear interrupt flag
INTCONbits.INTF = 0;


// Toggle led
LATDbits.LATD2 = ~LATDbits.LATD2;
}

Other Ways to Conserve Power

In this section, we look at other ways to conserve power on PIC® microcontrollers. We take several steps to reduce power consumption. We look at three universally applicable ways to reduce power consumption of embedded devices. These three methods are tried and true and are guaranteed to lower power consumption. In fact, the first two methods can also be applied to general-purpose processors as well. Many people use over-clocking, under-clocking, and under-voltage to reduce power consumption, usually with relatively little performance losses.

Reduce the Clock Frequency

To reduce the power consumption on the microcontroller, consider running the microcontroller at 31kHz. Running the device at such low power reduces power consumption for tasks that are not computationally intensive. If a particular application requires a lot of CPU power, then running it at a low clock speed may actually be counterproductive since it will take a long time to complete its task and thus will be on for longer. It is an art to find the balance between computational speed and power consumption. Generally, however, the lower the clock speed, the lower the power consumption.

Reduce the Operating Voltage

Another way to reduce the power consumption on the microcontroller is to reduce the power from the usual 5 volts to 3.3 volts. That way, the microcontroller consumes less power as the voltage is lower. The disadvantage is that if your system has sensors that run at a higher voltage, you may need to add logic-level converters, which increases the design complexity.

Power External Devices from I/O Lines

If the power consumption of the device is less than the maximum the microcontroller can source, it’s best to drive the devices directly from the microcontroller. This method reduces power consumption; however, it is at the tradeoff of utilizing I/O pins.

Conclusion

This chapter looked at specific ways to reduce power consumption on the PIC® microcontroller, including using sleep mode as well as using the watchdog timer.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.13.180