Posted by: Claudio Carbone | 10 October 2011

Put a PIC32 to sleep

I’m working with these 32bit microcontrollers which are relatively new (Microchip started producing them around 2008), at least to me.
I’m fighting to gain as much knowledge as possible but they are so vast an architectural leap from 16 and 18 series MCUs, that the involved work is huge.
I’m studying them from multiple sides at once, which is difficult, but often there isn’t time to prepare a learning guide, lay out a path and follow it. Most times you’re forced to try shortcuts (not all of which are really so) and see what the outcome is.
In this process I fighted with the documentation (something Microchip seems to have banded: pic32 documentation plainly sucks), I fighted with the forums (they also seem to have dropped official support from the forums, mods are nowhere to be seen and users are left at themselves), I fighted with the hardware.

So I figured: why not sharing some of my newly acquired knowledge?

So here it is just one bit: how to put the cpu to sleep using the Change Notification module.

This module is a peripheral that can always run (even during sleep with primary oscillator disabled), it’s purpose is to notify (by interrupt) of changes on specific input pins. The pins that can work with these module are labeled CNnumber on the datasheets, so not any pin can be used for this purpose.
The board I’m using is an inexpensive SD demo board made by Tiertex, with three leds, a button, dual oscillator (primary and secondary for RTC) and microSD slot.

My demo uses two timers (the Core timer and Timer1) to blink two leds at two different rates.
The button is used to switch the Timer1 on and off, thus disabling one of the two blinking leds.
In order to put the MCU to sleep the two lines gotosleep= in the CN interrupt handler need be uncommented.
I suggest you run the demo and ensures everything is working (button correctly detected, timers halting and resuming).
Once everything is ok, you can uncomment the sleep lines.

The sleep command MUST be outside the issuing ISR.
In fact the actual sleep command, PowerSaveSleep(), is somewhere else.
That’s because the CN ISR is the same function that is called when entering as well as when exiting the sleep.
Since during sleep the mcu halts at the exact same instruction that puts it to sleep, if you put the sleep command in the ISR then the following ISR call, which should wake the cpu, would not be served because the code was halted inside the previous ISR.

Also keep in mind that the execution resumes at the exact same point it was halted.
So if you entered sleep by CN and plan to resume, for example, by RTC, when the RTC raises the IRQ the code would continue to execute the part of the CN ISR that remained after the sleep instruction, only after that the CPU would look for the RTC interrupt.

Hope this was clear and useful.

Here is the link -> Source Code



  1. After a few annoying hours I came across this post and you managed to clear up the issue I was having with one line:

    The sleep command MUST be outside the issuing ISR.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s


%d bloggers like this: