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

2 RS232, how to handle I/O

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



Joined: 03 Feb 2013
Posts: 27
Location: Seattle Area

View user's profile Send private message

2 RS232, how to handle I/O
PostPosted: Fri Aug 21, 2020 5:24 pm     Reply with quote

Hi - On my project, I have two RS232 streams going on at once. Well, at the moment none of them are going on at once. This is a PIC18F25K80, with both streams connected to hardware EUSART pins. At the moment, I'm not getting an interrupt on incoming characters (waiting for that LED to blink!). So, since the XBEE channel doesn't work, evidently there is something wrong in my software.

A bigger question is how do I set it up for both channels to be receiving at once? Seems like INT.RDA only accommodates one interrupt and buffer. I've tried INT_RDA2, it doesn't work either. The compiler doesn't seem to like INT_RDA1 or INT_RDA0. How do you tell the compiler which RDA to use if there are two channels?

I can see the input line going to RB7 wiggle on my scope when I send it a character, but no interrupt occurs. I've successfully transmitted from this same circuit, so I think the hardware is ok.

Any thoughts would be appreciated.

My code is shown in my next post, it currently won't find input characters:


Last edited by OldGuy on Fri Aug 21, 2020 6:19 pm; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 9228
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Aug 21, 2020 5:33 pm     Reply with quote

from my foggy memory...so are 14 hr days..

you need two ISRs....

int_rda is the first serial port
int_rda1 is the 2nd serial port.

if you press F11, when using MPLAB, the CCs C manual magically opens up. find the 'preprocessor' tab (?), find INT_RDA... it's there 'somewhere'.

