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] Need help on Interrupt

Status
Not open for further replies.

SlickSteiner

Newbie level 5
Joined
Jan 6, 2012
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,331
I am a beginner at programming microcontrollers in C using MPLABX and HI-TECH C
I am having a problem with a code that I made where 4 LEDs will blink one after another, and when an Interrupt is detected it should stop at the position where the LED is on and blink 3 times.
The problem that I am encountering is when I service the interrupt, the LED doesnt blink.
Here is my code:
Code:
/*************************************************************************
 *Description: LED Flash Interrupt                                       *
 *                                                                       *
 * Services an Interrupt when the external interrupt is asserted         *
 *                                                                       *
 *                                                                       *
 * Four LEDs blinks in succession until an interrupt is asserted where   *
 * it will blink in the specified LED for three times, and resumes after *
 * ***********************************************************************
 * Pin Assignments:                                                      *
 *      BUTTON - RB0                                                     *
 *                                                                       *
 * **********************************************************************/

#include <htc.h>

/*CONFIGURATION*/
__CONFIG(FOSC_XT & CP_OFF & WDTE_OFF & PWRTE_ON);

#define _XTAL_FREQ 4000000              //Crystal in Hz

/*PIN ASSIGNMENTS*/
#define BUTTON RB0                      //BUTTON as RB0

/*GLOBAL VARIABLES*/
unsigned char sPORTB;                   //Shadow copy of PORTB
unsigned char store_LED = 1;            //Stores the LED value

/*FUNCTION PROTOTYPING*/
void init();

/*MAIN FUNCTION*/
void main()
{
    init();
    //Main Loop
    for(;;)
    {
        __delay_ms(500);                //Delay of 500ms
        sPORTB = (1<<store_LED);        //Turns on the LED on the position specified by store_LED
        store_LED++;                    //Increments the value of Store LED
        if(store_LED == 5)              //If store_LED is 5
        {
            store_LED = 1;              //RESET store_LED to 1
        }
        PORTB = sPORTB;                 //UPDATE PORTB
        sPORTB = ~(1<<store_LED);       //RESET the previous position of store_LED to 0
    }
}

void init()
{
    TRISB = 0b11100001;     //SET RB1 to RB4 as OUTPUTS
    PORTB = 0b00000000;     //SET PORTB to 0
    sPORTB = 0b00000000;    //SET Shadow of PORTB to 0

    /*CONFIGURE INTERRUPTS*/
    INTEDG = 0;             //Trigger on Falling Edge
    INTE = 1;               //ENABLE External Input
    ei();                   //ENABLE Global Interrupt
}

void interrupt isr(void)
{
    unsigned int led_count = 0;                 //led_count Variable
    INTF = 0;                                   //RESET Interrupt Flag
    for(led_count=0;led_count <3;led_count++)   //Repeat 3 times
    {
        __delay_ms(500);                        //Delay of 500ms
        sPORTB ^= (1<<store_LED);               //Toggles store_LED
    }
}
.

By the way, I am using the PIC16F84A microcontroller
 
Last edited:

You are not writing the value to PORT B in the interrupt?
 

