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

2 RS232 in the same PIC

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



Joined: 14 Aug 2012
Posts: 30
Location: France

View user's profile Send private message

2 RS232 in the same PIC
PostPosted: Tue Aug 14, 2012 8:36 am     Reply with quote

Hello,

I'm using a PIC18F2523 and would like to have 2 port RS232. the first will be connected to a computer and the second to other card.

The first one is software on RB2, RB4 (INT_RB). The second is hardware and connected to UART on RC6, RC7 (INT_RDA).

In my software with a signal of the PIC (INTERLOCK_RS232) I activate the software or the hardware RS232.

I test the software communication first and it's working well. I would like to add the other one but the first isn't working anymore.

I explain on example:
Code:
while(1)
    {
    if(input(INTERLOCK_RS232))
     {
     #use rs232(baud=9600, parity=N,stop=1,xmit=PIN_C6,rcv=PIN_C7,bits=8, errors)
     output_low(LED_REV);
     printf("A");
     }
    else                                         
     {
     #use rs232(baud=4800, parity=N,stop=1,xmit=PIN_B2,rcv=PIN_B4,bits=8, disable_ints, force_sw, errors)
     output_high(LED_REV);
     printf("B");
     }
This is working well : the baud change and the TX and RX change Pin well. I visiualize it with a scope.

But When I want to use an int RB or RDA, the software RS232 doesn't work anymore.

Code:
#int_rda
void serial_RS485()
    {
    byte i;
   
    if (kbhit())
     {
     buffer_RS232[pointeur_RS232]=getc();
     pointeur_RS232++;
     if (pointeur_RS232>=20)                     //Buffer plein
      {
      for (i=0;i<=24;i++)                        // Init buffer RS232
       buffer_RS232[i]=0x30;
      pointeur_RS232=0;
      }
     }
    }

#INT_RB
void  serial_RS232(void)
   {
   byte i;

   if (kbhit())
    {
    buffer_RS232[pointeur_RS232]=getc();
    pointeur_RS232++;
    }
     
   if (pointeur_RS232==size_rs232)               //Buffer plein
    {
    for (i=0;i<size_rs232;i++)                   // Init buffer RS232
     buffer_RS232[i]=0x30;
    pointeur_RS232=0;
    }
   }


First I try this and TX (RB2 and RC6) are always high the printf function doesn't work anymore:

Code:
main()
 {
....
   while(1)
    {
    if(input(INTERLOCK_RS232))                 
     {
     #use rs232(baud=9600, parity=N,stop=1,xmit=PIN_C6,rcv=PIN_C7,bits=8, errors)
     disable_interrupts(INT_RB);
     enable_interrupts(INT_RDA);
     output_low(LED_REV);
     printf("A");
     }
    else                                     
     {
     #use rs232(baud=4800, parity=N,stop=1,xmit=PIN_B2,rcv=PIN_B4,bits=8, disable_ints, force_sw, errors)
     enable_interrupts(INT_RB);
     disable_interrupts(INT_RDA);
     output_high(LED_REV);
     printf("B");
     }
    RS232();
}


Do you have an idea on what's hapen?

Thanks

Fabrice
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Tue Aug 14, 2012 2:17 pm     Reply with quote

Use streams.

The #use RS232 switching, only allows one RS232 version to work at a time. Hence the other stops working.

This is what streams are _for_....

Best Wishes
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Tue Aug 14, 2012 10:37 pm     Reply with quote

And if you want TRUE dual RS232 operation, you need a PIC with 2 hardware UARTs.

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
neo19



Joined: 14 Aug 2012
Posts: 30
Location: France

View user's profile Send private message

PostPosted: Thu Aug 16, 2012 1:09 am     Reply with quote

Dear Ttelmah,

thanks for your answer.

So I try to use streams. It's better :
The fprintf towards RS232 or 485 is now working but not the INT.

Code:
#use rs232(baud=9600, parity=N,stop=1,xmit=PIN_C6,rcv=PIN_C7,bits=8, errors, stream=RS_485)
#use rs232(baud=4800, parity=N,stop=1,xmit=PIN_B2,rcv=PIN_B4,bits=8, disable_ints, force_sw, errors, stream=RS_232)

#int_rda
void serial_RS485()
    {
    byte i;
   
    if (kbhit(RS_485))
     {
     buffer_RS232[pointeur_RS232]=fgetc(RS_485);
     pointeur_RS232++;
     if (pointeur_RS232>=20)                     //Buffer plein
      {
      for (i=0;i<=24;i++)                        // Init buffer RS232
       buffer_RS232[i]=0x30;
      pointeur_RS232=0;
      }
     }
    }

#INT_RB
void  serial_RS232(void)
   {
   byte i;

   if (kbhit(RS_232))
    {
    buffer_RS232[pointeur_RS232]=fgetc(RS_232);
    pointeur_RS232++;
    }
     
   if (pointeur_RS232==size_rs232)               //Buffer plein
    {
    for (i=0;i<size_rs232;i++)                   // Init buffer RS232
     buffer_RS232[i]=0x30;
    pointeur_RS232=0;
    }
   }

main()
....
    if(input(INTERLOCK_RS232))     
     {
     disable_interrupts(INT_RB);
     enable_interrupts(INT_RDA);
     output_low(LED_REV);
     fprintf(rs_485,"A");
     }
    else
     {
     enable_interrupts(INT_RB);
     disable_interrupts(INT_RDA);
     output_high(LED_REV);
     fprintf(rs_232,"B");
     }


Best regards,

Fabrice


Last edited by neo19 on Thu Aug 16, 2012 1:40 am; edited 2 times in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Thu Aug 16, 2012 1:24 am     Reply with quote

Several little comments/problems:

1) You don't need to test kbhit in the int_rda. The interrupt says 'a character is waiting to be read'. Pointless, and costs time.
2) INT_RB, says 'input line on port b has changed state'. Now, without knowing your hardware, can this be triggered without the line being used for serial having changed?. This would then give kbhit(RS_232), not being true. Problem then is that you _must_ read port_b to clear the interrupt, or the code will hang. Most likely problem.
3) You have a real problem if data can arrive on both ports at the same time (seems not to be the case judging by your 'interlock' use. Because your 'software' serial port on INT_RB, is only at 4800bps, the time needed to handle this can be twice the time needed for a byte to arrive on the UART serial. Since there is less than two characters of buffering on the hardware serial, data will then be lost. This is made worse by having prints in the interrupt handler. Is it possible to swap the streams, so the hardware stream is the slower one?. Set a flag, and do all printing outside the ISR's.
4) There is also a problem sending any print inside the INT_RB handler, or even printing at all on this serial. CCS software serial, is _half duplex_ data can only go in one direction at a time. If anything arrives while you are printing, this will trigger the interrupt handler to be called again after the byte has been sent, the kbhit will test as false (since the transmission will have finished), and the port will not be read, hanging the serial....


Best Wishes
neo19



Joined: 14 Aug 2012
Posts: 30
Location: France

View user's profile Send private message

PostPosted: Thu Aug 16, 2012 2:16 am     Reply with quote

for your different comments:

1) interesting for optimizing my code. I will delete it and try again
2) the int_Rb was working very well but solo without int rda
3) Data can't arrive at the same time on both ports. It was not define like that.
only one at each time.
4)I modify my post. the fprintf with the interlock is in the main part. it was only to test the stream.

fabrice
neo19



Joined: 14 Aug 2012
Posts: 30
Location: France

View user's profile Send private message

PostPosted: Thu Aug 16, 2012 6:35 am     Reply with quote

Dear Telmah,

I thought it was so easy to use not as the same time a UART and software RS232.

So, as I only use one communication at the time I will only use UART with a little relay to connect the PC or internal RS485.

Thanks

Fabrice
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