Professional Documents
Culture Documents
Author Message
I would like to implement similar application like Microchip AN843, for that I require Fast
Interrupts for Timer0, Timer1 and Timer2 and Slow interrupts for RB and A to D converter.
Please help me to write fast interrupts (For Timer0, Timer 1 and Timer2) using PIC C. (Device is
PIC18F452)
my code as follows:
MOVWF hWTemp
MOVFF STATUS,hSTemp
MOVFF BSR,hBTemp
BRA HighIntSelect
NOP
MOVWF lWTemp
MOVFF STATUS,lSTemp
MOVFF BSR,lBTemp
BRA lowIntSelect ;Jump to interrupt polling routine
HIGH_CONTEXT_RESTORE:
MOVFF hBTemp,BSR
MOVF hWTemp,W
MOVFF hSTemp,STATUS
RETFIE 1
lowContextRestore:
1 от 9 27.2.2007 г. 09:43
CCS :: View topic - Fast Interrupts for Timer0, Timer1 and Timer2 http://ccsinfo.com/forum/viewtopic.php?t=26440&highlight=int0...
MOVFF lBTemp,BSR
MOVF lWTemp,W
MOVFF lSTemp,STATUS
RETFIE 1;
HighIntSelect:
btfsc TMR2IF ;Timer2 to PR2 match?
bra TIMER2_PR2_Match
btfsc TMR1IF ;Timer1 overflow Interrupt?
bra TIMER1_OVERFLOW
btfsc TMR0IF ;Timer0 overflow Interrupt?
bra TIMER0_OVERFLOW ;Yes
BRA HIGH_CONTEXT_RESTORE
LOW_CONTEXT_SAVE:
MOVWF lWTemp
MOVFF STATUS,lSTemp
MOVFF BSR,lBTemp
BRA lowIntSelect ;Jump to interrupt polling routine
TIMER2_PR2_Match:
bcf TMR2IF ;
tstfsz PWM3_DUTYCYCLE ;If Software PWM duty cycle=0, then
bra PWM3_NOT_0 ;no need to set the PWM3 port pin
BRA HIGH_CONTEXT_RESTORE
TIMER1_OVERFLOW:
BCF PWM3_PORT ;PWM3 pin cleared after the duty cycle time expires
BCF TMR1IF
BRA HIGH_CONTEXT_RESTORE
TIMER0_OVERFLOW:
BCF TMR0IF
BSF TIMER0_OV_FLAG
BRA HIGH_CONTEXT_RESTORE
lowIntSelect:
btfsc RBIF ;RB interrupt?
bra CHECK_FAULT ;Yes
btfsc ADIF
bra AD_CONV_COMPLETE
BRA lowContextRestore
CHECK_FAULT:
BCF RBIF
BRA lowContextRestore
AD_CONV_COMPLETE:
movff ADRESH,FREQUENCY
movlw 0x14 ;Minimum Frequency set to 5Hz (scaling factor X4)
cpfsgt FREQUENCY
movwf FREQUENCY
movlw 0xF0 ;Limiting V/F to F= 60Hz (scaling factor X4)
cpfslt FREQUENCY
movwf FREQUENCY
2 от 9 27.2.2007 г. 09:43
CCS :: View topic - Fast Interrupts for Timer0, Timer1 and Timer2 http://ccsinfo.com/forum/viewtopic.php?t=26440&highlight=int0...
PWM3_NOT_0:
movlw 0xFF ;Higher byte of Timer1 loaded with FFh
movwf TMR1H
movff PWM3_DUTYCYCLE,TMR1L ;Lower byte of Timer1 loaded with Duty cycle
bsf PWM3_PORT ;PWM3 pin set high
BRA HIGH_CONTEXT_RESTORE
#ENDASM
}
Thank you,
Best Regards,
Thushi
First, when posting source code use the 'Code' button. This will keep the formatting of your code
Joined: 18 Mar 2004
Posts: 1332 intact.
Location: The Netherlands
Code:
#ORG 0X000008, 0X000180
Don't do this. This will map your fast interrupt handler over the start address 0x0018 of the
normal interrupt. In CCS you create an interrupt handler by specifying the #int_xxx identifier,
for Fast interrupts add the FAST keyword.
Code:
MOVWF hWTemp
MOVFF STATUS,hSTemp
MOVFF BSR,hBTemp
You don't need to do this. On entering an interrupt the PIC18 processors will save the contents
of these three registers to hardware shadow registers. On exiting the interrupt use RETFIE with
parameter 1 to restore the contents of these register.
I coudnt use FAST keyword for all three interrupt service routines . (T0, T1 and T2). This is the
problem I have. I want to service the interrupts as soon as possible. T0, T1, T2 set to higher
priority.
thank you
ckielstra wrote:
First, when posting source code use the 'Code' button. This will keep the formatting of your
code intact.
Code:
#ORG 0X000008, 0X000180
Don't do this. This will map your fast interrupt handler over the start address 0x0018
3 от 9 27.2.2007 г. 09:43
CCS :: View topic - Fast Interrupts for Timer0, Timer1 and Timer2 http://ccsinfo.com/forum/viewtopic.php?t=26440&highlight=int0...
of the normal interrupt. In CCS you create an interrupt handler by specifying the
#int_xxx identifier, for Fast interrupts add the FAST keyword.
Code:
MOVWF hWTemp
MOVFF STATUS,hSTemp
MOVFF BSR,hBTemp
You don't need to do this. On entering an interrupt the PIC18 processors will save the
contents of these three registers to hardware shadow registers. On exiting the
interrupt use RETFIE with parameter 1 to restore the contents of these register.
You cheat!....
Declare _one_ interrupt as fast. Write your complete handler, including the tests for which
interrupt has occured, and the routines for the other interrupts inside this handler.
Then simply set the 'high priority' bits, for the other two interrupts.
Best Wishes
Quote:
Joined: 18 Mar 2004
Posts: 1332 I coudnt use FAST keyword for all three interrupt service routines . (T0, T1 and T2). This is
Location: The Netherlands the problem I have. I want to service the interrupts as soon as possible. T0, T1, T2 set to
higher priority.
CCS support for the FAST interrupts is 'minimal'...
Write CCS-C code like you are going to create a FAST interrupt for just a single interrupt.
The trick is to not only enable the interrupt for the specified FAST interrupt but also set the high
priority flags for all other FAST interrupts (requires direct writing to the priority registers, no CCS
command exists for this).
For the normal priority interrupts CCS can create a good dispatcher for you automatically, you
don't have to write this code yourself.
#INT_TIMER0 FAST // Note the FAST keyword to make this a high priority interrupt
void my_fast_isr(void)
{
// Put here your FAST interrupt code
// Note that it is your responsibility to save and restore all modified registers,
// except for Wreg, Status and BSR which are all saved to shadow registers
// automatically by hardware.
}
#INT_TBE
void tbe_isr(void)
{
// place here your UART Tx code.
}
#INT_AD
void ad_isr(void)
{
// put here your AD converter code.
}
//===============================
4 от 9 27.2.2007 г. 09:43
CCS :: View topic - Fast Interrupts for Timer0, Timer1 and Timer2 http://ccsinfo.com/forum/viewtopic.php?t=26440&highlight=int0...
void main()
{
// bit_set(INTCON2, 1); // Set Timer0 as high priority
// Not required, the compiler will do this because
// we already defined this as a FAST interrupt
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER2);
enable_interrupts(INT_TBE);
enable_interrupts(INT_AD);
enable_interrupts(GLOBAL);
while(1);
}
Dear Mr.Ttelmah
Joined: 22 Feb 2006
Posts: 14
Thanks for your reply.
Can you please give me a sample code to do that. I coudnt understand what you wrote here. Is
it some think like this?
Code:
#int_timer0 fast
void timer0_isr()
{
//my timer 0 interrupt routines goes here
[/code]
Thanks again..
I am doing motor control application so that time is more critical. Timer0 is used for set the
frequency of the motor. Timer2 is used to generate PWM (Two channels) and Timer 1 is used for
software PWM. so that Timer2 and Timer 1 interrupts have to be serviced as soon as possible. I
need STATUS, Wreg and BSR to save. nothing other than that.
I set prority bits already. If I set Timer 2 interrupt FAST then Timer 1 is become slow, because it
is saves all the contexts. How can I do that???
Thank you
Best Regards,
Thushi
ckielstra wrote:
5 от 9 27.2.2007 г. 09:43
CCS :: View topic - Fast Interrupts for Timer0, Timer1 and Timer2 http://ccsinfo.com/forum/viewtopic.php?t=26440&highlight=int0...
Quote:
I coudnt use FAST keyword for all three interrupt service routines . (T0, T1 and
T2). This is the problem I have. I want to service the interrupts as soon as
possible. T0, T1, T2 set to higher priority.
CCS support for the FAST interrupts is 'minimal'...
Write CCS-C code like you are going to create a FAST interrupt for just a single
interrupt.
The trick is to not only enable the interrupt for the specified FAST interrupt but also
set the high priority flags for all other FAST interrupts (requires direct writing to the
priority registers, no CCS command exists for this).
For the normal priority interrupts CCS can create a good dispatcher for you
automatically, you don't have to write this code yourself.
#INT_TIMER0 FAST // Note the FAST keyword to make this a high priority interrupt
void my_fast_isr(void)
{
// Put here your FAST interrupt code
// Note that it is your responsibility to save and restore all modified registers,
// except for Wreg, Status and BSR which are all saved to shadow registers
// automatically by hardware.
}
#INT_TBE
void tbe_isr(void)
{
// place here your UART Tx code.
}
#INT_AD
void ad_isr(void)
{
// put here your AD converter code.
}
//===============================
void main()
{
// bit_set(INTCON2, 1); // Set Timer0 as high priority
// Not required, the compiler will do this because
// we already defined this as a FAST interrupt
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER2);
enable_interrupts(INT_TBE);
enable_interrupts(INT_AD);
enable_interrupts(GLOBAL);
while(1);
}
6 от 9 27.2.2007 г. 09:43
CCS :: View topic - Fast Interrupts for Timer0, Timer1 and Timer2 http://ccsinfo.com/forum/viewtopic.php?t=26440&highlight=int0...
never used), and the real handler for timer0. Set this one as 'fast'. Then in this handler, check at
the start which interrupt bit is set, jump to the required handler code, clear the corresponding
interrupt flag, and return.
In the main code, simply set the 'high priority' bits for timer1, and timer2, which will then vector
to the timer0 handler (which effectively becomes an 'int_global' for the high priority interrupt).
As a comment though, you make no mention of actually using other interrupts?. If not, then
forget using high priority!... The 'point' about high priority, is that it allows one interrupt to
interrupt another. If you only want 'quick' handling of the interrupts, then simply write an
'int_global' handler, and use the retfie 1 ability from this. This will be as 'fast', as the high
priority interrupts, and avoids you having to fiddle.
Best Wishes
As an example of the 'int_global' approach, the following is some code I used for this. This was
for a different 'set' of interrupts to you, but shows how to handle it.
Code:
#int_global
void myint(void) {
#ASM
//Here for maximum speed, I test the RB interrupt - since it is allways
//enabled, I don't have to test the enable bit
BTFSS INTCON,RBIF
GOTO NXT
#endasm
quad(); //Quadrature handler.
#asm
BCF INTCON,RBIF
GOTO FEXIT //Use the fast stack for exit
NXT:
//Test for the external interrupt (power fail).
BTFSS INTCON,INT0E
GOTO NEXTA
BTFSC INTCON,INT0
#endasm
pfail();
#asm
NEXTA:
//Now for Timer 2
BTFSS PIE1,TMR2
GOTO NEXT1
BTFSC PIR1,TMR2
#endasm
TIMER2_isr();
#asm
NEXT1:
//Receive data available
BTFSS PIE1,RCIE
GOTO NEXT2
BTFSC PIR1,RCIE
#endasm
RDA_isr();
#asm
NEXT2:
//Transmit buffer empty
BTFSS PIE1,TXIE
GOTO FEXIT
BTFSC PIR1,TXIE
#endasm
TBE_isr();
#asm
//Here the 'fast' exit.
FEXIT:
7 от 9 27.2.2007 г. 09:43
CCS :: View topic - Fast Interrupts for Timer0, Timer1 and Timer2 http://ccsinfo.com/forum/viewtopic.php?t=26440&highlight=int0...
RETFIE 1
#ENDASM
}
The interrupt handlers each clear their own interrupt flag (except in my code the 'quad' handler),
and the compiler will insert them normally as 'inline'. I my code, I save/restore any extra
registers needed in these routines.
Best Wishes
Ttelmah wrote:
Joined: 22 Feb 2006
Posts: 14 As an example of the 'int_global' approach, the following is some code I used for this. This
was for a different 'set' of interrupts to you, but shows how to handle it.
Code:
#int_global
void myint(void) {
#ASM
//Here for maximum speed, I test the RB interrupt - since it is allways
//enabled, I don't have to test the enable bit
BTFSS INTCON,RBIF
GOTO NXT
#endasm
quad(); //Quadrature handler.
#asm
BCF INTCON,RBIF
GOTO FEXIT //Use the fast stack for exit
NXT:
//Test for the external interrupt (power fail).
BTFSS INTCON,INT0E
GOTO NEXTA
BTFSC INTCON,INT0
#endasm
pfail();
#asm
NEXTA:
//Now for Timer 2
BTFSS PIE1,TMR2
GOTO NEXT1
BTFSC PIR1,TMR2
#endasm
TIMER2_isr();
#asm
NEXT1:
//Receive data available
BTFSS PIE1,RCIE
GOTO NEXT2
BTFSC PIR1,RCIE
#endasm
RDA_isr();
#asm
NEXT2:
//Transmit buffer empty
BTFSS PIE1,TXIE
GOTO FEXIT
BTFSC PIR1,TXIE
#endasm
TBE_isr();
#asm
//Here the 'fast' exit.
FEXIT:
RETFIE 1
#ENDASM
}
The interrupt handlers each clear their own interrupt flag (except in my code the
'quad' handler), and the compiler will insert them normally as 'inline'. I my code, I
save/restore any extra registers needed in these routines.
Best Wishes
Hi,
8 от 9 27.2.2007 г. 09:43
CCS :: View topic - Fast Interrupts for Timer0, Timer1 and Timer2 http://ccsinfo.com/forum/viewtopic.php?t=26440&highlight=int0...
I coudnt see "#int_global" command in CCS C compiler help. Why they avoid it? I have PCW
3.242 Editor and compiler.
Thank you,
Best Regards,
Thushi..
Page 1 of 1
9 от 9 27.2.2007 г. 09:43