View previous topic :: View next topic |
Author |
Message |
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
Fast UART transmission |
Posted: Wed Feb 17, 2016 9:14 am |
|
|
Greetings! I'm using CCS v5.024, MPLab v 8.91 and dsPIC30F5015. I want to use UART interface, but normally if I have baudrate=9600 and this code:
This command takes 1ms. Is there a way I can just put the value into the output buffer and continue with the rest of the program - without waiting transmission to complete?!
Thanks! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Feb 17, 2016 10:22 am |
|
|
Use an ISR for the transmit. Either it's in the examples or one was posted here. You just load up a buffer and when the xmit section of the UART says I'm empty, it'll grab a character from the buffer and send it.
Jay
BTW 1ms for 9600 baud is correct. |
|
|
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
|
Posted: Wed Feb 17, 2016 10:40 am |
|
|
Just a second! If I use IRS am I going to decrease the transmition time to a few cycles or I`ll have 1ms in the interrupt?!
Thanks! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Wed Feb 17, 2016 10:42 am |
|
|
As Jay says, 1mSec/byte is roughly correct.
9600bps = 0.10416mSec/bit
8bit byte, involves 1 start bit, 8 data bits, 1 stop bit.
So 10 bits/byte transmitted.
1.04mSec/byte.
ex_stisr.c shows how to use a interrupt driven serial transmit.
Or on any recent compiler, you can add a transmit ISR to the #use rs232
#use rs232(UART1, BAUD=9600, TRANSMIT_BUFFER=64, TXISR, STREAM=RS232)
Then in the 'main', just enable_interrupts(GLOBAL); and you can fputc/fprintf directly to this buffered UART. Use tx_buffer_available(RS232) to find how much space is available in the buffer.
So if you want to send twenty characters, provided tx_buffer_available is greater than 21, you can print and it will all be buffered almost immediately. |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 303
|
|
Posted: Wed Feb 17, 2016 11:17 am |
|
|
I am not sure about that particular processor, but typically putc or fputc will only wait if the buffer is full. If the buffer is not full it will place the byte into the buffer and return without waiting for the transmit to complete.
This assumes there is no flow control or enable line set up. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Wed Feb 17, 2016 3:32 pm |
|
|
Yes.
The hardware transmission buffer though is very small. On PIC18's, just two characters (one 'in transmission', and one extra). On the PIC30, just four characters.
The only reason it'd wait for a single character, is either using a software UART, or that the hardware buffer is full.
The point about using the transmit interrupt is it allows you to 'extend' the transmission buffer size. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Wed Feb 17, 2016 3:53 pm |
|
|
If you use a dsPIC that has DMA, you can then employ the DMA to automatically send your message for you, with no processor involvement required beyond the initial setup. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Thu Feb 18, 2016 1:37 am |
|
|
Not actually that easy or advantageous for simple data transmission.
It's great for 'packet based' transmission (if you have a packet of fixed size, that is transmitted), but gains you little or nothing for more basic data.
Where DMA is great, is when you can set up a linear block of data to send. Then program the UART interrupt to occur every four bytes, and the DMA interrupt to occur when you reach the end of the block. It then handles automatically re-filling the UART buffer, and sends the whole block without processor intervention. However for normal transmissions involving data of variable size, it doesn't gain you anything. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Thu Feb 18, 2016 5:04 am |
|
|
stoyanoff wrote: | Just a second! If I use IRS am I going to decrease the transmition time to a few cycles or I`ll have 1ms in the interrupt?!
Thanks! |
No, you won't have 1mSec in the interrupt, and the transmission time will remain the same.
The sequence will be:
1) Your call loads the data into the software buffer. Total time a few hundred machine cycles.
2) Interrupt occurs when the UART _can_ receive a byte. Code then transfers one byte to the UART transmit buffer, and immediately exits. Tiny delay.
3) '2' repeats until all bytes are sent. Meanwhile your code can keep running as normal, but will be slowed fractionally as each byte is transferred when the UART signals it can take another byte. A few machine cycles, every 1.04mSec.
So interrupt is being called every 1.04mSec to load the next byte from the software buffer, to the UART hardware.
The actual transmission time is fixed by the baud rate. Nothing else. However instead of having to wait for all the bytes to send, they are transferred to the software buffer (provided it has enough space), and the transmission carries on under control of the interrupt. Meanwhile your code can carry on doing other things. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Thu Feb 18, 2016 8:04 am |
|
|
Ttelmah wrote: | Not actually that easy or advantageous for simple data transmission.
It's great for 'packet based' transmission (if you have a packet of fixed size, that is transmitted), but gains you little or nothing for more basic data.
Where DMA is great, is when you can set up a linear block of data to send. Then program the UART interrupt to occur every four bytes, and the DMA interrupt to occur when you reach the end of the block. It then handles automatically re-filling the UART buffer, and sends the whole block without processor intervention. However for normal transmissions involving data of variable size, it doesn't gain you anything. |
I agree that it's not easy to set up, but I respectfully must disagree regarding variable sized data. You just fill your "outbound" buffer (not the UART's buffer) and set the DMA count to however many bytes are in your buffer. Finally, trigger the DMA and let it do its' thing. The DMA interrupt fires when it's done. At that point, repeat if necessary and do nothing if not. I have two different products in the field that use this idea, and they're rock solid.
Where DMA and UARTs doesn't make sense is in data reception with variable sized packets. In that situation, DMA actually makes your job harder to do. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Thu Feb 18, 2016 3:22 pm |
|
|
It still requires the buffer to be linear, and with known blocks to transmit.
I've used it on known 'pre-prepared' packets, and it is great for this, but for normal UART I/O, using single byte, or normal printf I/O, it is very hard indeed to handle adding characters dynamically.
It's the difference between things that are suited to a linear buffer, and a circular buffer. 90% of standard UART comms is better suited to the latter.... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Sat Feb 20, 2016 6:36 am |
|
|
Have to ask an obvious question..
Can you increase the baudrate or is it fixed on the other device at 9600?
I know 9600 seems to a defacto standard these days, but modern chips can easily push 38400, even 115K200 without errors.
Maybe an option ?
Jay |
|
|
avatarengineer
Joined: 13 May 2013 Posts: 51 Location: Arizona
|
Baudrate |
Posted: Mon Feb 29, 2016 10:00 am |
|
|
@temtronic
You can any baud rate you wish (within reason);
i.e. a software UART version or hardware version can be described
#DEFINE SWUART FORCE_SW,xmit=Tx2,rcv=Rx2,BRGH1OK,bits=8,parity=n,Stop=1
#USE rs232(SWUART,baud=200000,DISABLE_INTS,stream=COMport)
Looking at the PIC in mind, the UART clock divider, per spec, has pre & post scalers that if you create a spreadsheet, like I do,
will calculate actual versus programmed baud with an error rate based on packet size.
Helps to know drift and offset of Fosc, too.
The old increments of Baud such as 9600 or 115.2K aren't the only choices.
You can use 400Kbaud (it divides evenly from an 8 or 16MHz clock) as long as your receiver is the same or using AutoBaud. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Mon Feb 29, 2016 10:04 am |
|
|
Temtronic knows full well what baud rates can be done. He was asking the _thread poster_ whether he could use a higher baud rate, if he was worried by how long a byte takes to send at 9600bps. |
|
|
|