| View previous topic :: View next topic | 
	
	
		| Author | Message | 
	
		| kgng97ccs 
 
 
 Joined: 02 Apr 2022
 Posts: 103
 
 
 
			    
 
 | 
			
				| Setting up a software UART |  
				|  Posted: Mon Nov 21, 2022 11:00 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Nov 21, 2022 11:49 pm |   |  
				| 
 |  
				| 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Nov 22, 2022 1:56 am |   |  
				| 
 |  
				| 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: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Nov 22, 2022 6:22 am |   |  
				| 
 |  
				| 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: 103
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Dec 27, 2022 9:27 am |   |  
				| 
 |  
				| 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: 350
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Dec 27, 2022 11:10 am |   |  
				| 
 |  
				| Not discontinued, just sometimes unavailable due to supply shortages. |  | 
	
		|  | 
	
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Dec 27, 2022 11:54 am |   |  
				| 
 |  
				| 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: 103
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Dec 30, 2022 3:39 am |   |  
				| 
 |  
				| 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Dec 30, 2022 10:20 am |   |  
				| 
 |  
				| Dropping TX, is explicitly sending a 'start', so not surprisng you were seing spurious characters!.
 Glad you have it working now.
 
   
 Happy New Year everybody.
 |  | 
	
		|  | 
	
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Dec 31, 2022 7:20 am |   |  
				| 
 |  
				| 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Dec 31, 2022 8:06 am |   |  
				| 
 |  
				| 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: 103
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Jan 15, 2023 2:17 am |   |  
				| 
 |  
				| Thank you, Ttelmah and Temtronic, for your advice. 
 
 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: |  	  | If you're concerned about saving power, you may be able to reduce the delay_ms(20). 
 | 
 
 
 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). 	  | 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. 
 | 
 
 Thank you for your help.
 |  | 
	
		|  | 
	
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Jan 15, 2023 6:58 am |   |  
				| 
 |  
				| Great news.  |  | 
	
		|  | 
	
		|  |