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 _/_/_/_/_/_/
Message
Re: [AVR-Chat] How to implement 6 UART Serial Connections using Atmega128
2004-02-04 by Wagner Lipnharski
Attachments
- No local attachments were found for this message.