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.

PIC interrupt handeling basics RB0

Status
Not open for further replies.
Hello everybody!
I am new on this forum and this is my first letter.
First, sorry for my english, it is not my native language - but i shall try :) !
Well, I am trying to experiment with my EasyPIC3 board from Mikroelektronika with PIC18F4550 installed, compiler is MPLAB C18 Student Edition in MPLAB IDE v.8.15a.
What is confusing me is the sofrware "mechanaism" of interrupts in C18. Let me be more precise: I know how stuff works in hardware but (for the first time) I saw the code for interrupt routine in C!!!
So what is my question: Mr.Pommie, can You give us a lesson (in the letter on this forum or in the article) what is what in this #pragma-s, why are you using asm code etc.
I think that people will agree with me that only precise and detailed explanation with the example will give the result.
Please, Mr.Pommie, spent some time and do it for us!
Best regards from Peca.
 
The use of #pragmas is not very intuitive and makes the code seem far more complicated. Pragmas are used to include anything that is not standard C, things like the config setting and to locate code in special areas. The interrupt vector is one such area and,

Code:
//Low priority interrupt vector
#pragma code InterruptVectorLow = 0x18 //[COLOR="Red"]<<<< should be 0x08[/COLOR]   
void
InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow
  _endasm
}
#pragma code
simply tells the compiler to place a single instruction (a goto) at location 0x18 which is the address the processor jumps to when an interrupt occurs. The #pragma code tells the compiler it is now free to put the code where it thinks is best. The pragmas around the interrupt handler (not the vector above) are not really needed and were just included as this is how Microchip write their examples.

Mike.
 
Last edited:
Hi, again!
Please, look at the attached code. I tried to comment it in detail.
So, why I have nothing on my port D? Why my LED`s refuses to flash?:(
Thanks in advance.
Peca.
P.S. After I send the previous letter, I find the explanation in MPLAB IDE help about #pragma interrupts. So, Mr.Pommie... decide what you want.:)
 

Attachments

  • Timer_With_Interrupt.zip
    10.2 KB · Views: 212
That is because I'm stupid and used the wrong vector, in compatibility mode the interrupts go to location 0x08 and not 0x18. Makes me wonder how Lunar's code worked.

So, change 0x18 to 0x08. Also, change while(Limit<=5); to while(1); otherwise it will go wandering through memory.

Mike.
 
Changed code.

Hi, Mike!

Thank you a lot! Code starts to work immediately after I changed it.
Of course, I tried to do some more so I changed code again an it works!
Here is the new code:
Code:
#include "p18f4550.h"
#include "Config_Bits.h"

void Timer2(void);

#pragma code High_Vector_Section=0x08		// We shall use high-interrupt. Interrupt vector is at address 0x08. 				<--- (changed)
void Timer2_Interrupt (void)						// On every occurence of interrupt from Timer2...
{
	_asm
	goto	Timer2													// ... jump to high-interrupt ISR Timer2!
	_endasm
}
#pragma code

volatile unsigned int Limit=0, Counter=0;		// Global variables. Their values can be changed by main() or by ISR. 

#pragma interrupt Timer2										// Tell the compiler that ISR for high-interrupt is Timer2.							<--- (changed)
void Timer2(void)														// The body of high-interrupt ISR starts here. 
{
	PIR1bits.TMR2IF=0;												// Immediately clear the interrupt flag.			
	Counter++;																// Increase counter. Remember, this means that one mS is passed!
	LATDbits.LATD0=!LATDbits.LATD0;						// Change the state of port D, pin 0 and LED connected to it.
	if(Counter>=1000)													// Look if counter reaches 1000mS - it is one second (1s)! And if so...
	{
		LATDbits.LATD4=!LATDbits.LATD4;					// ... change state of port D, pin 4 and LED connected to it...
		Counter=0;															// ... and clear counter to start counting again.
		Limit++;																// Increase the limit.
	}		
}	

void main(void)
{
	TRISD=0x00;		 						// Port D to be output port.
	LATD=0x00;								// All LED`s are OFF.
	IPR1bits.TMR2IP=1;				// Interrupt priority bit set to 1 - high priority. 		<--- (changed)
	PIE1bits.TMR2IE=1;				// Interrupt on TMR2IF enabled.
	
	//T2CONbits.T2CKPS0=1;
	//T2CONbits.T2CKPS1=1;
	//T2CONbits.TMR2ON=1;
	 
	T2CON=0b00000110;					// Timer2 config register:	prescaler (bits 0-1):				divide by 16
	 													//													timer2 ON/OFF (bit 2):			TMR2ON=1 - ON
	 													// 													postscaler (bits 3-7):			1:1
	PR2=0x7C;									// Period register set to 124 (dec.).
	INTCONbits.PEIE=1;				// Enable peripheral interrupt sources.
	INTCONbits.GIE=1;					// Enable global interrupts.
	while(Limit<=4);					// Wait approx. 5 seconds...														<--- (changed)
	T2CONbits.TMR2ON=0;				// ... than stop theTimer2...														<--- (changed)
		INTCONbits.PEIE=0;			// ... disable peripheral interrupt sources...					<--- (changed)
		INTCONbits.GIE=0;				// ... and disble global interrupts.										<--- (changed)					
	LATDbits.LATD7=1;					// Change state of pin 7 at port D if we arriwe here.		<--- (changed)
	while(1);
}

