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 CCS Technical Support

Setting up a software UART

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



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

Setting up a software UART
PostPosted: Mon Nov 21, 2022 11:00 pm     Reply with quote

I am using the PIC18LF46K22 MCU, CCS C compiler v5.113, and MPLAB IDE v8.92.

I tested the following program for a software UART, to check whether I was able to receive the transmitted data. The RCV pin is the INT0 interrupt pin. The compiled program was loaded onto the MCU and I used the Terminal.exe interface to send and receive data.
Code:
#include "18LF46K22.h"
#fuses INTRC_IO
#use delay(clock=16000000)
#use rs232(baud=9600, xmit=pin_A6, rcv=pin_B0, disable_ints, sample_early, errors, stream=UART_db)

#int_ext
void f_int_ext_isr()
{
   /* Echo back received byte */
   fputc(fgetc(UART_db), UART_db);
}

void main()
{
   ext_int_edge(0, H_to_L);
   clear_interrupt(int_ext);
   enable_interrupts(int_ext);
   enable_interrupts(global);
   
   while (true);
}

Results:
1. When I sent “$CA$06$01$00$C1$34$01$39”, the program only echoed back “CA 01 C1 01” (only bytes 1, 3, 5, 7).
2. When I sent “$CA$0E$01$00$C1$34$56$78$90$AA$BB$CC$DD$EE$01$61”, the program only echoed back “CA 01 C1 56 90 BB DD 01” (only bytes 1, 3, 5, 7, 9, 11, 13, 15).
3. The program always skips the even byte.

Question:
What should I do to get the program to work properly?
I will appreciate any ideas or advice. Thank you.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 21, 2022 11:49 pm     Reply with quote

A soft uart can only do one thing at a time. If it's doing fputc() in the isr
then it can't exit to main() and get the next INT0 interrupt for the next
incoming byte. You're transmitting a byte when the next one comes in
so you miss it.

Save the whole message in a large buffer. Then when it's done, send the
whole message back. Put a marker byte in the message sent to the PIC
to show the end of the message.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Tue Nov 22, 2022 1:56 am     Reply with quote

If you really 'must' use a software serial, and need to have other things
happening while you are receiving, there is another approach to doing such
serial.
I posted in the code forum a while ago, a software serial done by using
a timer:
[url]
http://www.ccsinfo.com/forum/viewtopic.php?t=51403&highlight=timer+serial
[/url]

This generates a buffered serial receive done by sampling the pin at
intervals 4* the baud rate.
This can also be adapted to provide transmit as well.

Keeping it to one job at a time by only sending when receive is not
happening, is much simpler, but solutions can be written if this can't be
avoided.
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Nov 22, 2022 6:22 am     Reply with quote

hmm, I was curious to see if the 46k22 was available ( next year..) but their recommended alternate the PIC18F46Q10 is !!
It not only has FIVE UARTs, it's 1/2 the price !!

but, I'd have to upgrade my compiler.

Just wanted to point out another way to get a 3rd UART.

Jay
kgng97ccs



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

PostPosted: Tue Dec 27, 2022 9:27 am     Reply with quote

Sorry for this late acknowledgement.

Thank you all very much for your input.

It was good that Temtronic brought up the possibility of the PIC18LF46K22 being discontinued. We will be keeping a close watch on this MCU as we are using it in a number of our products.

Yes, we have used up the two hardware UARTs available on the PIC18LF46K22, and that is why we have to use a software UART.

I have managed to get the software UART working quite reliably now, except that sometimes the Terminal program shows garbage for a short while, and then reverts to showing the characters correctly.

Also, I have a program (hex file) that prints some text before the master while (true) loop through the software UART to the Terminal screen every time it runs. However, every time the program runs, the same garbage always appears in the same print location, but the corresponding fprintf statement where the garbage occurs is just like the other fprintf statements that print correctly.

Is there any way to minimize the occurrence of such garbage?

I will appreciate any ideas. Thank you.
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Tue Dec 27, 2022 11:10 am     Reply with quote

Not discontinued, just sometimes unavailable due to supply shortages.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Tue Dec 27, 2022 11:54 am     Reply with quote

It is not clear how the hardware is actually done?.
If it is using a MAX232 type chip, the charge pumps in these do take a
little time to generate the full output voltage. Hence code generally needs
to start by explicitly setting the TX bit high, and then waiting for a few
mSec before starting a transmission. Generally something like 15mSec is
needed before the level can be guaranteed. A chip that starts and
immediately sends will commonly find the first few characters are corrupted.
kgng97ccs



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

PostPosted: Fri Dec 30, 2022 3:39 am     Reply with quote

Thank you, gaugeguy, for pointing out my misunderstanding.

Thank you, Ttelmah, for the tip.

I tried this tip on the software UART by setting the TX bit to high before the fprintf statement where the character corruption occurs, and it works!

My fprintf problem occurred in a function, and I realized that at the beginning of the function, I had set the TX bit of the software UART to low, to minimize current consumption.
Code:
output_low(debug_tx_pin);


output_high(debug_tx_pin);
delay_ms(20);

fprintf(UART_db, "Master oscillator settings:\n");
fprintf ...;
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Fri Dec 30, 2022 10:20 am     Reply with quote

Dropping TX, is explicitly sending a 'start', so not surprisng you were
seing spurious characters!.
Glad you have it working now.
Very Happy

Happy New Year everybody.
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Dec 31, 2022 7:20 am     Reply with quote

Nice it's 'up and running' !
If you're concerned about saving power, you may be able to reduce the delay_ms(20).
try 15 and see if it's 100% working. if not, try 17, try again.

Even if you have to use delay_ms(19), you've saved '1ms of power'. Not much but saving a few electrons and some there, does add up !
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Sat Dec 31, 2022 8:06 am     Reply with quote

Also, if the signal being high draws more power, then you need to ask 'why'.
Generally on the outputs themselves it is changing the level that draws
power. Being stable high or low should not make any difference, unless
there is some pull-up/pull-down involved in what is being driven.
kgng97ccs



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

PostPosted: Sun Jan 15, 2023 2:17 am     Reply with quote

Thank you, Ttelmah and Temtronic, for your advice.

Quote:
If you're concerned about saving power, you may be able to reduce the delay_ms(20).
Temtronic: I tested the delay time all the way down to zero (no delay), and it still works -- repeatedly without corrupted characters! I now do not use any delay after the "output_high(debug_tx_pin)" statement.

Quote:
Generally on the outputs themselves it is changing the level that draws power. Being stable high or low should not make any difference, unless there is some pull-up/pull-down involved in what is being driven.
Ttelmah, your comment prompted me to test how the state of the TX pin affects the current consumption. It turned out that setting it to high or low makes no difference to the current consumption! So now, I just set it to high and leave it that way (without resetting it to low later).

Thank you for your help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Sun Jan 15, 2023 6:58 am     Reply with quote

Great news. Smile
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