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

Serial communication with 18F4550

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



Joined: 14 Apr 2012
Posts: 3

View user's profile Send private message

Serial communication with 18F4550
PostPosted: Sat Apr 14, 2012 2:54 pm     Reply with quote

Hi all,

To make a long story short, I try to read data from a EM406 GPS module.

This guy continuously sends ascii frames to the serial port.

When you connect the GPS to Hyperterminal (4800-N-1) you can see the message content with position and so on.

I wrote a small piece of code(see below) to grab that message, without success :-(

I tested my serial comm code by sending messages from Hyperterminal to the PIC and there, it works fantastic !

After spending a while testing hardware, baud rate and others basics, I came down to the conclusion that the only difference between the reception from the GPS (that doesn't work) and the reception from Hyperterminal (that works OK) is the fact that the GPS continuously poors a large amount of data to the UART, while Hyperterminal send one character at the time.

This issue of "jamming" the serial port appears on many posts, but despite the helpful tips I found there (the "ERROR" command in the RS232 setting, #INT_RDA interrupt,...) it still doesnt' work !

Is there something more I can do OR do I just reach the limit of what this chip can do ???

Keep in mind that I have no possibility to change the way the GPS module outputs its data.

Thanks for reading
Antoine
Code:

#INT_RDA
void serial_isr()
{
   char cara;
   output_toggle(led4);
   cara = getc();
   if ((RS232_ERRORS & 6)!=0) return;
   putc(cara);
}

void main(){

char c;
// Clear the USART receive register and its fifo
// by reading it three times.
c = RCREG;
c = RCREG;
c = RCREG;


enable_interrupts(global);
enable_interrupts(INT_RDA);


while(TRUE)
{
   
     delay_ms(1);
     
    output_toggle(led3);


}//fin du main

Crying or Very sad
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Sat Apr 14, 2012 3:08 pm     Reply with quote

First, if the UART is hung, reading the buffer _will not clear the condition_. The UART has to be turned 'off', and then 'on' again. Use getc in your boot code.

So:
Code:

void main(void){
 
   char c;
   // Clear the USART receive register
  while (kbhit()) c = getc();


When you add 'ERRORS' to the #USE RS232 line, code is added to the _getc_, to automatically do this and clear the error once triggered.

You don't show your RS232 setup line, so we cannot verify that you have added errors to this.

With this done, you don't need to add anything to do with RS232_ERRORS to your INT_RDA. You only need to read RS232_ERRORS, if you want to do something about errors if they happen.

Realistically, you don't show your code 'using' the value you have read. Assuming something here takes _time_, your INT_RDA, needs to be actually buffering the data (sending it to a larger storage area until you can do something with it EX_SISR.c shows how to do this.

Seriously you don't tell us your clock rate, so comments about what the chip can do, are unanswerable, _but_ to put it into perspective, I have systems logging data from a GPS, and writing data to an SMS, when the unit gets within a specified distance of a target, together with reading other parameters like temperature, using a very basic PIC at 4MHz, and not even working terribly hard.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Apr 14, 2012 3:29 pm     Reply with quote

Here are some RS-232 example programs for 18F2550/ 18F4550:

Without interrupts:
http://www.ccsinfo.com/forum/viewtopic.php?t=37881&start=5
With interrupts:
http://www.ccsinfo.com/forum/viewtopic.php?t=34110&start=5

Note: Change the oscillator fuse and the #use delay() frequency
to match your board.
Antoine1973



Joined: 14 Apr 2012
Posts: 3

View user's profile Send private message

PostPosted: Sat Apr 14, 2012 3:51 pm     Reply with quote

Ttelmah: thx a lot for your advices:

// Clear the USART receive register
while (kbhit()) c = getc();

Helped a lot.

BTW: #use rs232(baud=4800,STOP=1, BITS=8, PARITY=N, ERRORS, UART1)
Antoine1973



Joined: 14 Apr 2012
Posts: 3

View user's profile Send private message

PostPosted: Sun Apr 15, 2012 3:42 am     Reply with quote

Hello all,

It works ! FYI code below.

For Lextronic GPS users: I had to insert a buffer between the GPS output and the RX pin of the pic. The 3V output is too weak to trigger the input pin.

Topic closed.
Code:

#include <18F4550.h>

//configure a 20MHz crystal to operate at 48MHz (USB High speed)
#fuses NOWDT,NOPROTECT,NOLVP,NODEBUG
#fuses PLL5    // Divide 20MHz crystal to feed 4MHz to the PLL
#fuses HSPLL
#fuses CPUDIV1 // PLL Postscaler divides by 2 ==>  Primary clock = 48 MHz
#fuses USBDIV  // Use clock from PLL
#fuses VREGEN    // Enables 3.3V

#use delay(clock=48Mhz)  // 48 MHzPrimary Clock comes from PLL Postscaler
#use rs232(baud=4800,STOP=1, BITS=8, PARITY=N, ERRORS, UART1)   //baud=5050 

#define led1 PIN_A2         //mode  LED1
#define led2 PIN_A4         //curseur ++ ou -- LED2
#define led3 PIN_A3         //memorisation LED3
#define led5 PIN_E0         //bit de vie LED5
#define led4 PIN_A5         //LED4

#include <string.h>

char trame[5];
int i;
char message[21];   
char cara;


#INT_RDA
void serial_isr()
{
cara = getc();
if (cara == '$') {output_toggle(led4);    }   
}


void main(){

char c;

while (kbhit()) c = getc(); 

enable_interrupts(global);
enable_interrupts(INT_RDA);

   while(TRUE)
   {
     delay_ms(10);
     
   output_toggle(led3);
   putc(cara);  // echoes out the received character

   //output_bit(PIN_A5,input(PIN_C7));
   }

}//fin du main
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Sun Apr 15, 2012 6:11 pm     Reply with quote

Hi,

Well, you've solved, one of your problems, the hardware one, but your code still does nothing useful.

BTW, the hardware issue is that the PIC Rx input is a schmitt trigger input, and has different threshold requirements than other PIC inputs. The original 3V signal was not sufficient to reliably trip the input!

For your code, I suggest you look at ex_sisr.c in the examples folder to see how to implement an interrupt driven circular serial buffering system. Such a scheme is probably the only reliable means to receive asynchronous serial data.

John
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