View previous topic :: View next topic |
Author |
Message |
colin382
Joined: 03 Jun 2020 Posts: 37 Location: UK
|
Multiple UARTs |
Posted: Sat Feb 18, 2023 7:36 am |
|
|
I have a need for six UARTs on a single PIC16LF15325. Only the transmit lines are needed and I have written a simple function to take a byte and send it from a pin specified within the code.
Rather than write six such functions each the same except for its name and the txd pin, is it possible to use one function and pass the pin ID (SoftTx below) as an argument? E.g SoftUART(pin, byte)
I have discovered the hard way that re-defining a pin name to a different chip pin doesnt work- the compiler warns and ignores the re-definition.
Using CCS Workshop compiler v5.105c
Code: |
#define SoftTx PIN_C4 // pin 6, radio data
void SoftUART(unsigned int8 data){
// a software UART (TX only) running here at 2400 bps
unsigned int8 i;
unsigned int1 txd;
output_bit(SoftTx,0); // start bit
delay_us(353); // extend to full bit period
for(i=0;i<8;i++){ // output each bit, lsb first
txd = data & 1; // get bottom bit
output_bit(SoftTx,txd); // send it
delay_us(353); // extend to full bit period
data = data>>1; // shift to next bit
}
output_bit(SoftTx,1); // stop bit
delay_us(706); // extend to two bit periods
}
PS if there is a better way to write a UART transmit function, let me know!
|
|
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Sat Feb 18, 2023 7:49 am |
|
|
Just cut the 6 functions....
While it may take up more code space, it works.
It might even use LESS space,depending on how 'pin selection' is coded.
I did that for a project that needed 4 'one wire DS temp sensors'. It was actually better to have one sensor per pin than the normal 'all on one' approach.
If you have a table of baud rate vs delays, you can easily change baudrates. Handy when that 7th channel added... |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Sat Feb 18, 2023 12:54 pm |
|
|
Or just use a wrapper.
Key to understand is that the stream name has to generate different
code for each UART, hence the reason it cannot be passed to a function.
However you can perfectly well have the six sets of code generated
and route as required. So:
Code: |
int uart_to_use 0;
void routed_putc(char val)
{
switch (uart_to_use) {
case 0:
putc(val, STREAM1);
break;
case 1:
putc(val, STREAM2);
break;
case 2:
putc(val, STREAM3);
break;
case 3:
putc(val, STREAM4);
break;
case 4:
putc(val, STREAM5);
break;
case 5:
putc(val, STREAM6);
break;
]
]
|
//then just set 'uart_to_use, and printf to routed_putc |
|
![](templates/subSilver/images/spacer.gif) |
colin382
Joined: 03 Jun 2020 Posts: 37 Location: UK
|
|
Posted: Sat Feb 18, 2023 2:54 pm |
|
|
Thanks both, I'll just write separate functions for each. |
|
![](templates/subSilver/images/spacer.gif) |
alan
Joined: 12 Nov 2012 Posts: 357 Location: South Africa
|
|
Posted: Sun Feb 19, 2023 8:31 am |
|
|
I like to use #define for this type of function.
Only one to maintain instead of 6. You just can't use local variables.
Code: | #define SoftTx PIN_C4 // pin 6, radio data
unsigned int8 i;
unsigned int1 txd;
#define SoftUART(pin, data) {\
/* a software UART (TX only) running here at 2400 bps*/\
output_bit(pin,0); /* start bit*/\
delay_us(353); /* extend to full bit period*/\
for(i=0;i<8;i++){ /* output each bit, lsb first*/\
txd = data & 1; /* get bottom bit*/\
output_bit(pin,txd); /*send it*/\
delay_us(353); /* extend to full bit period*/\
data = data>>1; /*shift to next bit*/\
}\
output_bit(pin,1); /* stop bit*/\
delay_us(706); /* extend to two bit periods*/\
}
SoftUART(SoftTx,TxData);
SoftUART(SoftTx1,TxData);
|
|
|
![](templates/subSilver/images/spacer.gif) |
colin382
Joined: 03 Jun 2020 Posts: 37 Location: UK
|
|
Posted: Tue Feb 21, 2023 8:41 am |
|
|
Thanks Alan, your code looks like what I am trying to achieve, but I could not get it to work. I also studied the CCS ex_macro.c, but that didnt work either. So I guess I am going to have to set up six similar functions. Fortunately there is plenty of code and RAM space. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Tue Feb 21, 2023 9:05 am |
|
|
Having individual functions for each serial port can be a good idea,especially when 'someone' decides that Comport #3 HAS to be 9600 while the rest are 2400.
6 comports isn't too bad though 32 was a wee bit of a challenge. DOCUMENT/comment your code now.....if you don't ,a month from now you'll wonder WHAT was this for ????? ![Sad](images/smiles/icon_sad.gif) |
|
![](templates/subSilver/images/spacer.gif) |
colin382
Joined: 03 Jun 2020 Posts: 37 Location: UK
|
|
Posted: Tue Feb 21, 2023 10:45 am |
|
|
Good advice, as always. |
|
![](templates/subSilver/images/spacer.gif) |
|