|
|
View previous topic :: View next topic |
Author |
Message |
neo19
Joined: 14 Aug 2012 Posts: 30 Location: France
|
2 RS232 in the same PIC |
Posted: Tue Aug 14, 2012 8:36 am |
|
|
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: 19499
|
|
Posted: Tue Aug 14, 2012 2:17 pm |
|
|
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: 1615 Location: Central Illinois, USA
|
|
Posted: Tue Aug 14, 2012 10:37 pm |
|
|
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
|
|
Posted: Thu Aug 16, 2012 1:09 am |
|
|
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: 19499
|
|
Posted: Thu Aug 16, 2012 1:24 am |
|
|
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
|
|
Posted: Thu Aug 16, 2012 2:16 am |
|
|
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
|
|
Posted: Thu Aug 16, 2012 6:35 am |
|
|
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 |
|
|
|
|
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
|