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.

interrupt handling using pic16f877a

Status
Not open for further replies.

Rackie

Newbie level 5
Joined
Feb 22, 2012
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,332
Hi Tahmid,

I am using mickoC and proteus for simulation.
Please tell me some advices regarding the problem of this code.
This code is for our traffic light project and I've got a problem with the push button(which is the interrupt), it won't work.



Code:
int j=5;
 int i=0;
 int count = 0;


void interrupt(void)
{
    for(i=0;i<5;i++)
                     {
                     PORTA = 0xFF;
                     PORTC = 0x00;
                     PORTD = 0x00;
                     Delay_ms(1000);
                     PORTC = 0x0F;
                     PORTD = 0xF0;
                     Delay_ms(1000);
                     count = count + 1;
                     }
                     PORTA = 0x00;
                     PORTC = 0xF0;
                     PORTD = 0x0F;

                     Delay_ms(5000);

    for(j=5;j<10;j++)
                     {
                     PORTA = 0xFF;
                     PORTC = 0x00;
                     PORTD = 0x00;
                     Delay_ms(1000);
                     PORTC = 0xF0;
                     PORTD = 0x0F;
                     Delay_ms(1000);
                     count = count + 1;
                     }

                     PORTA = 0x00;
                     PORTC = 0x0F;
                     PORTD = 0xF0;
    INTCON.INTF = 0; //You HAVE to clear interrupt flag
}



void main() {

  INTCON.GIE = 1; //Enable Global Interrupt
  INTCON.INTE = 1; //Enable RB0/INT external Interrupt
  INTCON.PEIE = 0; //Disable all unmasked peripheral interrupt
  OPTION_REG.INTEDG = 1; //Interrupt on rising edge
   
  TRISB = 0xFF;         //making portB as input
  TRISC = 0x00;        // making portC as output
  TRISD = 0x00;        // making portD as output
  TRISA = 0x00;       // making portA as output
  
  ADCON1 = 7; //Disable ADC so that PORTA can be used for digital purpose
  CMCON = 7; //Disable comparator
  
  PORTC = 0x0F;        // initially the red light is on for pedestrian
  PORTD = 0xF0;       //initially the green light is on for vehicle
  PORTA = 0x00;

}


Thanks in advance...
 
Last edited by a moderator:

At the end of the code, add this line before the last }
Code:
while(1);

I see that the interrupt works. One thing that should be changed is your code sequence. In the interrupt only a 'flag' should be set and all other processing should be done in the main program. You're wasting 25 seconds in the interrupt. In this code, the only problem this creates is that the microcontroller won't react to the button press within this 25 seconds.

How did you connect the button? You should pull down RB0 with a 10k resistor and connect the switch between the pin and +5V. Then, the interrupt occurs when the switch is pressed. You could also connect a pull up resistor from RB0 and connect the switch between the pin and ground. In this case, the interrupt occurs when the switch is released.

Hope this helps.
Tahmid.
 

As Tahmid said, don't put delay on interrupt. Do interrupt as short as possible.
 

I connect the button in between the +5v and the pin. What do you mean by "only a flag should be set in the interrupt"?

---------- Post added at 10:20 ---------- Previous post was at 10:19 ----------

I try not to put delay in the interrupt but still doesn't work.

---------- Post added at 10:49 ---------- Previous post was at 10:20 ----------

Can you please give me an example code for handling interrupt? so that i could base my code on your example...
 

While your code should be improved, it does work. You can use it for testing. Since you connected a switch between RB0 and +5V, you should connect a 10k resistor between RB0 and ground.

You should connect all VDD and VSS to +5V and ground respectively.

You have to pull-up the MCLR pin with a resistor. You can use 10k resistor.

Did you connect the oscillator? PIC16F877A doesn't have an internal oscillator, so you need to connect an oscillator. Commonly crystal oscillators are used between OSC1 and OSC2. Capacitors (around 12-22pF) are used from OSC1 and OSC2 to ground.

You should check your configuration bits. Eg, check if watch dog timer is disabled, if correct oscillator type is used, etc.

Hope this helps.
Tahmid.
 
  • Like
Reactions: Rackie

    Rackie

    Points: 2
    Helpful Answer Positive Rating
how to connect the pull up resistor to the MCLR? Resistor in between the pin and the ground or a resistor in between the pin and the +5v?

---------- Post added at 15:33 ---------- Previous post was at 15:15 ----------

My program and simulation is now working. Thank you so much for your help and great advises. :)
 

how to connect the pull up resistor to the MCLR? Resistor in between the pin and the ground or a resistor in between the pin and the +5v?

You want to pull the MCLR pin high, so connect a 10KΩ resistor from the MCLR pin to +5V.

BigDog
 
  • Like
Reactions: Rackie

    Rackie

    Points: 2
    Helpful Answer Positive Rating
I have a question, why is it that RA4 won't turn to 1 when i turn the PortA into 1 or high?
 

I have a question, why is it that RA4 won't turn to 1 when i turn the PortA into 1 or high?

RA4 is when configured as an output pin, is an open-drain type.

An open-drain output does not behave like the other output pins, effectively they can only sink current, not source current.


Open-drain Outputs on the PIC

One pin, RA4, is different; it is configured as an open drain MOSFET.
When set to low, it performs identically with the other pin architectures.
However, when set to high, there is no internal connection with VDD and
hence it will not directly source voltage. If it’s necessary to use RA4 as a
sourcing output pin, you can add an external “pull-up” resistor, typically in
the range of 470 ohms–4.7K ohms. The sourced current then comes from
the pull-up resistor. Unlike all other pins that cannot exceed VDD, RA4’s
open drain is rated to 12 volts.



BigDog
 
  • Like
Reactions: Rackie

    V

    Points: 2
    Helpful Answer Positive Rating

    Rackie

    Points: 2
    Helpful Answer Positive Rating
RA4 is when configured as an output pin, is an open-drain type.

An open-drain output does not behave like the other output pins, effectively they can only sink current, not source current.


Open-drain Outputs on the PIC





BigDog

These links should help Rackie grasp the concept.

I would just like to point out that there is a mistake in page 2 of the 2nd link (the PDF document). The 1st diagram in that page shows the "totem-pole" output stage. However, the drain and source of the PMOS are reversed. Source should be connected to VDD and drain to I/O_pin.

Hope this helps.
Tahmid.
 

    V

    Points: 2
    Helpful Answer Positive Rating
Guys, thanks again for your help and great advises. :)
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top