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 support@ccsinfo.com

#INT_RDA interrupt problem

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



Joined: 05 Aug 2008
Posts: 11

View user's profile Send private message

#INT_RDA interrupt problem
PostPosted: Sun Oct 04, 2009 1:33 am     Reply with quote

Hi,

I am trying to configure my PIC18F2550 for receiving GPS data.

I figured out that the external interrupts are working fine but the serial interrupt is not working at all. The clock is well configured and there seems to be some problem in serial interrupt configuration.

Here is the code for the same.

Code:

#include <18F2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOMCLR,USBDIV,PLL5,CPUDIV4,VREGEN
#use delay(clock=16000000)
#use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
char gps_data[5];
long data_counter = 0;

void main(void) {
   LED_ON(LED2);
   LED_ON(LED3); 
   
   ext_int_edge(H_TO_L);     
   
   // init interrupt triggering for button press
   enable_interrupts(GLOBAL);
   
   // Enable serial interrupt
   enable_interrupts(INT_RDA);
   // Enable ext0 interrupt
   enable_interrupts(INT_EXT);
   // Enable ext1 interrupt
   enable_interrupts(INT_EXT1);

   nokia_init();

   while (TRUE) {
   }

#int_rda
void rda_isr()
{
   char c;
   gps_data[data_counter] = getch();
   data_counter++;
   if(data_counter==5)
   {
   nokia_clear_screen();
   nokia_gotoxy(0,1);
   printf(nokia_printchar,"Interrupt");
   delay_ms(500);
   data_counter=0;
   }
   clear_interrupt(int_RDA);
}

#int_ext
void EXT0_isr()
{
nokia_clear_screen();
nokia_gotoxy(0,1);
printf(nokia_printchar,"EXT0 int");
delay_ms(1000);
}

#int_ext1
void EXT1_isr()
{
nokia_clear_screen();
nokia_gotoxy(0,1);
printf(nokia_printchar,"EXT1int");
delay_ms(1000);
}
akshaymathur39



Joined: 05 Aug 2008
Posts: 11

View user's profile Send private message

PostPosted: Sun Oct 04, 2009 2:14 am     Reply with quote

I just tried this code:

Code:
int8 i=1;
char c;
   
#int_RDA
void RDA_int()
{
   c=getc();
   i++;
   nokia_clear_screen();
   nokia_gotoxy(0,1);
   printf(nokia_printchar,"Interrupt %i",i);
   delay_ms(500);
   clear_interrupt(int_rda);
}

#int_ext
void search_isr()
{
nokia_clear_screen();
nokia_gotoxy(0,1);
printf(nokia_printchar,"Search int");
delay_ms(1000);
   clear_interrupt(int_ext);
}

#int_ext1
void backlight_isr()
{
nokia_clear_screen();
nokia_gotoxy(0,1);
printf(nokia_printchar,"Backlight int");
delay_ms(1000);
clear_interrupt(int_ext1);
}

void main(void) {
   LED_OFF(LED3);
   LED_ON(LED2);   
   
   nokia_init();
   ext_int_edge(H_TO_L);     
   
   // init interrupt triggering for button press
   enable_interrupts(GLOBAL);
   
   // Enable serial interrupt
   clear_interrupt(INT_RDA); enable_interrupts(INT_RDA);
   // Enable ext0 interrupt
   clear_interrupt(INT_EXT); enable_interrupts(INT_EXT);
   // Enable ext1 interrupt
   clear_interrupt(INT_EXT1); enable_interrupts(INT_EXT1);
   
   delay_ms(3000);
   
   LED_ON(LED3);


   while (TRUE) {
   
   }
}


It display following:
Interrupt 2
Interrupt 3
Interrupt 4

Can anybody please be of some help.
Ttelmah
Guest







PostPosted: Sun Oct 04, 2009 2:30 am     Reply with quote

First thing, add the keyword 'errors' to your #use RS232 declaration.
This is particularly 'vital', becaue of your INT_RDA, which breaks a whole crop of 'guidelines'....

Basically, you should get out of ISR's as quickly as possible, unless you know _exactly_ what you are doing. In your case, on the fifth character, you will stay in the ISR, for a huge time. 500mSec, plus the time to clear the display, write a message, etc. etc.. If more serial characters are received wqhile this is going on, the ISR can't be called, and these will lockup the UART _permanently_. Adding errors, will generate the code to clear this lockup, but not get rid of the basic 'cause' - set a flag in the ISR, and do all these slow operations in the main, when this is set. This then gets 'worse', since your code sits for over a second, in each of the other interrupt handlers....

Then, I'd 'guess' that the nokia routines, almost certainly use a subroutine, to actually write bytes to the display controller. This is probably used inside the nokia_init routine, and inside each of the display routines as well. If so, then interrupts _will_ be disabled in the main code, inside these routines. It won't as it stands cause a problem (except if interrupts trigger during the nokia_init), at present, since yourmain wait loop, does not try to perform any 'display', but in future _will_ cause problems. Same comment applies, don't perform display operations or delays inside the interrupts.

Recite 100 times. An ISR, should _only_ handle the actual interrupt 'event'. Keep everything else 'outside' the ISR.

Don't use 16bit counters, unless they are needed. An int8, is handled _faster_. Make your data counter 8bit, unless you are expecting more than 255 bytes of data.

Best Wishes
akshaymathur
Guest







PostPosted: Sun Oct 04, 2009 12:28 pm     Reply with quote

Hi!

Thanks for your reply. I added "errors" keyword in the #use RS232 statement.

But all I am receiving is not the actual string coming from GPS module but some random values like " ~x'A' ".

Can you please help me to refine the program.

Awaiting replies.
Jeff7



Joined: 22 Sep 2009
Posts: 13

View user's profile Send private message

PostPosted: Sun Oct 04, 2009 12:34 pm     Reply with quote

Definitely do get rid of any delay_ms and printf's inside the interrupt.
Get the data first, maybe send the data to a holding array, and then afterward print out what's inside the array.
At least that's been my approach.
And of course ensure that your module is also communicating at 4800bps.


I'm working on something similar actually. I kind of came into the project after a lot of the coding had been done, but our GPS modules were problematic, and I was told to basically do a redesign, with "make it work" as the ultimate goal. Smile
This device only needed to get data occasionally though, to keep some clock code in the PIC synced up and accurate; the PIC was usually busy doing various other things.

The code that was there acquired the data without the use of an interrupt.
Every few seconds it would do a check on the RX pin using a while-loop and kbhit to look for data.
(I'm not sure if the timed_getc() function is part of the normal CCS package, and thus falls under the "no-post copyrighted" clause of the posting rules. If it is included, I think it would be in comms.h.)


That function was called from within a while loop that was running with a timer - if it didn't get the data it was looking for within about 200mS, it exited, and would try again later.

Code:

   gps_break = 0;
   while (true && gps_break < 3)
   {
      if (timed_getd() == '$')
      {
         timed_getD();  // G
         timed_getD();  // P
         if (timed_getd() == 'R')
         {
           for (i=3;i<71;i++)
           {
              comms[i] = timed_getd();
           }
           comms[0] = 'G';
           comms[1] = 'P';           
           comms[2] = 'R';
           read_counter = 0;
           gps_break = 0;
           break;
         }
      }
   }


The data packets from this module always start with $ and then they give an identifier as to the kind of data (GPGSV, GPRMC, etc). This would look for the RMC packet, and then retrieve the full string for processing.

On occasion it would get garbled data, but there was a checksum function later on to first calculate the checksum of the data between the $ and * in the string, and compare it to the one read from the data packet. If it failed the test, the get_time function simply exited; otherwise, it would continue on and extract the time information.


On a side note, I was also able to send a command to the GPS module, speeding it up from 4800bps to 38400bps. I don't remember the exact times (they're written down in a notebook somewhere at work), but it was taking somewhere around a full half-second just to transfer this big chunk of data. Upping the speed helped reduce that considerably.
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