suri_list wrote:
> We have to implement 6 serial connections to 6 modules from each
> module. we are going to use the atmega128 on each module.
>
> The atmega128 has 2 uarts so i can implement 2 simultaneous uarts.
> It is preferable not to have any external components (we have to keep
> footprint small) , so i want to do everything with the atmega128.
>
> -- But what abt the other 4. Will I have to bit bang the rest of the
> 4 using a software routine uart?
>
> -- Any other interesting solution which will allow me to use timers
> or something so that the cpu doesnt have to be busy doing the serial
> commn
What will be the serial data rate on all the 6 ports, mostly the 4 to be
done by software (bit-bang)?
Doing multi-bit-bang software routines is not that difficult, mostly to
transmit, and mostly if all use the same data rate.
Lets say that all should use 9600bps, so that is the frequency you should
use at some timer causing an interrupt.
Forget the existant UARTs in the chip for a while. Lets concentrate at the
bit-bang transmission routine.
You allocate 4 register or sram variables to hold the data to be
transmitted, lets call them TBR1 to TBR4 (Transmission Buffer Register),
another 4 bariables TR1 to TR4 (transmission register) another 4 variables
as a flag, TF1 to TF4. Another 4 variables, TRC1-4 are the counter for bits
transfered. At reset all variables at set to zero.
The TBR1-4 will hold the byte TO BE transmitted, and this is where your
application software writes such byte. It is a Transmission Buffer.
The TR1-4 are actually the place where bits are rolled out being
transmitted, so the transmission software-uart works on those.
The TRC1-4 are the transmission bit counter.
The TF1-4 are the flag bytes, they holds two kind of information. Value $01
means TBR is busy holding the next byte to be transmitted, $00 means that
byte was already copied to TR and TBR is free to receive the next byte to be
transmitted.
Lets reffer to them as TFx, TRx, TRCx TBRx
Whenever your software wants to transmit something at UARTx, it should first
check the value of the correspondent TFx (Flag), if different from zero, the
buffer is not available, it is holding the next byte to be transmitted, so
the software waits. If it is zero, it means the buffer is empty so it can
writes the transmission data byte to TBRx (Transmission Buffer - TO BE
transmitted), and set TFx to $01, meaning the buffer is holding a new byte
to be transmitted.
The 9600Hz interrupt timer routine, at every interrupt, will scan first
check the TRCx bytes, one at time. If the TRCx contains $00 it means the
last (if ever) byte in TRx was already done, nothing should be transmitted,
and in this case, it needs to se if a new byte should be transmitted,
looking at TFx, if TFx is zero, then that particular UARTx has nothing to
transmit, so it moves to the next UARTx set of registers and do it for all
of them. IF TRCx contains $00 and TFx contains $01, it means a new byte is
available to be transmitted at TRBx, so it copies TRBx contents to TRx, set
TRCx to $0A and clear TFx, freeing the buffer, and skip to the next UARTx.
During the 9600Hz interrupt timer routine, if the TRCx is different from
zero, it does this:
If it is $0A, send the START pulse (sets UARTx TX pin high), decrement TRCx
and go to next UARTx.
If TRCx is higher than 1 and lower than $0A, it shifts left TRx and moves
the Carry bit to the correspondent UARTx TX pin. Decrement TRCx and go to
next UARTx.
If TRCx is 1, it is the stop bit, so sets zero to the UARTx TX pin.
Decrement TRCx (to zero).
This does all the transmission job, for as many UARTs you need.
==========
The receiver part is a little picky, since it requires a faster sampling of
the incoming serial data.
The idea is to run another timer routine running at least 4 to 5 times
faster than the incoming speed.
So, planning to build 9600 serial ports, it will be wise to produce this
timer interrupt running at 48kHz.
It uses a similar approach for the transmitter, a receiv"ing" buffer, a 10
bits counter, a receiv"ed" buffer and a flag, for each of the UARTx.
At every 48kHz interrupt, it checks if the flag shows a byte actually under
reception, if not, it just observes the RXx pin, if it is down, nothing is
happening, if suddently it appears up, the start bit is comming, so it sets
the bits counter to 47. Why 47? Remember that this timer is running 5
times faster than the incomming bits, and that it is possible that the Start
bit arised in between the last reading and this one, so it is possible one
5x clock period was lost, no problem. Remember that to sample the incoming
data bits, it is wise to do it in middle of the actual incoming bit time, so
the 8 next bits to receive (actually data bits) times 5 is 40 interrupts,
plus the half bit, plus the whole start bit, adds 9.5 x 5 = 47.5, leaves as
47. Then, at every of this 48kHz interrupt, the sub-RX-UARTx routine checks
if each counter is lower than 41 and above 5. If it is, a byte is under
reception, so it checks if the counter is a round multiple of 5, like 5, 10,
15... up to 40. If it is, then the UARTx RX pin is SHIFTED LEFT into the
correspondent receiv"ing" register. In any case, counter above zero, it is
decremented by one. When the counter reaches a value below 5 but not zero,
the receiv"ing" register is copied to receiv"ed" register and the flag is
seto to 1, indicating a valid received byte available at receiv"ed"
register. When counter = 0, nothing is done.
It seems that reception is harder, but nothing at all.
A 48kHz interrupt timer routine can handle almost 160 instructions if clock
is 8MHz, fairly easy to deal up to 8 UARTs RX and TX.
An extra counter could decrement a counter from 5 and reset it to 5 when
zero, for each time this interrupt happens. Whenever the counter reaches
zero, it can launches the transmission routine above, so you don't need to
have two timers running. Of course, it consider 48kHz to be 5x the UARTs
speed of 9600bps, and all run at the same speed.
This routines are so nice, that I would use the required 6 UARTs by
software, leave the hardware uarts alone... :))) To increase from 4 to 6,
it is just a matter of more 16 variable bytes and extend the interrupt
routines a little.
Wagner Lipnharski - email: wagner@ustr.net
UST Research Inc. - Development Director
http://www.ustr.net - Orlando Florida 32837
Licensed Consultant Atmel AVR _/_/_/_/_/_/