This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

8051 and power management

Hi,

I am trying to implement power management for 8051 using IDLE and STOP mode. COuple of questions:
a) Where should i place PCON |= 0x01; ? The example of keil doesn't really explain this. Should i create a timer and place this line in it ?
b) How do I implement STOP mode ? I used PCON |= 0x02; and placed it in external interrupt 1, but I am unsure how to save all the context (registers, ACC, SP etc) so that when I press the reset button, all these would be recovered, and to resume from previous execution ?
c) How to differiate between warm and cold reset ? The example doesn't seem to work for me.

Thanks all

  • a) Where should i place PCON |= 0x01; ? The example of keil doesn't really explain this. Should i create a timer and place this line in it ?
    do not idle in an ISR, you may get into a debugging nightmare re interrupt priorities etc.
    b) How do I implement STOP mode ? I used PCON |= 0x02; and placed it in external interrupt 1, but I am unsure how to save all the context (registers, ACC, SP etc) so that when I press the reset button, all these would be recovered, and to resume from previous execution ?
    warm reset will reset all registers and RAM will be kept; however, you need to modify startup.a51 to not clear it.
    c) How to differiate between warm and cold reset ? The example doesn't seem to work for me.
    modern derivatives such as the Philips P89C51Rx2 series have a bit you can use, older ('standard') derivatives do not. There are schemes that will work 99.5% of the time for those, but none that are absolutely safe so use a derivative with the bit.

  • "Where should i place PCON |= 0x01; ?"

    Place this line at the point in your program where you want execution to stop. When an interrupt occurs the ISR (if present) will be run then execution will continue from the instruction following the PCON|=0x01.

    I haven't used stop mode.

    Stefan

  • Indeed placing PCON |= 0x01 in isr crashes my program.

    Any guidelines when should a MCU goes to idle mode ? I can only think of an incident whether serial port is waiting to send or receive.... Any other situations that IDLE mode be helpful ?

  • In the code you can see, how I usually use the IDLE mode. The main() function waits, until an interrupt occurs. Each interrupt routine has its own bit flag, that is set by the ISR. In main() this flag is cleared and the required actions are performed.


    void main()
    {
    	Init_System();
    
    	for( ; ; )
    	{
    		// wait for an event
    		while( !b_PeriodicTimer &&
    			  !b_NewCommand )
    		{
    			PCON |= 0x01;
    		}
    
    		ServiceWatchdog();
    
    		if( b_NewCommand )
    		{
    			b_NewCommand = FALSE;
    			ProcessCommand();
    		}
    
    		if( b_PeriodicTimer )
    		{
    			b_PeriodicTimer = FALSE;
    			PerformPeriodicTasks();
    		}
    
    		UpdateSystemStatus();
    	}
    }
    

  • Something more about all said above. Always read Errata for chip used. Some ones require switch down to X1 mode before power-down (for example, AT89C51RD/ED2), another ones need with NOP as the first command of wake up; there are also chips which do not fetch first command correct and need with special workaround...
    Good days!

  • Thanks for your code sample.

    I am puzzled by how your code would work for complex program.

    For example, ProcessCommand(); would branch out of main, and within ProcessCommand();, there are more functions for getting user input and processing interrupts.

    In short do I have to implement something similar for each subprogram ?

    Thanks


  • I am puzzled by how your code would work for complex program. ...


    Of cause it depends on the stucture of your program, if this kind of solution is appropriate. But I found this approach very useful for many solutions.
    Most of the embedded modules, for that I wrote the firmware, work almost autonomous. The processing of a command usually requires no further interaction.

    E.g. a module that controls the temperature of a chemical reactor has a command, that allows to change the temperature set-point.
    The new set-point is part of the command message. If the set-point is in the valid range, the command is acknowledged and the set-point is changed, otherwise an error code is sent as answer.
    An interrupt from an ADC triggers the temperature control each time a new temperature reading is available. Eventually the current temperature and the deviation to the set-point are reported to somewhere, too.

    I hope this simple example helps you to understand, how this approach can be used.

    Regards,
    Tim