CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

#int_ra is not cleared (solved)

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
mdemuth



Joined: 16 Apr 2007
Posts: 71
Location: Stuttgart, Germany

View user's profile Send private message Visit poster's website

#int_ra is not cleared (solved)
PostPosted: Fri Sep 20, 2013 6:11 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Sep 20, 2013 6:57 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Fri Sep 20, 2013 8:09 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Sep 20, 2013 9:48 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Sep 20, 2013 9:50 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Mon Sep 23, 2013 1:18 am     Reply with quote

Thanks Ttelmah!
Code:
 IOCAF5=IOCAF5 & 0; 

Solved the problem!
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Mon Sep 23, 2013 1:34 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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