OK, no one wants to help, so I must help myself.
I wrote simple (working) example how to use HARDWARE BASED SERIAL PORT, mode 1 (8 bit async, 1 stop bit, timed by timer 1, TxD/P3.1, RxD/P3.0) on AT89C2051 or AT98C4051, maybe others with some tweaks, use it for your projects if you want and feel free to ask, if something isn't clear.
Note that SerialISR() procedure serves serial port and other code works independently on it, but is interrupted when event on serial port occur so be aware of using time critical applications, especially if you are receiving or sending byte after byte without pause (SerialISR() must fit into two events). And Timer 1 is occupied by serial port so you can't use it.
Baudrate can be calculated using this:
Baudrate = ((2^SMOD)/32)*(Xtal frequency/(12*(256-TH1)))
+-5% tolerance is allowed
Code: Select all
program na_forum
' Declarations section
dim temp as byte
'-------------------------------------------------------
sub procedure SerialISR() org 0x0023
'if data was received or send, this procedure start
'if RI_bit = 1, data received:
if RI_bit = 1 then
RI_bit = 0 'we must clear received data indicator
temp = SBUF 'now we can work with data here or outside of procedure
P1 = temp 'for example
SBUF = temp 'or we can send the data back for echo
end if
'if TI_bit = 1 data was successfully send
if TI_bit = 1 then
TI_bit = 0 'we must clear send data indicator
end if
end sub
main:
' Main program
'Serial port initialization
TH1 = 243 'Timer 1 value, sets baudrate, 9600 here
TMOD = %00100000 'sets the timer mode
SCON = %01010000 'sets serial chanel: 8bit async timed by timer 1
EA_bit = 1 'enable interrupt
ES_bit = 1 'interrupt from serial chanel
TR1_bit = 1 'start timer 1
PCON = %10000000 'set SMOD bit to 1 - baudrate setting
'end of serial port initialization
'other code here:
do_nothing: 'wait to eternity or death :-)
Delay_ms(1000)
goto do_nothing
end.