HW SW UART
Hardware based UARTS (universal asynchronous receiver transmitter) is really preferred.
You just write a byte to a TX register and the UART then take care of the transmission, bit after bit.
TX seance simplified
An example: the uart is configure to 1200 baud. At byte capicity TX time of a byte is 10 milli seconds.
Writing the byte to (an empty) TX register takes next to noting.
sender call write function in driver
if UART TX register is empty sender write TX byte to TX register in UART
otherwise sender write the TX byte to the TX-buffer
UART issue an interrupt when the byte is transmitted
if there is bytes in the TX-buffer the interrupt routine write this to UART TX register
The same goes for receiving. It normally goes like:
RX seance simplified
UART do an interrupt to signal a byte arrived
ISR routing read byte from RX register and store it in a buffer or message queue
Reader calls read function which either read e byte from the buffer
or …
wait until a byte has arrived or timeout limit in read call has been reached
Software based UART - aka bit banging
Is no HW uart is present in system or an additional UART is needed sometimes a software based UART is used.
FOr Arduino see her SoftwareSerial.h and SoftwareSerial.cpp.
SW UARTS may have bad impact on your timing
Two examples for TX and RX 1 byte at 4800 baud
SW UART TX of 1 byte @4800 baud
TX 1 byte @ 4800 baud takes 2.5 msec.
A std digital out goin pin is used.
It is all done by bit banging
Interrupt is disabled
startbit edge to low
busy waiting 1 bit time -0.21 milli second
bit 0 starting edge high or low
busy waiting 1 bit time -0.21 milli second
bit 1 starting edge high or low
busy waiting 1 bit time -0.21 milli second
bit 2 starting edge high or low
busy waiting 1 bit time -0.21 milli second
bit 3 starting edge high or low
busy waiting 1 bit time -0.21 milli second
bit 4 starting edge high or low
busy waiting 1 bit time -0.21 milli second
bit 5 starting edge high or low
busy waiting 1 bit time -0.21 milli second
bit 6 starting edge high or low
busy waiting 1 bit time -0.21 milli second
bit 7 starting edge high or low
busy waiting 1 bit time -0.21 milli second
stopbit starting edge high
busy waiting 1 bit time -0.21 milli second
Interrupt is now re-enabled
So the machine is running with interrupt disabled for 2.1 milli second.
SW UART RX of 1 byte @4800 baud
RX 1 byte @ 4800 baud takes 2.5 msec.
A std digital out goin pin is used.
It is all done by bit banging
Interrupt register falling edge == startbit
busy waiting 0.5 bit time -0.10 milli second
read startbit - in middle of bit (bq of the 0.5 bittime delay above)
busy waiting 1 bit time -0.21 milli second
read bit 0 starting edge high or low
busy waiting 1 bit time -0.21 milli second
read bit 1 starting edge high or low
busy waiting 1 bit time -0.21 milli second
read bit 2 starting edge high or low
busy waiting 1 bit time -0.21 milli second
read read bit 3 starting edge high or low
busy waiting 1 bit time -0.21 milli second
read bit 4 starting edge high or low
busy waiting 1 bit time -0.21 milli second
read bit 5 starting edge high or low
busy waiting 1 bit time -0.21 milli second
read bit 6 starting edge high or low
busy waiting 1 bit time -0.21 milli second
read bit 7 starting edge high or low
busy waiting 1 bit time -0.21 milli second
read stopbit starting edge high
busy waiting 1 bit time -0.21 milli second
Interrupt is now re-enabled
So the machine is running with interrupt disabled for 2.1 milli second.
SW based TX or RX - you decide
Some thoughts.
Above we see that bit banging with interrupt is disabled is user for TX and RX.
So at a given time only RX or TX can take place.
Furthermore interrupt disabled for such long time may have negative impact on HW (and of course SW as well) devices.
An exanple.
On HW UART a GPS running 9600 baud is running
On a SoftwareSerial port running 1200 baud we have a comm link to another machine
Receiving 1 byte @ 1200 baud at th SW UARTS disables interupt for 10 milliseconds
The HW UART for the GPS takes 1.25 millisecond for each byte
10/1.25 = 8 has the potential that we loose 8 bytes in a row from the GPS.
hmmm
SW TX has normally no outgoing buffer because it is bitbang driven TX carried out by the caller of the write command.
Final thoughts
IF your are strictly servicing one SW and HW based system at a time it might work.
For data and CPU time budget you have - of course - to take bit banging/pulling time into your budget.
Doing bitbanging in a kernel based system is not recommended.
At 1200 baud interrupt will be disabled 10 milliseconds which is 10 kernel tick.
BTW your millis counter or similar will also loose time.
In a multicore system you might locate bit banging on one core and essential realtime task on other(s)) core. This might add RT quality to your solution.
|