; ;**************************************************************************** ; ; Purpose: ; Automatically Detect The Baud Rate On The Serial Port ; ; Date: ; 02/03/95 ; ; Author: ; John C. Wren ; ; Modications: ; 02/04/97 - Added Description Fields For Archive ; ; Processor: ; Generic 8031, Running At 11.0592MHz ; ; Assembler: ; Avocet AVA51 ; ; Dependencies: ; None ; ; Files: ; None ; ; Philosophic: ; These Routines Make The Assumption That The Entire CPU Can Be ; Dedicated To Determing The Baud Rate Of The Serial Port. This ; Could Be Better Implemented By Tying The Serial Port RX Pin To ; -INT0 Or -INT1. This Would Allow An Interrupt To Be Generated ; On The Edge Of The Start Bit, Rather Than The Autobauder Camping ; Out On The Port Pin, Waiting For The Change. ; ; This Routine Came From A FORTH Interpeter I Wrote. Since The System ; Didn't Have To Do Anything While Waiting For The Serial Port To ; Autobaud, It Was OK To Camp Out On The Serial Port Pin. This Is ; Not Very Elegant. ; ;**************************************************************************** ; ; Includes ; seg code ; ;**************************************************************************** ; ; Publics ; public AUTOBAUD ; ;****************************************************************************** ; ; Description: ; Determine Baud Rate Of Serial Port By Timing Start Bit. ; ; Entry Requirements: ; None ; ; On Exit: ; B/A Has Current Baud Rate (As 9600, 1900, etc For Displaying) ; R0 Has Value For SMOD Bit Used ; R1 Has Divisor Rate Used ; ; Affected: ; SCON, SBUF, TMOD, TH0, TL0, R0, R1, B, A, DPTR, PSW ; ; Stack: ; 0 Bytes, Not Including Space Used By Called Routines ; ; Comments: ; The Tables Are Setup To Allow +-3% Variation In Timing. If Can't ; Get A Good Baud Rate, Just Keep Trying. The Routine Can And Will ; Be Tricked If Not Running At 8/N/1. ; AUTOBAUD proc clr es ; No Serial Interrupts clr et0 ; No Timer 0 Interrupt mov scon,#052h ; Mode 3 Serial Port mov tmod,#021h ; Timer 1 Mode 2, Timer 0 Mode 1 mov sbuf,#000h ; Send A Null For First Character setb tr1 ; Start Timer 1 Up ; ; Wait For Start Bit, Run Timer While Start Bit High ; l?p0: clr ri ; Ignore Any Character In SBUF clr tr0 ; Cancel Timer 0 mov th0,#000h ; Clear Timer 0 High mov tl0,#000h ; Clear Timer 0 Low jb p3.0,$ ; Wait For Start Bit High setb tr0 ; Start Timer 0 Running jnb p3.0,$ ; Wait For Start Bit To Go Low clr tr0 ; Cancel Timer 0 ; ; Timer 0 Has Start Bit Period. Test Against Table. ; mov dptr,#Table ; Point To Table l?p1: mov a,#0 ; Set For MOVC movc a,@a+dptr ; Get High Byte From Table cjne a,th0,l?p2 ; Compare mov a,#1 ; Set For MOVC movc a,@a+dptr ; Get Low Byte From Table cjne a,tl0,l?p2 ; Compare l?p2: jc l?p4 ; If Greater, Try Next Entry mov a,#2 ; Set For MOVC movc a,@a+dptr ; Get High Byte From Table cjne a,th0,l?p3 ; Compare mov a,#3 ; Set For MOVC movc a,@a+dptr ; Get Low Byte From Table cjne a,tl0,l?p3 ; Compare setb c ; Flip Status l?p3: jnc l?p4 ; If Less, Try Next Entry ; mov a,#4 ; Point To SMOD Status Byte movc a,@a+dptr ; Get SMOD Byte mov r0,a ; Move To R0 For Return mov pcon,a ; Store It Back mov a,#5 ; Point To Speed Byte movc a,@a+dptr ; Get Speed Byte mov r1,a ; Move To R1 For Return mov th1,a ; Setup Baud Rate Timer mov tl1,a ; Setup Baud Rate Timer jnb ri,$ ; Wait For Character clr ri ; Say Character Received Isn't There mov a,#6 ; Offset To Baud Rate High movc a,@a+dptr ; Get High Of Baud Rate In Binary mov b,a ; Store In B mov a,#7 ; Offset To Baud Rate Low movc a,@a+dptr ; Get Low Of Baud Rate In Binary setb es ; Allow Serial Interrupts ret ; Return To Caller ; l?p4: mov a,#8 ; Number Bytes In Record add a,dpl ; Add In DPL mov dpl,a ; Back To DPL jnc l?p5 ; If No Carry, Skip inc dph ; Increment High Of DPTR l?p5: clr a ; Clear For MOVC movc a,@a+dptr ; Get Byte cjne a,#-1,l?p1 ; While Not -1, Loop sjmp l?p0 ; Try Again ; ; All Values Calculated For 11.059200Mhz ; Table: dw 6328, 5960, 00040h, 00150; 150 dw 3164, 2980, 000a0h, 00300; 300 dw 2109, 1987, 000c0h, 00450; 450 dw 1582, 1490, 000d0h, 00600; 600 dw 0791, 0745, 000e8h, 01200; 1200 dw 0527, 0497, 000f0h, 01800; 1800 dw 0396, 0372, 000f4h, 02400; 2400 dw 0264, 0248, 000f8h, 03600; 3600 dw 0198, 0186, 000fah, 04800; 4800 dw 0132, 0124, 000fch, 07200; 7200 dw 0099, 0093, 000fdh, 09600; 9600 dw 0066, 0062, 000feh, 14400; 14400 dw 0049, 0047, 080fdh, 19200; 19200 dw -1 endproc ; ;**************************************************************************** ; end