|
|
View previous topic :: View next topic |
Author |
Message |
ALCION
Joined: 31 May 2007 Posts: 16
|
PIC18F26K22 + 2 PORT RS232 + INT |
Posted: Sun Jan 18, 2015 8:44 pm |
|
|
hi, in a project need to use 2 RS232 serial ports used a PIC16F886 and had hw port and another sw but I want to try with 2 ports for hw.
Anyone have any example of how to configure the two RS232 hw ports and which interrupts use?
I see that there is only one Int_RDA I can not use Int_RDA1
I use MPLAB 8.80 and CCS vr 4,140
Thank You! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
ALCION
Joined: 31 May 2007 Posts: 16
|
|
Posted: Sun Jan 25, 2015 5:25 pm |
|
|
Thanks PCM programmer and excuse the delay in responding but was testing, the example you send me works well, but still have problems using two rs232, I use a pic18f26k22 and each serial port I connect to a lap top via a USB-RS232 converter.
The problem is that it is frozen and does not send any data.
you have any example where hw 2 serial ports are used?
Thanks for the support. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jan 25, 2015 7:14 pm |
|
|
Explain what you are doing, in detail.
Do you have two USB-to-RS232 converter cables ?
Is each cable connected to a different USB connector on your laptop ?
Does each cable connect to a MAX232 chip on your PIC board ?
What software are you using on the laptop ? Are you running two
instances of TeraTerm simultaneously, with each one configured for
a different COMx port ?
How do you know what ports the USB-to-serial converters are using ?
Have you checked in Windows Device Manager to see what COM ports
have been assigned to the USB-to-Serial converters ?
The above is my guess of your test setup. If it's not true, then you need
to describe the actual setup in detail. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Jan 26, 2015 2:13 am |
|
|
This was originally written in a V4 compiler. Now using V5.
Code: |
//your processor include and fuses here
//your clock setup here
#use rs232(baud=9600,parity=N,UART1,bits=8,stream=PORT1,errors) //U1
#use rs232(baud=57600,parity=N,UART2,bits=8,stream=PORT2,errors) //U2
//This is using Uart1 at 9600bps, and Uart2 at 57600bps
//Buffer tests and handling - actually in a separate file 'serial_buffer.h' for me
char btempU1RX,btempU2RX,btempU1TX,btempU2TX;
#define SIBUFF (32) //buffer sizes
typedef struct {
unsigned int8 in;
unsigned int8 out;
char buff[SIBUFF];
} buffer; //definition of a 'buffer' data type
buffer U1RX,U1TX,U2RX,U2TX; //four 32byte buffers
//macros to handle the buffer operations
#define incin(buff) ((buff.in==(SIBUFF-1))?0:buff.in+1)
#define incout(buff) ((buff.out==(SIBUFF-1))?0:buff.out+1)
#define isempty(buff) (buff.in==buff.out)
#define hasdata(buff) (buff.in!=buff.out)
#define isfull(buff) ((incin(buff)==buff.out)
#define tobuff(bname,c) { bname.buff[bname.in]=c;\
bname.in=incin(bname);\
if (bname.in==bname.out) bname.out=incout(bname);\
}
#define frombuff(bname) (btemp##bname=bname.buff[bname.out],\
bname.out=incout(bname), \
btemp##bname)
//note the building of the temporary variable name here
#define clrbuff(buff) buff.in=buff.out=0
#define bkbhit(BUFF) hasdata(BUFF)
#define bgetc(BUFF) frombuff(BUFF);
void U1putc(int chr)
{
tobuff(U1TX,chr);
enable_interrupts(INT_TBE);
}
void U2putc(int chr)
{
tobuff(U2TX,chr);
enable_interrupts(INT_TBE2);
}
//Interrupt code
#INT_RDA
void uart1rx(void)
{
char temp;
temp=fgetc(PORT1);
tobuff(U1RX, temp); //save character to circular buffer
}
#INT_RDA2
void uart2rx(void)
{
char temp;
temp=fgetc(PORT2);
tobuff(U2RX, temp);
}
#INT_TBE
void uart1tx(void)
{
char temp;
temp=bgetc(U1TX);
fputc(temp,PORT1);
if (isempty(U1TX)) disable_interrupts(INT_TBE);
//stop INT_TBE if nothing left to send
}
#INT_TBE2
void uart2tx(void)
{
char temp;
temp=bgetc(U2TX);
fputc(temp,PORT2);
if (isempty(U2TX)) disable_interrupts(INT_TBE2);
//as above for INT_TBE2
}
//Then the main
void main(void)
{
char temp;
//Again this is in fact in an include file 'init' routine
clrbuff(U1RX);
clrbuff(U2RX);
clrbuff(U1TX);
clrbuff(U2TX); //initialise the four buffers
//Now enable the RX interrupts
enable_interrupts(INT_RDA);
enable_interrupts(INT_RDA2);
enable_interrupts(GLOBAL);
//To write to UART1:
printf(U1putc,"Message to the first UART\n\r");
//To write to UART2:
printf(U2putc,"Message to second UART\n\r");
//Understand that _both_ these message will now be transmitting
//at the same time, from the buffers.
while (TRUE)
{
if (bkbhit(U1RX))
{
//Here data has been received on UART1
temp=bgetc(U1RX);
U1putc(temp); //echo it back
}
if (bkbhit(U2RX))
{
//Here there is data on UART2
temp=bgetc(U2RX);
U2putc(temp); //echo it back
}
}
}
|
This illustrates the key points. _everything_ needs to be buffered. Problem is that unless this is done, if (for instance) you go and transmit a message on UART1, then UART2 is idle while you do this transmission. If you sit waiting for data on UART1, then you will miss things on UART2 while doing this. etc. ect.. You need to be receiving, and transmitting using the interrupts and each interrupt routine must return ASAP, or another channel may miss being service.
These routines throw the oldest character, if a buffer overflows.
The comments about getting out of the interrupt quickly, also apply to any 'other' interrupts you are running. Timers etc.. You need to always make sure that interrupts are serviced faster than the time between any possible combination of sequential characters arriving. Also that things in your main code, do not result in interrupts being disabled. There was a bug in the early V5 compilers, that may have existed in the late V4's (haven't checked your version), with 'printf' resulting sometimes in GIE being disabled. Add the line 'enable_interrupts(GLOBAL);' after every call to printf if you think you might have this. |
|
|
|
|
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
|