I know it does work.... I had a 46k22 tied in a double loopback test ( PC>uart1>uart2>uart1>pc and with double buffers got 115k200 serial without a problem....

other will reply, maybe with a small test program for you... I need some zz's

Jay
OldGuy



Joined: 03 Feb 2013
Posts: 27
Location: Seattle Area

View user's profile Send private message

PostPosted: Fri Aug 21, 2020 6:15 pm     Reply with quote

Thanks for your tired thoughts Jay.

So RDA is EUSART 1 and RDA2 is EUSART 2? Defined by the pin numbers in the Use RS232?

That would make sense, and be easy to accommodate if I can figure out why it isn't capturing RDA.

Any further thoughts appreciated.

I think I posted my code wrong initially, I'll try it again:



Code:

#include <18F25K80.h>  // this also does the #device PIC18F25K0


// the fuses specify use of external 16 MHz oscillator
#use     delay (clock=16MHZ)
#fuses   NOWDT, HSH, NOPUT, NOPROTECT, NOWDT, NOPLLEN

// set up the RS-232 channels
#use rs232 (stream=SOUNDER, baud=4800, xmit=PIN_C6, rcv=PIN_C7, PARITY=N, BITS=8, ERRORS)  // Sounder in 0813 RS-232 mode
#use rs232 (stream=XBEE,    baud=9600, xmit=PIN_B6, rcv=PIN_B7, PARITY=N, BITS=8, ERRORS)  // XBee to shore

 
#include <stdlib.h>

#define  LED           PIN_A1  // pin 2, signal RA1/AN1 - low to turn on LED
#define  OFF           0  // for reel and LED control
#define  ON            1  // for LED
#define  IN            2  // reel
#define  OUT           3  // reel
#define  BUFFER_SIZE  32

char buffer[BUFFER_SIZE];
char next_in  = 0;
char next_out = 0;

char char_received = ' ';

// LED on or off
Void LED1 (what) {
   if (what == OFF) output_high (LED);
   if (what == ON)  output_low (LED);
   }
   
 // blink the LED for the specified number of mS (500mS if zero)
 Void LED1_Blink (int16 how_long) {
    LED1(ON);
    if (how_long == 0)
       Delay_MS (500);
    else
       DELAY_MS(how_long);
    LED1(OFF);
    }

#define bkbhit (next_in!=next_out)

BYTE bgetc() {
   BYTE c;
   while(!bkbhit);
   c=buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}


#int_rda
void serial_isr() {
   LED1_blink(0);
   int t;
   buffer[next_in]=bgetc();
   if (buffer[next_in] == 'O') LED1_blink(0);
   if (buffer[next_in] == 'I') LED1_blink(0);
   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   if(next_in==next_out)
      next_in=t;           // Buffer full !!
}


   
void main (void) {


   char_received       = ' ';

   LED1_Blink (0);           // LED on for a little bit to know we're running

   // XBEE input interrupt
   enable_interrupts (INT_RDA);
   enable_interrupts (global);
   
   // now we just sit here and loop, gathering data
   while (TRUE) {

     delay_ms(500);  // don't loop too fast
     
     // see if anything arrives via xBee
     if (bkbhit) char_received = bgetc();         
 
     if (char_received == 'I') led1_blink(0);
     if (char_received == 'O') led1_blink(0);

   }

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 21, 2020 6:49 pm     Reply with quote

Your code is badly wrong. Look at the .LST file.
Quote:

....... // set up the RS-232 channels
....... #use rs232 (stream=SOUNDER, baud=4800, xmit=PIN_C6, rcv=PIN_C7, PARITY=N, BITS=8, ERRORS) // Sounder in 0813 RS-232 mode
........ #use rs232 (stream=XBEE, baud=9600, xmit=PIN_B6, rcv=PIN_B7, PARITY=N, BITS=8, ERRORS) // XBee to shore
........

The compiler is not generating any code for either UART.

You don't have any calls to fgetc() in your rda isrs. Without that, you won't
receive and characters. Study Ex_Sisr.c. Notice the isr doesn't call bgetc().
It calls getc(). For streams you need to use fgetc() and specify the stream
as the parameter.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 21, 2020 6:53 pm     Reply with quote

temtronic wrote:

int_rda is the first serial port
int_rda1 is the 2nd serial port.

temtronic,
Why don't you just pull up the .h file before answering ? What good is a
bum answer ? If you look at the .h file, you see it's RDA and RDA2
Here is the list of ints from the .h file:
Quote:
#define INT_EXT2 0x00F010
#define INT_RB 0x01FFF208
#define INT_AD 0x009D40
#define INT_RDA 0x009D20
#define INT_TBE 0x009D10
#define INT_SSP 0x009D08
#define INT_BUSCOL 0x00A008
#define INT_RDA2 0x00A320
#define INT_TBE2 0x00A310
#define INT_OSCF 0x00A080
OldGuy



Joined: 03 Feb 2013
Posts: 27
Location: Seattle Area

View user's profile Send private message

PostPosted: Fri Aug 21, 2020 7:07 pm     Reply with quote

I fixed that erroneous call bgetc, still no luck after changing it to getc(XBEE) or fgetc(XBEE). On another device I've done with a different PIC it works fine with getc().
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 21, 2020 7:09 pm     Reply with quote

Post your revised program.
OldGuy



Joined: 03 Feb 2013
Posts: 27
Location: Seattle Area

View user's profile Send private message

PostPosted: Fri Aug 21, 2020 7:13 pm     Reply with quote

Here's the current program...

Code:

#include <18F25K80.h>  // this also does the #device PIC18F25K0


// the fuses specify use of external 16 MHz oscillator
#use     delay (clock=16MHZ)
#fuses   NOWDT, HSH, NOPUT, NOPROTECT, NOWDT, NOPLLEN

// set up the RS-232 channels
#use rs232 (stream=SOUNDER, baud=4800, xmit=PIN_C6, rcv=PIN_C7, PARITY=N, BITS=8, ERRORS)  // Sounder in 0813 RS-232 mode
#use rs232 (stream=XBEE,    baud=9600, xmit=PIN_B6, rcv=PIN_B7, PARITY=N, BITS=8, ERRORS)  // XBee to shore

 
#include <stdlib.h>

#define  LED           PIN_A1  // pin 2, signal RA1/AN1 - low to turn on LED
#define  OFF           0  // for reel and LED control
#define  ON            1  // for LED

// RS232 Buffer
#define  BUFFER_SIZE  32
char buffer[BUFFER_SIZE];
char next_in  = 0;
char next_out = 0;
char char_received = ' ';

// LED on or off
Void LED1 (what) {
   if (what == OFF) output_high (LED);
   if (what == ON)  output_low (LED);
}
   
 // blink the LED for the specified number of mS (500mS if zero)
 Void LED1_Blink (int16 how_long) {
    LED1(ON);
    if (how_long == 0)
       Delay_MS (500);
    else
       DELAY_MS(how_long);
    LED1(OFF);
 }

#define bkbhit (next_in!=next_out)

BYTE bgetc() {
   BYTE c;
   while(!bkbhit);
   c=buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}


#int_rda
void serial_isr() {
   LED1(ON);
 
   int t;
   buffer[next_in]=fgetc(XBEE);  // also tried getc() and fgetc()

   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   if(next_in==next_out)
      next_in=t;           // Buffer full !!
}


   
void main (void) {

   LED1_Blink (0);           // LED on for a little bit to know we're running

   // XBEE input interrupt
   enable_interrupts (INT_RDA);
   enable_interrupts (global);
   
   // now we just sit here and loop, gathering data
   while (TRUE) {

     delay_ms(500);  // don't loop too fast
     
     // see if anything arrives via xBee
     if (bkbhit) char_received = bgetc();         
 
     if (char_received == 'I') led1_blink(0);
     if (char_received == 'O') led1_blink(0);

   }

}
[/quote]
OldGuy



Joined: 03 Feb 2013
Posts: 27
Location: Seattle Area

View user's profile Send private message

Got it!
PostPosted: Fri Aug 21, 2020 7:57 pm     Reply with quote

I found that by switching to INT_RDA2 it works with the following code. I may have missed this working earlier, if I forgot to unplug the ICD-U64. It also wants to use the same line as incoming RS232, and screws up the signal unless I unplug it each time. Once in a while I forget.

I'm going to presume that I'll use INT_RDA for the other RS232 I/O. Sound correct?

Thank you for your time to give me tips to come to a solution!

Brian


Code:

#include <18F25K80.h>  // this also does the #device PIC18F25K0 
#include <stdlib.h>

// the fuses specify use of external 16 MHz oscillator
#use     delay (clock=16MHZ)
#fuses   NOWDT, HSH, NOPUT, NOPROTECT, NOWDT, NOPLLEN

// set up the RS-232 channels
#use rs232 (stream=SOUNDER, baud=4800, xmit=PIN_C6, rcv=PIN_C7, PARITY=N, BITS=8, ERRORS)  // Sounder in 0813 RS-232 mode
#use rs232 (stream=XBEE,    baud=9600, xmit=PIN_B6, rcv=PIN_B7, PARITY=N, BITS=8, ERRORS)  // XBee to shore

#define  LED           PIN_A1  // pin 2, signal RA1/AN1 - low to turn on LED
#define  OFF           0  // for reel and LED control
#define  ON            1  // for LED

// RS232 Buffer
#define  BUFFER_SIZE  32
char buffer[BUFFER_SIZE];
char next_in  = 0;
char next_out = 0;
char char_received = ' ';

// LED on or off
Void LED1 (what) {
   if (what == OFF) output_high (LED);
   if (what == ON)  output_low (LED);
}
   
 // blink the LED for the specified number of mS (500mS if zero)
 Void LED1_Blink (int16 how_long) {
    LED1(ON);
    if (how_long == 0)
       Delay_ms (500);
    else
       Delay_ms (how_long);
    LED1(OFF);
 }

#define bkbhit (next_in!=next_out)

BYTE bgetc() {
   BYTE c;
   while(!bkbhit);
   c=buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}


#int_rda2
void serial_isr() {
   //LED1(ON);
 
   int t;
   buffer[next_in]=fgetc(XBEE);  // also tried getc() and fgetc()

   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   if(next_in==next_out)
      next_in=t;           // Buffer full !!
}


   
void main (void) {

   LED1_Blink (0);           // LED on for a little bit to know we're running

   // XBEE input interrupt
   enable_interrupts (INT_RDA2);
   enable_interrupts (global);
   
   // now we just sit here and loop, gathering data
   while (TRUE) {

     delay_ms(500);  // don't loop too fast
     
     // see if anything arrives via xBee
     if (bkbhit) char_received = bgetc();         
 
     if (char_received == 'I')  led1_blink(0);   char_received = ' ';
     if (char_received == 'O')  led1_blink(250); char_received = ' ';
     char_received = ' ';
   }

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Got it!
PostPosted: Fri Aug 21, 2020 9:01 pm     Reply with quote

[quote="OldGuy"
I'm going to presume that I'll use INT_RDA for the other RS232 I/O. Sound correct?
[/quote]
Yes, INT_RDA is associated with UART1 on pins C6 and C7.
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Sat Aug 22, 2020 1:32 am     Reply with quote

As a 'comment', I'd suggest not using the pin numbers.
Issues are:
1) Easy to get them wrong.
2) The numbers do nothing to tell you which stream is which UART,
3) On chips where the UART uses PPS, the pin numbers will result in
a software UART being setup, so no interrupt.

If instead, you use the UART name, the code tells you at once which UART
is being used by which stream:
Code:

//uses pin C6 for TX and C7 for RX, INT_RDA
#use rs232 (stream=SOUNDER, baud=4800, UART1, PARITY=N, BITS=8, ERRORS)  // Sounder in 0813 RS-232 mode
//Uses B6 for TX and B7 for RX, INT_RDA2
#use rs232 (stream=XBEE,    baud=9600, UART2, PARITY=N, BITS=8, ERRORS)  // XBee to shore


Adding the remark, reminds you which pins are involved.
Then if you switch to a chip that uses PPS, the compiler will nicely tell you
that the pins need to be setup before you can use the UART.
This way you have a nice reminder of which stream uses which physical
UART. Very Happy
OldGuy



Joined: 03 Feb 2013
Posts: 27
Location: Seattle Area

View user's profile Send private message

PostPosted: Sat Aug 22, 2020 7:31 am     Reply with quote

Thanks for the tips Ttelmah. Makes sense.
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