View previous topic :: View next topic |
Author |
Message |
id31
Joined: 19 Dec 2014 Posts: 16
|
different UART by function's argument |
Posted: Mon Jan 23, 2017 3:00 am |
|
|
Hi,
Question please:
I have 2 UART channel at pic18.
I declared 2 differnt RS232:
Code: |
#use rs232(baud=9600, BITS=8, XMIT=PIN1, RCV=PIN2, STREAM=CH1)
#use rs232(baud=9600, BITS=8, XMIT=PIN13, RCV=PIN4, STREAM=CH2) |
Everything works well!
I have 2 functions that get in the data:
Code: |
int rcv_ch1()
{
return (getc(CH1));
}
int rcv_ch2()
{
return (getc(CH2));
} |
could I merge it to 1 function like that ?:
Code: | int rcv_ch(int(?) ch)
{
return(getc(ch));
}
|
Thank you ! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Mon Jan 23, 2017 3:17 am |
|
|
No.
Problem is that the 'getc' (or putc), is actually replaced with the code to talk to the selected UART. Writing the getc (or putc), so it accepted a variable as a stream name, would require exactly the same switching you are having to do, but would need it for every stream operation, result much bulkier code....
What you can do is combine them with your own selection. So:
Code: |
int rcv_ch(int1 ch)
{
if (ch)
return(fgetc(CH2));
return(fgetc(CH1);
}
|
ch can then be '0' for the first channel, and '1' for the second.
The two receive routines are both included in the 'rcv_ch' function, and if ch is '1', fgetc(CH2) is executed, while if it is '0', fgetc(CH1) is called.
I've switched it to using fgetc. I know in CCS, fgetc is 'overloaded' onto getc, so if you call getc, with a variable, it switches to actually using fgetc, but I think it is clearer to stick with the original use of 'getc' so it returns a character from the primary port, while 'fgetc' accesses named streams. |
|
|
id31
Joined: 19 Dec 2014 Posts: 16
|
|
Posted: Mon Jan 23, 2017 3:42 am |
|
|
OK
thank you! very helpful! |
|
|
MikeW
Joined: 15 Sep 2003 Posts: 184 Location: Warrington UK
|
|
Posted: Mon Jan 23, 2017 9:03 am |
|
|
@Ttelmah
dont think thats quite right.
surely if ch is a 1, then it calls ch2, then call ch1
try
Code: |
int rcv_ch(int1 ch)
{
if (ch)
{
return(fgetc(CH2));
}
else
{
return(fgetc(CH1);
}
} |
|
|
|
newguy
Joined: 24 Jun 2004 Posts: 1908
|
|
Posted: Mon Jan 23, 2017 9:07 am |
|
|
No, what he wrote will function as specified. Remember a return statement effectively "pulls the rip cord" and gets out of the function. Therefore if ch is a 1, the function gets the character waiting in UART2's buffer and returns it. Execution never gets to the second return statement. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Mon Jan 23, 2017 9:39 am |
|
|
It's an important understanding of 'program flow'.
If I wrote:
Code: |
int rcv_ch(int1 ch)
{
int temp;
if (ch)
temp=fgetc(CH2);
temp=fgetc(CH1);
return temp;
}
|
Then it'd be wrong. All program paths would lead to the second return, and the value from the first path would be lost.
This would have to be fixed by using the 'else'.
However as shown it'll work (except I left the closing bracket off the second return....). As newguy says the first path gets the value from CH2, and immediately exits with this. Every other route gets the value from CH1, and returns. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1908
|
|
Posted: Mon Jan 23, 2017 10:29 am |
|
|
At my old position we had an on-again, off-again software engineer at times. After the last time he quit, troubleshooting some of his code fell to me. He had taken code that had an if { } else { } structure and changed it to a if { .... } continue { other stuff } structure. For what reason I have no idea, other than he never seemed happy unless he was rewriting working code. I found that the gnu compiler wasn't properly exiting the inner loop/brace once it hit the continue so I changed it back to the original structure. It worked again after that.
I tend to come from the "explicit" category of programming so I like code that may be longer but its flow is never in question. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Mon Jan 23, 2017 11:26 am |
|
|
Whatever method is used, it needs some form of 'error checking' concerning the actual 'channel' or UART number. Silly things like -1 or +3 'could' be passed.... Invalid UART 'channels' should return some 'error' message.
Jay |
|
|
MikeW
Joined: 15 Sep 2003 Posts: 184 Location: Warrington UK
|
|
Posted: Mon Jan 23, 2017 12:16 pm |
|
|
I accept as a hardware guy, the C code is ok.
I would hate to try to debug it though.
C is a minefield for the inexperienced
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Mon Jan 23, 2017 1:01 pm |
|
|
temtronic wrote: | Whatever method is used, it needs some form of 'error checking' concerning the actual 'channel' or UART number. Silly things like -1 or +3 'could' be passed.... Invalid UART 'channels' should return some 'error' message.
Jay |
except (of course) that as written it only accepts an int1, so just two choices. |
|
|
|