The previous code looks good in my MPLAB editor. Why is it so ugly here?

Question: is it possible to have multiple ISR`s for the same interrupt? And if it is, how to organise them to work properly?

Peca.
P.S. What is compatibility mode? I didn`t find anything about it.
 
Last edited:
The code looks ugly because it has a mix of spaces and tabs. Tabs in MPLAB are set to 4 and on here they are 8, if you set MPLAB to insert spaces rather than tabs it will be neater.

For an explanation of compatibility mode, read page 97 of the datasheet.

You can have multiple different interrupts by checking the flag to see which one caused it,
Code:
#pragma interrupt ISR
void ISR(void)                      
{
    if(PIR1bits.TMR2IF){

	//do timer 2 stuff

	PIR1bits.TMR2IF=0;
    }
    if(INTCONbits.RBIF){

	//do IOC stuff

	INTCONbits.RBIF=0;
    }
}

Mike.
 
Hi, Mike!

Thank you again.
Yes, on page 97 I find the explanation. I read that section many times but I didn`t read this very, very carefuly so I missed the term "compatibility mode" :eek:. So, thank you again.
But in my question I asked if it is possible to have NOT ONE ISR for the same interrupt flag (let`s say for Timer2 -TMR2IF ) but MORE THAN ONE ISR? Maybe I want more jobs to do when the exact one flag is setting (it is clear to me that I can have one ISR for each interrupt flag or the same ISR for more than one interrupt flags). That`s OK.
On my opinion it is not possible and I can`t figure how to do this (now :)) "knowing" the mechanism of interrupts. Why? Because, when the interrupt is issued, on address 0x08 (or 0x18) PIC puts only one address! This address belongs to only one ISR "connected" only for that interrupt. I don`t see the room for another ISR`s. Do I think correctly? (Or... there is some hidden trick from The Great Teachers :)).

Peca.
 
Last edited:
You can have multiple tasks on each interrupt but you have to control which task is executed. For example you may have a 1mS interrupt that has multiple counters that trigger different events every 13, 27 and 50mS.

Mike.
 
Something usefull.

Hi!

Here is the result of previous disscusion: small program which I use for the not so accurate pauses in code (during the debugging) on my EasyPIC3 at 8MHz with pic18f4550. As you can see, the time is given in seconds and its fractions.
Try to implement it in your code. I am very curious how it works on another platforms.
 

Attachments

  • Pause_For_Forum.zip
    11.5 KB · Views: 183
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top