Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC18F ISR

Status
Not open for further replies.

adrianvon

Member
Hi all,

I am trying to use the external interrupt of an 18f microcontroller. I want the program to operate as follow:

Turn LED connected to port D.0 OFF
Turn LED connected to port D.1 ON

If external interrupt INT0 is activated, invert the LEDs from on to off

Can someone tell me what is wrong with the ISR code below please? I did debug the program and it remains looping in the main function no matter if the interrupt is active of not.

Code:
#pragma code main = 0x00
#pragma code Interrupt_HIGHpriority = 0x08
#pragma Interrupt_HIGHpriority

void Interrupt_HIGHpriority(void);


void main(void)
{
  TRISBbits.TRISB0 = 1;

  TRISDbits.TRISD0 = 0;
  TRISDbits.TRISD1 = 0;

  INTCON = 0;          
  RCON = 0;

  INTCONbits.INT0IF   = 0;
  RCONbits.IPEN       = 0;
  INTCONbits.GIE      = 1;
  INTCONbits.INT0IE   = 1;
  INTCON2bits.INTEDG0 = 0;

while(1)
{
   LATDbits.LATD0 = 0;
   LATDbits.LATD1 = 1;
}
}




//Interrupt Service Routine


void Interrupt_HIGHpriority(void)
{
  INTCONbits.GIE = 0;

   LATDbits.LATD0 = 1;
   LATDbits.LATD1 = 0;


while(1){}

  INTCONbits.GIE    = 1;
  INTCONbits.INT0IF = 0;
}
#pragma code
 
Last edited:
In your main code you constantly set D0 to 0 and D1 to 1. Whatever you do with the interrupt, get changed back.

Replace this:

C:
while(1)
{
LATDbits.LATD0 = 0;
LATDbits.LATD1 = 1;
}

with this:

C:
LATDbits.LATD0 = 0;
LATDbits.LATD1 = 1;
 
while(1){}
 
C:
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
   {
   _asm
   goto Interrupt_HIGHpriority  //jump to interrupt routine
   _endasm
   }

void main(void)
{
  TRISBbits.TRISB0 = 1;

  TRISDbits.TRISD0 = 0;
  TRISDbits.TRISD1 = 0;

  INTCON = 0;           
  RCON = 0;

  INTCONbits.INT0IF   = 0;
  RCONbits.IPEN       = 0;
  INTCONbits.GIE      = 1;
  INTCONbits.INT0IE   = 1;
  INTCON2bits.INTEDG0 = 0;

   while(1)
   {
      LATDbits.LATD0 = 0;
      LATDbits.LATD1 = 1;
   }
}


//Interrupt Service Routine
#pragma code
#pragma interrupt Interrupt_HIGHpriority
void Interrupt_HIGHpriority(void)
{
  INTCONbits.GIE = 0;

   LATDbits.LATD0 = 1;
   LATDbits.LATD1 = 0;
   PIR2bits.CMIF = 0;

while(1){} ///  <----- WHAT THE HELL IS THIS

  INTCONbits.GIE    = 1; 
  INTCONbits.INT0IF = 0;
}
I'm assuming C18!!!
First you need to enter the vector for the interrupt...
Secondly.. There is a forever loop in your interrupt....
Thirdly.. There is no need to turn off/on the global interrupt bit during an interrupt ( its automatically done this way )
 
Thanks for the replies. I included an infinite loop in the ISR so I will know when the program enters the loop.
Unfortunatelly the program is still not working. Why is TRISB showing as FF when in debug mode, even though portB.0 (interrupt pin) is shorted to ground?
 
TRISB is the data direction register, PORTB will show the value on the pins.

Mike.
 
Hi again. Thanks for the replies. Below is the full code:
Code:
#include<p18f4550.h>                             

#pragma config FOSC   = HS   
#pragma config FCMEN  = OFF  
#pragma config PWRT   = ON    
#pragma config BOR    = OFF   
#pragma config WDT    = OFF  
#pragma config LVP    = OFF 
#pragma config IESO   = OFF   
#pragma config CP0    = OFF  
#pragma config MCLRE  = ON   
#pragma config ICPRT  = OFF 

#pragma code main = 0x00  
#pragma code InterruptVectorHigh = 0x08 

void InterruptVectorHigh(void);
void Interrupt_HIGHpriority(void);


