{"id":3237,"date":"2011-08-06T18:32:20","date_gmt":"2011-08-06T22:32:20","guid":{"rendered":"http:\/\/embedded-lab.com\/blog\/?p=3237"},"modified":"2012-11-06T13:59:14","modified_gmt":"2012-11-06T18:59:14","slug":"lab-17-sleep-and-wake-pic-microcontrollers","status":"publish","type":"post","link":"https:\/\/embedded-lab.com\/blog\/lab-17-sleep-and-wake-pic-microcontrollers\/","title":{"rendered":"Lab 17: Sleep and Wake PIC microcontrollers"},"content":{"rendered":"<p>PIC microcontrollers&#8217; <strong>Sleep<\/strong> feature is an extremely useful mechanism to minimize power consumption in battery-powered applications. In Sleep mode, the normal operation of a PIC microcontroller is suspended and the clock oscillator is switched off. The power consumption is lowest in this state. The device can be woken up by an external reset, a watch-dog timer reset, an interrupt on INT0 pin, or port-on-change interrupt. In this experiment, we will discuss how to put a PIC microcontroller into Sleep mode and compare the current consumption during Sleep mode and the normal operation mode.<\/p>\n<div id=\"attachment_3374\" style=\"width: 570px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeTitle.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3374\" class=\"size-full wp-image-3374 \" title=\"SleepModeTitle\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeTitle.jpg\" alt=\"\" width=\"560\" height=\"323\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeTitle.jpg 560w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeTitle-550x317.jpg 550w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/a><p id=\"caption-attachment-3374\" class=\"wp-caption-text\">Understanding Sleep mode<\/p><\/div>\n<p><!--more--><\/p>\n<p><strong>Theory<\/strong><\/p>\n<p>In Sleep (Power-down) mode, a PIC microcontroller is placed in it\u2019s lowest current consumption state. The device goes into Sleep mode by executing a SLEEP instruction.\u00a0The device oscillator is turned off, so no system clocks are occurring in the device. However, the I\/O ports maintain the status they had before the SLEEP instruction was executed. Therefore, in order to minimize the power consumption in Sleep mode, the output ports must not be sourcing or sinking the current before going into Sleep mode. Besides, all the unused I\/O pins should be\u00a0configured as inputs and pulled either high (V<sub>DD<\/sub>) or low (V<sub>SS<\/sub>).<\/p>\n<p>Several events can make the device wake up from the sleep mode:<\/p>\n<p>1. Any device reset.<br \/>\n2. Watchdog Timer Wake-up (if WDT was enabled).<br \/>\n3. Any peripheral module which can set its interrupt flag while in sleep, such as:<\/p>\n<ul>\n<li>External INT pin<\/li>\n<li>Change on port pin<\/li>\n<li>Comparators<\/li>\n<li>A\/D conversion<\/li>\n<li>Timer1<\/li>\n<li>LCD<\/li>\n<li>SSP<\/li>\n<li>Capture, etc.<\/li>\n<\/ul>\n<p>The first event (device reset) will reset the device upon wake-up. However the latter two events will wake the\u00a0device and then resume program execution. When the SLEEP instruction is being executed, the next instruction (PC + 1) is pre-fetched, so that on wake-up the processor could execute the next instruction after the SLEEP command. For the device to wake-up through an interrupt event, the corresponding interrupt enable bit must be set (enabled). Wake-up is regardless of the state of the GIE bit. If the GIE bit is clear (disabled),\u00a0the device will just wake up from sleep and continues executing the program from the instruction right after the SLEEP command. If the GIE bit is set (enabled), the processor will execute the instruction after the SLEEP instruction and then branches to the interrupt address (0004h).\u00a0Therefore, if an interrupt is to be used just to wake up the PIC microcontroller, the GIE bit must be cleared before\u00a0the sleep instruction.<\/p>\n<p><em><strong>Watchdog Timer (WDT)<\/strong><\/em><\/p>\n<p>The Watchdog Timer or WDT is an independent timer with its own clock source. It provides a way for the PIC processor to recover from a software error that obstruct from program continuation, such as an endless loop. It is a free-running timer which, if allowed to overflow, will automatically reset the PIC. The WDT is enabled\/disabled by a device configuration bit, WDTE. If it is enabled, software execution may not disable this function. To prevent a time-out condition the watchdog must be reset periodically via software. In PIC16F628A (the PICMicro used in this experiment), the watchdog timer has a nominal time-out period of 18 ms, which can be extended up to 2.3 s by using a prescaler with a division ratio of up to 1:128. The prescaler rate is selected through PS0-PS2 bits of the OPTION register. Note that the PSA bit must also be set to assign the prescaler to WDT, otherwise it will be used by Timer0.<\/p>\n<div id=\"attachment_3382\" style=\"width: 587px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/OPTION_REG.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3382\" class=\"size-full wp-image-3382\" title=\"OPTION_REG\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/OPTION_REG.jpg\" alt=\"\" width=\"577\" height=\"569\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/OPTION_REG.jpg 577w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/OPTION_REG-550x542.jpg 550w\" sizes=\"auto, (max-width: 577px) 100vw, 577px\" \/><\/a><p id=\"caption-attachment-3382\" class=\"wp-caption-text\">Set PSA bit of OPTION register to assign prescaler to WDT<\/p><\/div>\n<p>In normal operation, if the watchdog timer is enabled, a WDT reset instruction (CLRWDT) is placed in the main loop of the program, where it would normally be expected to be executed often enough to prevent the WDT overflow. If the program hangs, and the CLRWDT instruction is not executed in time, the program counter is reset to 0000 so that the program restarts.<\/p>\n<p>However, if the PIC microcontroller is in Sleep mode, a WDT time-out will not reset the device, but just causes it to wake up (known as <em>WDT wake-up<\/em>) and the microcontroller continues program execution from the instruction following\u00a0the Sleep instruction.<\/p>\n<p><strong>Note:<\/strong> <span style=\"color: #800000;\"><em>When a Sleep instruction is executed, the watchdog timer is cleared. But the WDT will keep running if it has been enabled. <\/em><\/span><\/p>\n<p>Sleep mode is extremely useful in battery-powered data-loggers where the measurement samples are to be taken with some sampling interval. Between successive data samples, the microcontroller can be put into Sleep mode to prolong the battery life.<\/p>\n<p><strong>Experimental Setup<\/strong><\/p>\n<p>The setup for this experiment would be as shown in the circuit diagram below. The PIC16F628A microcontroller runs at 4.0 MHz clock using an external crystal. An LED is connected to RB0 port pin, which glows for .5 sec after every 4.3 second delay. During the first half of the delay (2.3 sec), the microcontroller is put to Sleep mode and a WDT time-out wakes it up. The remaining 2 sec delay is created through a software routine using NOP instruction. An ammeter is connected in series between the power supply voltage and the microconroller circuit to monitor the current consumption of the circuit. The MCLR pin is pulled high through a 10 K resistor.<\/p>\n<div id=\"attachment_3388\" style=\"width: 432px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeCkt.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3388\" class=\"size-full wp-image-3388\" title=\"SleepModeCkt\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeCkt.jpg\" alt=\"\" width=\"422\" height=\"311\" \/><\/a><p id=\"caption-attachment-3388\" class=\"wp-caption-text\">Circuit diagram for Sleep mode experiment<\/p><\/div>\n<div id=\"attachment_3373\" style=\"width: 580px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeSetup2.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3373\" class=\"size-full wp-image-3373 \" title=\"SleepModeSetup2\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeSetup2.jpg\" alt=\"\" width=\"570\" height=\"465\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeSetup2.jpg 570w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeSetup2-550x448.jpg 550w\" sizes=\"auto, (max-width: 570px) 100vw, 570px\" \/><\/a><p id=\"caption-attachment-3373\" class=\"wp-caption-text\">PIC setup on breadboard<\/p><\/div>\n<div id=\"attachment_3372\" style=\"width: 580px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeSetup.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3372\" class=\"size-full wp-image-3372\" title=\"SleepModeSetup\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeSetup.jpg\" alt=\"\" width=\"570\" height=\"451\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeSetup.jpg 570w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeSetup-550x435.jpg 550w\" sizes=\"auto, (max-width: 570px) 100vw, 570px\" \/><\/a><p id=\"caption-attachment-3372\" class=\"wp-caption-text\">Complete experimental setup<\/p><\/div>\n<p><strong>Software<\/strong><\/p>\n<p>The following program is written in C and compiled with mikroC Pro for PIC. The <strong>OPTION<\/strong> register is configured to assign prescaler to WDT. The prescaler ratio of 1:128 creates the WDT time-out duration of approximately 2.3 sec. An additional software delay of 2 sec is created using the\u00a0Delay_ms()\u00a0library routine. The amount of current consumption during both the delay intervals is displayed on the digital ammeter.<\/p>\n\n<div class=\"wp_syntax\"><table><tr><td class=\"code\"><pre class=\"c\" style=\"font-family:monospace;\"><span style=\"color: #808080; font-style: italic;\">\/* Project name:\n     Understanding sleep mode in PIC microcontrollers\n * Copyright:\n     (c) Rajendra Bhatt\n * Test configuration:\n     MCU:             PIC16F628A\n     Oscillator:      XT, 4.0000 MHz\n*\/<\/span>\n&nbsp;\nsbit LED at RB0_bit<span style=\"color: #339933;\">;<\/span>       <span style=\"color: #666666; font-style: italic;\">\/\/ LED is connected to PORTB.0<\/span>\n&nbsp;\n<span style=\"color: #993333;\">void<\/span> main<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\nTRISB <span style=\"color: #339933;\">=<\/span> <span style=\"color: #208080;\">0b00000000<\/span><span style=\"color: #339933;\">;<\/span>\nTRISA <span style=\"color: #339933;\">=<\/span> <span style=\"color: #208080;\">0b00100000<\/span><span style=\"color: #339933;\">;<\/span>\nLED <span style=\"color: #339933;\">=<\/span> <span style=\"color: #0000dd;\">0<\/span><span style=\"color: #339933;\">;<\/span>\nOPTION_REG <span style=\"color: #339933;\">=<\/span> <span style=\"color: #208080;\">0b00001111<\/span><span style=\"color: #339933;\">;<\/span>   <span style=\"color: #666666; font-style: italic;\">\/\/ Assign 1:128 prescaler to WDT<\/span>\n<span style=\"color: #b1b100;\">do<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n  asm sleep<span style=\"color: #339933;\">;<\/span>               <span style=\"color: #666666; font-style: italic;\">\/\/ Sleep mode, WDT is cleared,<\/span>\n                           <span style=\"color: #666666; font-style: italic;\">\/\/ and time out occurs at Approx. 2.3 Sec<\/span>\n                           <span style=\"color: #666666; font-style: italic;\">\/\/ Current is minimum in Sleep mode<\/span>\n  LED <span style=\"color: #339933;\">=<\/span> <span style=\"color: #0000dd;\">1<\/span><span style=\"color: #339933;\">;<\/span>                 <span style=\"color: #666666; font-style: italic;\">\/\/ After wake-up the LED is turned on<\/span>\n  Delay_ms<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #0000dd;\">500<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  LED <span style=\"color: #339933;\">=<\/span> <span style=\"color: #0000dd;\">0<\/span><span style=\"color: #339933;\">;<\/span>\n  asm CLRWDT<span style=\"color: #339933;\">;<\/span>              <span style=\"color: #666666; font-style: italic;\">\/\/ Clear WDT<\/span>\n  Delay_ms<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #0000dd;\">2000<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>          <span style=\"color: #666666; font-style: italic;\">\/\/ Measure current here and compare with Sleep mode<\/span>\n <span style=\"color: #009900;\">&#125;<\/span><span style=\"color: #b1b100;\">while<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #0000dd;\">1<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>                <span style=\"color: #666666; font-style: italic;\">\/\/ current<\/span>\n<span style=\"color: #009900;\">&#125;<\/span><\/pre><\/td><\/tr><\/table><\/div>\n\n<p>The watchdog timer should be enabled in the configuration registers. In mikroC, this can be done through the <em>Edit Project<\/em> window (see below).<\/p>\n<div id=\"attachment_3378\" style=\"width: 585px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/ProjectEdit.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3378\" class=\"size-full wp-image-3378\" title=\"ProjectEdit\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/ProjectEdit.jpg\" alt=\"\" width=\"575\" height=\"374\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/ProjectEdit.jpg 575w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/ProjectEdit-550x357.jpg 550w\" sizes=\"auto, (max-width: 575px) 100vw, 575px\" \/><\/a><p id=\"caption-attachment-3378\" class=\"wp-caption-text\">Enabling WDT from Project Edit window in mikroC Pro for PIC<\/p><\/div>\n<p><strong>Output<\/strong><\/p>\n<p>The current consumption during software delay routine (LED is off) was found as high as 940 \u00b5A, whereas the\u00a0Sleep mode current was only 43\u00a0\u00b5A. This is a significant reduction in PIC&#8217;s power consumption.<\/p>\n<div id=\"attachment_3369\" style=\"width: 580px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/NormalCurrent.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3369\" class=\"size-full wp-image-3369\" title=\"NormalCurrent\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/NormalCurrent.jpg\" alt=\"\" width=\"570\" height=\"454\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/NormalCurrent.jpg 570w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/NormalCurrent-550x438.jpg 550w\" sizes=\"auto, (max-width: 570px) 100vw, 570px\" \/><\/a><p id=\"caption-attachment-3369\" class=\"wp-caption-text\">Normal operation current<\/p><\/div>\n<div id=\"attachment_3371\" style=\"width: 590px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeCurrent.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3371\" class=\"size-full wp-image-3371\" title=\"SleepModeCurrent\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeCurrent.jpg\" alt=\"\" width=\"580\" height=\"470\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeCurrent.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/08\/SleepModeCurrent-550x445.jpg 550w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><p id=\"caption-attachment-3371\" class=\"wp-caption-text\">Sleep mode current<\/p><\/div>\n<p><strong>Summary<\/strong><\/p>\n<p>PIC microcontroller&#8217;s Sleep mode is a low current mode where the power consumption is minimum. It is extremely useful in battery-powered applications to prolong the battery life. If you are making a battery-powered data logger, it would be a smart move to put the microcontroller into Sleep mode during the time when it is not sampling the data value, and it can be waken-up by WDT time-out. In PIC16F628A microcontroller, the use of Sleep mode with WDT wake-up provides a maximum sleep duration of 2.3 sec. But if your data logger design requires a longer sampling interval between two successive data samples and you want to put the microcontroller into Sleep mode during most of this interval, you can use multiple SLEEP instructions in sequence. When the microcontroller wakes up from the first sleep by WDT time-out, it resumes normal operation and executes the next instruction. If it finds another SLEEP instruction, it will reset the WDT and go back to Sleep mode again, thus prolonging the sleep duration. The test circuit used in this experiment illustrated that the PIC current consumption is significantly lower (more than 20 times less) in Sleep mode than in normal execution mode.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>PIC microcontrollers&#8217; Sleep feature is an extremely useful mechanism to minimize power consumption in battery-powered applications. In Sleep mode, the normal operation of a PIC microcontroller is suspended and the clock oscillator is switched off. The power consumption is lowest in this state. The device can be woken up by an external reset, a watch-dog timer reset, an interrupt on INT0 pin, or port-on-change interrupt. In this experiment, we will discuss how to put a PIC microcontroller into Sleep mode and compare the current consumption during Sleep mode and the normal operation mode.<\/p>\n","protected":false},"author":1,"featured_media":3369,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32,29,38],"tags":[96,317,318],"class_list":["post-3237","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded-labs","category-embedded-lessons","category-pic-tutorials","tag-pic16f628a","tag-sleep-mode","tag-watch-dog-timer"],"_links":{"self":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/3237","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/comments?post=3237"}],"version-history":[{"count":37,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/3237\/revisions"}],"predecessor-version":[{"id":6284,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/3237\/revisions\/6284"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media\/3369"}],"wp:attachment":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media?parent=3237"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/categories?post=3237"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/tags?post=3237"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}