|
|
View previous topic :: View next topic |
Author |
Message |
mdemuth
Joined: 16 Apr 2007 Posts: 71 Location: Stuttgart, Germany
|
#int_ra is not cleared (solved) |
Posted: Fri Sep 20, 2013 6:11 am |
|
|
Hi,
I just got stuck and would like to get some help.
I am trying to readout an encoder, which is connected to RA5 in combination with a motor drive.
The problem is, that it seems that the IRQ is entered but not left anymore.
Code: |
//// CCS Compiler Version: 4.124
////
/////////////////////////////////////////////////////////////////////////
#include <16f1824.h>
#device ADC=10
#fuses INTRC_IO,NOPROTECT,BROWNOUT,PUT,MCLR,WDT
#use delay(clock=8000000)
#use rs232(baud=19200, PARITY=N, BITS=8, STOP=1,XMIT=PIN_C3) // COM Initialisierung
#define tacho PIN_A5 // Drehzahl Istwert
#define Gate PIN_C5 // Gate for IGBT
#define LED PIN_A1 // LED
int8 dummy8=0;
int16 on_time=20;
#zero_ram
void main()
{
setup_oscillator (OSC_8MHZ);
setup_timer_2(T2_DIV_BY_64, 1022,1); // PWM for Motor Driver
SETUP_CCP1(CCP_PWM | CCP_TIMER2);
SETUP_WDT(WDT_1S); //WDT
putc(0x0C); // Formfeed
printf("\n\rOK");
SET_PWM1_DUTY(1023-on_time); // Motor is spinning constantly for test
while (1)
{
output_toggle(LED); // blinking as long as motor gets voltage and starts spinning....
delay_ms(100);
restart_wdt();
printf("\n\r%u",dummy8);
dummy8++;
enable_interrupts(global); // everything works fine until IRQ is entered (=> tachogenerator sends pulses)
enable_interrupts(INT_RA5_L2H); // then main loop stucks
restart_wdt();
}
}
#INT_RA
isr_tacho()
{
dummy8=input_a(); // clear IRQ
}
|
???
Last edited by mdemuth on Mon Sep 23, 2013 1:15 am; edited 1 time in total |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Fri Sep 20, 2013 6:57 am |
|
|
Hi,
There is quite a lot wrong with your code! For starters, get rid of the watchdog function until you've finished debugging the basic functionality of
your code! Next, you should move the 'enable_interrupts' outside of the 'While(1)' loop, and reverse their order (ie. the 'global' enable should be
last...). After you do this, see if the code behaves the way you expect...
John |
|
|
mdemuth
Joined: 16 Apr 2007 Posts: 71 Location: Stuttgart, Germany
|
|
Posted: Fri Sep 20, 2013 8:09 am |
|
|
OK: not WDT and enable IRQ before while(1)
Here is the new code:
Code: |
/////////////////////////////////////////////////////////////////////////
//// WEPA TOPITEC
////
//// Version 0.0 17.09.13
//// Michael Demuth indEAS GmbH
//// CCS Compiler Version: 4.124
////
/////////////////////////////////////////////////////////////////////////
#include <16f1824.h>
#device ADC=10
#fuses INTRC_IO,NOPROTECT,BROWNOUT,PUT,MCLR,NOWDT
#use delay(clock=8000000)
#use rs232(baud=19200, PARITY=N, BITS=8, STOP=1,XMIT=PIN_C3) // COM Initialisierung
#define tacho PIN_A5 // Drehzahl Istwert
#define Gate PIN_C5 // Gate for IGBT
#define LED PIN_A1 // LED
int8 dummy8=0;
int16 on_time=20;
#zero_ram
void main()
{
setup_oscillator (OSC_8MHZ);
setup_timer_2(T2_DIV_BY_64, 1022,1); // PWM for Motor Driver
SETUP_CCP1(CCP_PWM | CCP_TIMER2);
SETUP_WDT(WDT_OFF); //WDT
putc(0x0C); // Formfeed
printf("\n\rOK");
SET_PWM1_DUTY(1023-on_time); // Motor is spinning constantly for test
enable_interrupts(global); // everything works fine until IRQ is entered (=> tachogenerator sends pulses)
enable_interrupts(INT_RA5_L2H); // then main loop stucks
while (1)
{
output_toggle(LED); // blinking as long as motor gets voltage and starts spinning....
delay_ms(100);
restart_wdt();
printf("\n\r%u",dummy8);
dummy8++;
restart_wdt();
}
}
#INT_RA
isr_tacho()
{
dummy8=input_a(); // clear IRQ
printf("\n\r%u",dummy8);
}
|
no change! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Fri Sep 20, 2013 9:48 am |
|
|
What compiler version?...
Unlike INT_RB, INT_RA, has individual bit enables. Current compilers will set these, or you can specify exactly what pins to use. Also unlike INT_RB, you can specify which edge to use in the setup. Because of these differences though, the handler also has to clear the IOCAF bits. The compiler will clear the IOC interrupt, but not these bits.
Start with only enabling the interrupt on RA5:
Code: |
enable_interrupts(INT_RA5);
|
Handler will still be INT_RA.
Then add:
Code: |
#BYTE IOCAF = getenv("SFR:IOCAF")
#BIT IOCAF5 = IOCAF.5
//then for the interrupt handler:
#INT_RA
void RA_isr(void)
{
dummy=input(PIN_A5);
IOCAF5=IOCAF5 & 0; //ensure interrupt is not missed if it occurs at this instant
}
|
Best Wishes |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Fri Sep 20, 2013 9:50 am |
|
|
Hi,
OK, basic troubleshooting 101. You have a suspected problem with the 'interrupt on change' for Port A, yet your test program is loaded with
unrelated things, such as the PWM code, the 'restart_wdt' code, etc. My suggestion would be to reduce your test program to the barest essentials
until you resolve *this* issue!
Is the serial port working, and are you seeing the 'OK' being printed, and values for the 'dummy8' variable?
Why are you incrementing the 'dummy8' variable inside the While(1) loop? For now, I'd do that inside the ISR, and then print it inside the While(1) loop.
Also, you really want to get rid of the 'Printf' inside the ISR. Always keep the ISR as short as possible. In your case, clear the interrupt by reading
the port, increment your variable, and get out!
Also, it's probably not critical, but it's good practice to perform the 'global' interrupt enable after individual interrupts are enabled. I mentioned
this before, but you didn't change it!
John |
|
|
mdemuth
Joined: 16 Apr 2007 Posts: 71 Location: Stuttgart, Germany
|
|
Posted: Mon Sep 23, 2013 1:18 am |
|
|
Thanks Ttelmah!
Solved the problem! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Mon Sep 23, 2013 1:34 am |
|
|
Good.
As a comment, the reason I said to only enable the interrupt on the bit your want, is that otherwise the code will hang, if another bit triggers the interrupt. Just a 'caveat'.
Best Wishes. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|