Call me crazy if you like but I decided to make myself a dual serial port system for the 8051 (AT89S52) via hardware multiplexing (4052 IC) in which the uart selection is controlled by a GPIO pin. The crystal attached is 22.1184Mhz. I did it because I have a radio module (model: HM-TRP) that has a uart and I'm also connecting it to the PC as well. Ideally, I want to use the 8051 to allow the PC through a friendly terminal interface to program the radio module.
The issue I'm having which isn't really documented is the timing of serial operations. I'm looking at a speed of 56Kbps. I set PCON.7 to 1 and I followed the baud rate chart and set my timer 1 reload value to FEh. This works nice for the only one hardware uart on the 8051.
My idea to streamline both serial ports is to enable one for a fixed window of time, then switch to the other one for a fixed window of time. The problem is I don't know how to calculate such window efficiently. If I make the time incorrect, then some bits will be cut-off (thereby producing a framing error).
Because I'm using the 8N1 format and 56k speed for serial data on all devices, I believe that the 8051 makes a scan after 10 incoming bits to see if the data is present or not. For this reason, I also included a decade counter on board (CD4017) that can go to 10 (or 9) and then trigger an interrupt to offload work from the processor. then I'm thinking implementing a serial function like this (assume a jump was executed from the vector address before the instructions below start):
serial_1_timer_interrupt: cpl TIMER ;set clock line on the 4017 in opposite state reti INT1_interrupt: ;triggered when Q5 on the 4017 goes low jbc SERIAL_RECEIVED,notbad cpl UARTLINE ;select uart line: clear=1st uart, set=2nd uart notbad: reti serial_interrupt: jnb RI,notreceived setb SERIAL_RECEIVED ;set software flag if data received before time runs out mov @R0,SBUF inc R0 clr TIMER ;set last so nothing bad happens if interrupt is triggered notreceived: clr RI clr TI reti
But then again, I might have to step speed down to about 38.4K to prevent stalls in the timer interrupt.
I know i may need to put a bit more thought into the code, but is this the most practical way to do this? I mean I want to make things as multitasking as possible (example: send data from PC to micro while reading a byte from radio module)
Now you really are talking crazy!
I just did a search at RS:
The cheapest AT89S52 is £1.46
uk.rs-online.com/.../
A search of all microcontrollers with 2 or more UARTS has four pages of chips costing less than that!