void main(void)
{
  TRISBbits.TRISB0 = 1;

  TRISDbits.TRISD0 = 0;
  TRISDbits.TRISD1 = 0;

  INTCON = 0;            
  RCON = 0;
 
  INTCONbits.INT0IF   = 0;  
  RCONbits.IPEN       = 0;  
  INTCONbits.GIE      = 1;
  INTCONbits.INT0IE   = 1; 
  INTCON2bits.INTEDG0 = 0; 

  LATDbits.LATD0 = 1;
  LATDbits.LATD1 = 0;

while(1)
{
}
}



void InterruptVectorHigh (void)
   {
   _asm
   goto Interrupt_HIGHpriority
   _endasm
   }


#pragma code
#pragma interrupt Interrupt_HIGHpriority

void Interrupt_HIGHpriority(void)
{

   LATDbits.LATD0 = 0;
   LATDbits.LATD1 = 1;

   PIR2bits.CMIF = 0;  
   INTCONbits.INT0IF = 0;
}
 
Sorry!! The interrupt vector definition had to be next to the interrupt code..

Also the ADC on port b has to be dissabled

C:
#include<p18f4550.h>   

#pragma config FOSC  = HS  
#pragma config FCMEN  = OFF  
#pragma config PWRT  = ON   
#pragma config BOR  = OFF  
#pragma config WDT  = OFF  
#pragma config LVP  = OFF
#pragma config IESO  = OFF  
#pragma config CP0  = OFF  
#pragma config MCLRE  = ON  
#pragma config ICPRT  = OFF
#pragma config PBADEN  = OFF

void Interrupt_HIGHpriority(void);

void main(void)
   {
   TRISBbits.TRISB0 = 1;
   TRISDbits.TRISD0 = 0;
   TRISDbits.TRISD1 = 0;

   INTCON = 0;   
   RCON = 0;
   
   INTCONbits.INT0IF  = 0;  
   RCONbits.IPEN  = 0;  
   INTCONbits.GIE  = 1;
   INTCONbits.INT0IE  = 1;
   INTCON2bits.INTEDG0 = 0;

   LATDbits.LATD0 = 1;
   LATDbits.LATD1 = 0;

   while(1)
     {
     }
   }

#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
   {
   _asm
   goto Interrupt_HIGHpriority
   _endasm
   }


#pragma code
#pragma interrupt Interrupt_HIGHpriority

void Interrupt_HIGHpriority(void)
   {
   LATDbits.LATD0 = 0;
   LATDbits.LATD1 = 1;

   PIR2bits.CMIF = 0;  
   INTCONbits.INT0IF = 0;
  }
 
Thanks Ian Rogers :)

Can I write the ISR directly in the InterruptVectorHigh routine? Also, can you explain the code below for me please?


#pragma code
#pragma interrupt Interrupt_HIGHpriority

And the last question, is there the need to prototype the following functions? :

void InterruptVectorHigh(void);
void Interrupt_HIGHpriority(void);

Thanks in advance.
 
1) No! Its an internal C18 thing... Its the way that this compiler utilises interrupts. XC8 doesn't do it this way... I prefer the XC8 way!!!

If you have the full version of C18 you are entitled to an upgrade to XC8 pro...

2) Just the prototype for the C coded function, not the asm one...

Cheers
 
I don't think so.... Are you comparing two voltages? If so it just either outputs on another pin or sets an interrupt.

A good feature of the comparator is the wake from sleep function...


Thanks for the reply. Does it make sense to connect the output pin of the comparator to an interrupt pin?

Another question not related to the comparator: Can I store a variable which can go up to 20,000 in an integer? or is an integer 8bit?

Thanks in advance.
 
Integer means "whole number" so regardless of how many bits the integer has, its still a whole number..

One byte = Byte or char is 8 bits and can represent -128 to +127 or 0 to 255..
Two bytes = Word or short is 16 bits and can represent -32768 to +32767 or 0 to 65535..
Four bytes = Double Word or Long is 32 bits an can represent -2417483647 to +2417483646 or 0 to 429496295..

so to answer your question... 20.000 can be represented with a word (16 bits)
 
Yes!... I always look ahead to what may be needed... if you are going to use maths then maybe a glance to the future is in order...

Many times I have multiplied two numbers and not realized I had breached the size of the variable..

ie....
unsigned int a, b;
a = 20000;
b = a *4;

Result b = 14,464.... Should have been 80,000
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top