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

CCS C send string data with using interrupt

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



Joined: 31 May 2012
Posts: 10

View user's profile Send private message

CCS C send string data with using interrupt
PostPosted: Wed Aug 06, 2014 2:00 am     Reply with quote

Hi,
I am getting some data over serial and I want to send (random) Gps data when coming data equals 'A'.Unfortunately, I can not send more than 15 character always.If my string size lower as char data="123465789012"; it works properly, does not freeze pic and others.If my string size getting bigger as data="123465789012345";, pic send this data just one time then system is freezing and not respond.

I want to show to you what I have done and what I got;

Code:
#int_rda
{
...
e=getch();
if(e=='A')
      {
    char       gps[]="$GPGGA,111111.111,1111.1110,N,01111.0111,E,1,09,1,9,111,M,1,M,,*1E";
       output_high(pin_d0);
    --------------------------------------------
       printf("Work");   //pic sends to serial, sytems working properly
    --------------------------------------------
       putc('c');   //pic sends, sytems working properly
    --------------------------------------------
       printf(gps);   //sends ONE times to serial, then not send same data and system  freezes
    --------------------------------------------
       puts(gps);   //sends ONE times to serial, then not send same data and system  freezes
       --------------------------------------------
       for(i=0;i<65;i++)
       {
       printf(gps[i]);   //sends ONE times to serial, then not send same data and system  freezes
       }
       ---------------------------------------------
       puts("wasejdhdjefvcbjhwvbsjhbjhaehdjvfbasdöjbfv");   sends ONE times to serial, then not send same data and system  freezesr
    --------------------------------------------
     putc('1');
          putc('2');
           putc('3');
            putc('4');
             putc('5');
              putc('6');
               putc('7');
                putc('8');
                 putc('9');
                  putc('0');
                   putc('1');
                    putc('2');
                     putc('3');     //pic sends one times, sytems working properly
                   
    ---------------------------------------------------
        putc('1');
          putc('2');
           putc('3');
            putc('4');
             putc('5');
              putc('6');
               putc('7');
                putc('8');
                 putc('9');
                  putc('0');
                   putc('1');
                    putc('2');
                     putc('3');
                      putc('4');
                        putc('5');   //sends TWO times (very interestingly) to serial, then not send same data and system  freezes
----------------------------------------------------------------------
for(i=0;i<67;i++)
        {
        printf("%c",gps[i]);  //sends ONE times to serial, then not send same data and system  freezes
       
        }
---------------------------------------------------------------------
        printf("%s",gps);  //sends ONE times to serial, then not send same data and system  freezes
      }
      if(e=='B')
      {
         output_low(pin_d0); //
      }

}

------------------------------------------------------------------------------

Question2 (not related with title)
Just assume I have 3 GPS(different types) and I want to see/show coming data from Gps's. How can I get coming datas from GPSs.
Code:
Method1
fgets(gps1,iletisim_1);   //iletisim1 1.rs232
fgets(gps2,iletisim_2);   //iletisim2 2.rs232

Method2
gps1=fgetc(iletisim_1);   //for will be use
gps2=fgetc(iletisim_2);
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

Re: CCS C send string data with using interrupt
PostPosted: Wed Aug 06, 2014 2:27 am     Reply with quote

This is a classic example of how NOT to write an interrupt handler.

For this class of application you would typically implement a ring buffer in the receive interrupt handler. The code is short and sweet. Get the received character, put it in the ring buffer, return from interrupt.

Then in the mainline code test if the ring buffer has anything in it, if so, go process it.

There are lots of examples, supplied with the compiler, in the forum, available on the internet.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!


Last edited by asmallri on Wed Aug 06, 2014 3:03 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19328

View user's profile Send private message

PostPosted: Wed Aug 06, 2014 2:47 am     Reply with quote

You need to understand time....

The PIC has just two characters of hardware buffering on output. If you arrive at the interrupt, and this is empty, two characters can be send almost immediately, but everything beyond this, has to wait for a character to be sent, before proceeding. Now, the receive also has a couple of characters of buffering, and the serial from the GPS, is probably not quite 'non stop', but after a certain number of characters (in your case 15), you will reach the point, where all the buffers are full, and if another character arrives at this time, the UART will then become hung....

So you always need ideally to get out of the ISR, before another character arrives.

There are two ways of doing this:
1) When data is to be sent, you set a flag, and then send this data in the main code.
2) You put the data to send into a buffer, and use an interrupt driven transmit.
3) Just store the character received, and do the entire job in the outside code.

CCS supplies an example of the second, in ex_stisr.c, and the core of the third in ex_sisr.c.

However there is then the question of whether you send anything else in the 'outside' code.
If you do, you can't use (directly) the buffered putc (from the example), inside the interrupt. There are ways of doing this, but it involves very careful control of the enable for the transmit interrupt, and possibly having two copies of the buffer write code, one for inside interrupts, and one for outside. Needs good understanding of what you are doing.
Easier probably to use method 1, or method 3 at this point.

On question 2, if you are using interrupt driven RX, you wouldn't use either approach shown.
Instead you would look for the start of message character, and then write the received data as it arrives, character at a time to a storage buffer, and when you see the end of line character, set a flag to say 'message received'.
Then look at the message in your main code when this flag is set (remember to clear the flag).
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