Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Power Management in PIC18F4520

Status
Not open for further replies.

Addeen

Newbie
Newbie level 1
Joined
Nov 18, 2020
Messages
1
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
16
I just started learning power management and I need to know, why INT0 is implemented, why void interrupt ISR(void) is implemented.
The code below will blink the LEDs for five times and enter into sleep mode. Upon an INT0 interrupt, the micro-controller resumes execution.

C:
// PIC18F4520 Configuration Bit Settings
#pragma config OSC = XT // Oscillator Selection bits (XT oscillator)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit
#pragma config WDT = OFF // Watchdog Timer Enable bit

#include <xc.h>
#include  <stdblib.h>
#define _XTAL_FREQ 4000000
#define SPEAKER PORTBbits.RB3

void interrupt ISR (void);
void main(void)
{
char i;
OSCCON = 0;
ADCON1 = 0x0F;           // Configure all ports as digital
TRISA = 0b11110000;      // Configure RA<3:0> as outputs (LEDs)
TRISB = 0b11110111;         // Configure RB3 as output (speaker)
// Set up for INT0 interrupt
  INTCONbits.GIE = 0;        // Disable global interrupt
INTCONbits.INT0IF=0;         // Clear INT0 interrupt flag
INTCON2bits.INTEDG0=1;   // Configure INT0 for rising edge trigger
INTCONbits.INT0IE=1;       // Enable INT0 interrupt
INTCONbits.GIE=1;       // Clear INT0 interrupt flag

while (1)
{
for (i=0;i<5;i++)
{
PORTA = 0b11111111;  // Turn on all LEDs
__delay_ms(300);
PORTA = 0b00000000;       // Turn off all LEDs
__delay_ms(300);
}
SLEEP();         // library function to execute sleep instruction
}
}
void interrupt ISR(void)
{
int x;
if (INTCONbits.INT0IF) // Check INT0 flag to confirm if INT0 interrupt trigger
{
for (x=0; x<3000; x++) // Sound the speaker
{
SPEAKER = 1;
_delay(500);
SPEAKER = 0;
_delay(500);
}
INTCONbits.INT0IF=0; // Clear interrupt flag
}
}
 
Last edited by a moderator:

The while(1) loop is a continuous loop, the (1) equates to always true so the loop has no end.
Note that after flashing the LED 5 times it reaches a SLEEP() macro. This suspends all further activity and effectively shuts the micro down.

The ISR is always active, it does nothing until an external signal, in this case a change on the INT0 pin is detected, note that this is a hardware operation so it is still active while the software is suspended by the SLEEP instruction.

When the ISR is triggered it toggles the pin assigned as 'SPEAKER' 3000 times to make a tone then clears the ISR flag so it can be 'armed' for future activation again. By breaking the SLEEP operation it resumes the while(1) loop again until it repeats the five flashes and goes back to sleep again.

Brian.
 
  • Like
Reactions: Addeen

    Addeen

    Points: 2
    Helpful Answer Positive Rating
While your code works and does exactly what you expect it to, I suggest that you look to revise it because it has delays in the ISR which is generally considered a 'bad thing' and can lead to problems in other situations.
In devices such as yours where you have either one or two interrupt levels (and you are using a device with 2 levels but configured to only use one of them), when an ISR is running then no mainline code (i.e. all of the code that isn't in the ISR) cannot run. The hardware will continue but if that also triggers an interrupt, it will not be processed until the ISR code completes. (Your MCU can have high and low priority interrupts where the high priority ISR can interrupt the low priority ISR but that is a more advanced concept and, if you are not clear on what is going on, can lead to further problems.)
Now your ISR will take about 3 seconds to run (1mSec in delays and 3000 times around the loop)which means that no other code can run for those 3 seconds. 3 seconds is an eternity for a microcontroller.
What you normally do in a situation like this is to have the ISR do whatever is needed quickly and in this case that means clear the interrupt flag and set a flag variable of your own, and then leave. In your main loop, you can check to see if your flag has been set and then process the speaker code if it has; remembering to clear your flag as well.
For simple code such as yours, perhaps put the speaker code after the sleep call.
Susan
 
  • Like
Reactions: Addeen

    Addeen

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top