View previous topic :: View next topic |
Author |
Message |
pudozh
Joined: 08 May 2015 Posts: 3
|
Enable/disable interrupts |
Posted: Fri May 08, 2015 8:05 am |
|
|
Good day
i must perform enabling an interrupt ( and a timer) while executing an another interrupt:
code:
Code: |
#include <16F1509.h>
#device ADC=10
#FUSES NOMCLR //no MCLR pin
#FUSES HS //External Oscillator
#byte CLC4GLS0=getenv("SFR:CLC4GLS0")
#byte CLC4GLS1=getenv("SFR:CLC4GLS1")
#byte CLC4GLS2=getenv("SFR:CLC4GLS2")
#byte CLC4GLS3=getenv("SFR:CLC4GLS3")
#byte CLC4SEL0=getenv("SFR:CLC4SEL0")
#byte CLC4SEL1=getenv("SFR:CLC4SEL1")
#byte CLC4POL=getenv("SFR:CLC4POL")
#byte CLC4CON=getenv("SFR:CLC4CON")
#byte PIR1=getenv("SFR:PIR1")
#byte PIE1=getenv("SFR:PIE1")
#byte T2CON=getenv("SFR:T2CON")
#byte TMR2=getenv("SFR:TMR2")
#byte PR2=getenv("SFR:PR2")
#bit TMR2IE = PIE1.1
#bit TMR2IF = PIR1.1
#use delay(crystal=20MHz)
int16 deep1;
void clcconf1(void);
#INT_TIMER2
void TIMER2_isr(void)
{
if (!(deep1--)) {
output_high(PIN_C0); // enable led
delay_us(2000); // pulse width
output_low(PIN_C0); // led off
TMR2IF = 0; //clear int flag
TMR2IE = 0; // disable interrupt
T2CON = 0; // stop timer2
output_high(PIN_A1); //reset clc flip flop (FF)
output_low(PIN_A1);
}
}
#INT_CLC4
void CLC4_isr(void)
{
deep1 = 150;
PR2 = 139; //
T2CON = 0b000110110; // timer2 on
TMR2IF = 0; //clear int flag
TMR2IE = 1; //enable interrupt timer2
}
#use delay(crystal=20MHz)
// to avoid error if use delay with interrupt routine
void main()
{
set_tris_a(0b11111001); //Bit 1 = input Bit 0 = output
set_tris_b(0b01111111); //Bit 1 = input Bit 0 = output
set_tris_c(0b00100100); //Bit 1 = input Bit 0 = output
clcconf1();
output_high(PIN_A1); //reset clc4 flip flop
output_low(PIN_A1);
delay_ms(1000);
enable_interrupts(INT_CLC4);
enable_interrupts(GLOBAL);
while(TRUE)
{
//code
}
}
|
When the CLC flip flop is fired the second interrupt work but after resetting the CLC is not possible to fire it again.
Any idea?
compiler is 5.008
Thanks |
|
|
pudozh
Joined: 08 May 2015 Posts: 3
|
|
Posted: Fri May 08, 2015 8:13 am |
|
|
Good day
a mistake on CLC4 int routine:
T2CON = 0b000110110; // timer2 on wrong
T2CON = 0b00101110; // timer2 on correct
Regards |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19492
|
|
Posted: Fri May 08, 2015 8:48 am |
|
|
Just use CCS code....
You do not need to fiddle with the bits, and what you are doing wastes an instruction.
Code: |
#INT_TIMER2
void TIMER2_isr(void)
{
if (!(deep1--))
{
output_high(PIN_C0); // enable led
delay_us(2000); // pulse width
output_low(PIN_C0); // led off
disable_interrupts(INT_TIMER2);
setup_timer_2(FALSE);
output_high(PIN_A1); //reset clc flip flop (FF)
output_low(PIN_A1);
}
}
|
The compiler always automatically clears interrupts for you, unless you specifically tell it not to (NO_CLEAR). So doing this is pointless.
You can just use the compiler's disable _interrupts instruction, and tell the compiler to stop the time. The same applies in all your other routines. clear_interrupt etc...
However there is a big problem, from using the delay routine in the interrupt. The compiler _will_ be giving you a warning that interrupts are disabled to prevent re-entrancy in the delay routine in the main code. Think again. There are lots of ways to do this to avoid this..... |
|
|
pudozh
Joined: 08 May 2015 Posts: 3
|
|
Posted: Fri May 08, 2015 10:19 am |
|
|
Thanks for suggest :
I've changed the code but the working is the same.
CLC4 FF give interrupt, interrupt on timer2 starts but at the end of routine
pin a1 reset the clc flip flop and after no more clc interrupts.
Code: | #include <16F1509.h>
#device ADC=10
#FUSES NOMCLR //no MCLR pin
#FUSES HS //Externrnal Oscillator
#byte CLC4GLS0=getenv("SFR:CLC4GLS0")
#byte CLC4GLS1=getenv("SFR:CLC4GLS1")
#byte CLC4GLS2=getenv("SFR:CLC4GLS2")
#byte CLC4GLS3=getenv("SFR:CLC4GLS3")
#byte CLC4SEL0=getenv("SFR:CLC4SEL0")
#byte CLC4SEL1=getenv("SFR:CLC4SEL1")
#byte CLC4POL=getenv("SFR:CLC4POL")
#byte CLC4CON=getenv("SFR:CLC4CON")
#use delay(crystal=20MHz)
int16 deep1;
void clcconf1(void);
#INT_TIMER2
void TIMER2_isr(void)
{
if (!(deep1--)) {
output_high(PIN_C0); // enable led
delay_us(2000); // pulse width
output_low(PIN_C0); // led off
disable_interrupts(INT_TIMER2); //disable interrupt
setup_timer_2(FALSE,1,1); // disable timer
output_high(PIN_A1); //reset clc flip flop (FF)
output_low(PIN_A1);
}
}
#INT_CLC4
void CLC4_isr(void)
{
deep1 = 150;
setup_timer_2(T2_DIV_BY_16,139,3); //448 us overflow, 1,3 ms interrupt
enable_interrupts(INT_TIMER2);
}
#use delay(crystal=20MHz)
// questa istanza รจ usata due volte per le routine di delay sotto interrupt
void main()
{
set_tris_a(0b11111001); //Bit 1 = input Bit 0 = output
set_tris_b(0b01111111); //Bit 1 = input Bit 0 = output
set_tris_c(0b00100100); //Bit 1 = input Bit 0 = output
clcconf1();
output_high(PIN_A1); //reset clc4 flip flop
output_low(PIN_A1);
delay_ms(1000);
enable_interrupts(INT_CLC4);
enable_interrupts(GLOBAL);
while(TRUE)
{
//code
}
}
void clcconf1(void)
{
// File: pagina2_sim.inc
// Generated by CLC Designer, Version: 3.0.0.4
// Date: 05/03/2015 21.28
// Device:PIC16(L)F1508/9
CLC4GLS0 = 0x02;
CLC4GLS1 = 0x00;
CLC4GLS2 = 0x80;
CLC4GLS3 = 0x00;
CLC4SEL0 = 0x00;
CLC4SEL1 = 0x50;
CLC4POL = 0x02;
CLC4CON = 0xD4;
} |
I don't know how the compiler polling multiple irq but something happens enabling / disabling irq
Suggest?
Thanks |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1933 Location: Norman, OK
|
|
Posted: Fri May 08, 2015 11:11 am |
|
|
Also, your #use delay is too late in the code, it should be right
after the #fuses in this case. You can only have ONE #use delay.
Also, you cannot have a 2ms delay in an interrupt routine. During
that delay interrupts are disabled. Get in and get out as quickly as
possible! You will need to form your pulse another way. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
|