I tried writing the value of PORTB in the interrupt, but it is not blinking properly :(.
Code:
void interrupt isr(void)
{
    unsigned int led_count = 0;                 //led_count Variable
    INTF = 0;                                   //RESET Interrupt Flag
    for(led_count=0;led_count <3;led_count++)   //Repeat 3 times
    {
        __delay_ms(500);                        //Delay of 500ms
        sPORTB ^= (1<<store_LED);               //Toggles store_LED
        PORTB = sPORTB;                         //Update PORTB
    }
}
 

It's not a good idea to call the delay routine from the interrupt.
You call it in the main loop, it could be interrupted during the delay function, so the delay function has to be a re-entrant function.

It might be a better plan to just set a flag in the interrupt, and poll the flag in the main routine. Then have a seperate function for the led blink.

For example, something like:

Code:
//global var

bool blink = false;
unsigned char blink_led = 0;

main()
  {
  for(;;)
    {
    if(blink == true)
      {
      blink_the_led(blink_led); 
      blink = false
      }
   }


 
void interrupt isr(void)
  {
  blink_led = (1<<store_LED);  
  blink = true;	
  INTF = 0; //RESET Interrupt Flag
  }
 
I tried doing what you said, and I notice a change :D. But, the blinking still wont work, instead I noticed that the variable blink_LED increments when I assert the ISR, thus making the light move from one LED to another.
Here is the code I modified:
Code:
/*************************************************************************
 *Description: LED Flash Interrupt                                       *
 *                                                                       *
 * Services an Interrupt when the external interrupt is asserted         *
 *                                                                       *
 *                                                                       *
 * Four LEDs blinks in succession until an interrupt is asserted where   *
 * it will blink in the specified LED for three times, and resumes after *
 * ***********************************************************************
 * Pin Assignments:                                                      *
 *      BUTTON - RB0                                                     *
 *                                                                       *
 * **********************************************************************/

#include <htc.h>

/*CONFIGURATION*/
__CONFIG(FOSC_XT & CP_OFF & WDTE_OFF & PWRTE_ON);

#define _XTAL_FREQ 4000000              //Crystal in Hz

/*PIN ASSIGNMENTS*/
#define BUTTON RB0                      //BUTTON as RB0

/*GLOBAL VARIABLES*/
unsigned char sPORTB;                   //Shadow copy of PORTB
unsigned char store_LED = 1;            //Stores the LED value
unsigned char blink_LED;
bit blink = 0;                          //Interrupt Flag (0 = OFF)
/*FUNCTION PROTOTYPING*/
void init();
void led_blink();

/*MAIN FUNCTION*/
void main()
{
   
    init();
    //Main Loop
    for(;;)
    {
        __delay_ms(500);                //Delay of 500ms
        sPORTB = (1<<store_LED);        //Turns on the LED on the position specified by store_LED
        store_LED++;                    //Increments the value of Store LED
        if(store_LED == 5)              //If store_LED is 5
        {
            store_LED = 1;              //RESET store_LED to 1
        }
        if(blink == 1)
        {
            led_blink();
        }
        PORTB = sPORTB;                 //UPDATE PORTB
        sPORTB = ~(1<<store_LED);       //RESET the previous position of store_LED to 0
    }
}

void init()
{
    TRISB = 0b11100001;     //SET RB1 to RB4 as OUTPUTS
    PORTB = 0b00000000;     //SET PORTB to 0
    sPORTB = 0b00000000;    //SET Shadow of PORTB to 0

    /*CONFIGURE INTERRUPTS*/
    INTEDG = 0;             //Trigger on Falling Edge
    INTE = 1;               //ENABLE External Input
    ei();                   //ENABLE Global Interrupt
}

void interrupt isr(void)
{
    unsigned int led_count = 0;                 //led_count Variable
    INTF = 0;                                   //RESET Interrupt Flag
    blink_LED = (1<<store_LED);
    blink = 1;
}

void led_blink()
{
    unsigned char blink_cnt;
    for(blink_cnt=0;blink_cnt<5;blink_cnt++)
    {
        __delay_ms(500);
        sPORTB ^= (0<<blink_LED);
        PORTB = sPORTB;
        blink = 0;
    }
}
 

Code:
void led_blink()
{
    unsigned char blink_cnt;
    for(blink_cnt=0;blink_cnt<5;blink_cnt++)
    {
        __delay_ms(500);
        sPORTB ^= (0<<blink_LED);  //Could this be a problem??? (1<<blink_LED);
        PORTB = sPORTB;
        blink = 0;
    }

Try using MPLAB SIM as the debugger. You can set breakpoints and step through the code to see what is going on.
Use the watch window to see the variables.
Set the interrupt flag in code to see the interrupt.
 

I have fixed my code :-D. Thank You for all the Help!
The solution that I found was to create a new variable to store the value of the store_LED variable before it increments, and to reset sPORTB to 0 when the interrupt is asserted.
Here is my code.
Code:
/*************************************************************************
 * Author: Melvin Sy                                                     *
 * ***********************************************************************
 * Description: LED Flash Interrupt                                      *
 *                                                                       *
 * Services an Interrupt when the external interrupt is asserted         *
 *                                                                       *
 * Four LEDs blinks in succession until an interrupt is asserted where   *
 * it will blink in the specified LED for three times, and resumes after *
 * ***********************************************************************
 * Pin Assignments:                                                      *
 * **********************************************************************/
#include <htc.h>

/*CONFIGURATION*/
__CONFIG(FOSC_XT & CP_OFF & WDTE_OFF & PWRTE_ON);

#define _XTAL_FREQ 4000000              //Crystal in Hz

/*GLOBAL VARIABLES*/
unsigned char sPORTB;                   //Shadow copy of PORTB
unsigned char store_LED = 1;            //Stores the LED value
unsigned char store_BLINK;              //Stores the most recent value of store_LED

/*FUNCTION PROTOTYPING*/
void init();
void led_blink();

/*MAIN FUNCTION*/
void main()
{
   
    init();
    //Main Loop
    for(;;)
    {
        __delay_ms(500);                //Delay of 500ms
        sPORTB = (1<<store_LED);        //Turns on the LED on the position specified by store_LED
        store_BLINK = store_LED;        //Update store_BLINK value
        store_LED++;                    //Increments the value of Store LED
        if(store_BLINK == 5)              //If store_LED is 5
        {
            store_LED = 1;              //RESET store_LED to 1
        }
        PORTB = sPORTB;                 //UPDATE PORTB
        sPORTB = ~(1<<store_LED);       //RESET the previous position of store_LED to 0
    }
}

void init()
{
    TRISB = 0b11000001;     //SET RB1 to RB4 as OUTPUTS
    PORTB = 0b00000000;     //SET PORTB to 0
    sPORTB = 0b00000000;    //SET Shadow of PORTB to 0

    /*CONFIGURE INTERRUPTS*/
    INTEDG = 0;             //Trigger on Falling Edge
    INTE = 1;               //ENABLE External Input
    ei();                   //ENABLE Global Interrupt
}

void interrupt isr(void)
{
    unsigned int led_count = 0;          //led_count Variable
    INTF = 0;                            //RESET Interrupt Flag
    led_blink();                         //Call Function
}

void led_blink()
{
    unsigned char blink_cnt;                    //Declare variable blink_cnt
    sPORTB = 0b00000000;                        //RESET sPORTB to 0
    for(blink_cnt=0;blink_cnt<10;blink_cnt++)   //Blink Loop
    {
        __delay_ms(500);                        //Delay of 500ms
        sPORTB ^= (1<<store_BLINK);             //Toggles the LED on the position specified by store_BLINK;
        PORTB = sPORTB;                         //Update PORTB
    }
}
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top