; RS485 Repeater Transmit Time Control ; Copyright 2007, Paul Stoffregen .equ locat, 0x0000 ;Location for this program ;.equ locat, 0x8000 ;Location for this program .org locat ljmp start .org locat+0x100 .db 0xA5,0xE5,0xE0,0xA5 ;signiture bytes ;.db 254,'P',0,0 ;id (35=prog) .db 249,255,0,0 ;id (249=init, before baud rate) .db 0,0,0,0 ;prompt code vector .db 0,0,0,0 ;reserved .db 0,0,0,0 ;reserved .db 0,0,0,0 ;reserved .db 0,0,0,0 ;user defined .db 255,255,255,255 ;length and checksum (255=unused) .db "Repeater",0 ;max 31 characters, plus the zero .org locat+0x100+64 ;executable code begins here .equ xmit_rate, 72 ;a byte is transmitted at (3600/xmit_rate) Hz start: mov ie, #0 orl PCON,#10000000b ; set double baud rate mov tmod, #0x2B ;timer0: two 8 bit timers, timer1: baud rate MOV SCON,#01010000b ; Set Serial for mode 1 ORL TCON,#01010010b ; Start timer 1 both timer mov th1, #255 ;max baud rate (57600 @ 11.0592 MHz) mov tl1, #255 mov th0, #0 mov tl0, #0 setb ti ;ti is normally set in this program clr ri ;ri is normally cleared setb tr0 ;tl0 always inc when INT0 is high setb tr1 ;th0 always inc mov r0, #xmit_rate mov r1, #0 clr p3.4 ;use aux port ;normally we're in 485->232 mode (INT0 low) by default main_loop: setb p1.6 ;allow flip-flop contol by incoming 232 data mov tl0, #48 ;timer0 will inc only when INT0 is high (232->485) clr tf0 ;so set it up ahead of time ;we will enter 232->485 automatically when a start bit from ;the 232 side sets the flip-flop. INT0 goes high and allows ;tl0 to count, and eventually tf0 will set set when it's time ;for the flip-flop to be cleared and end the 232->485 transmission. ;It's safe to start looking even before 232->485 mode begins, since ;the tl0 can't inc while INT0 is low and we obviously won't be ;receiving any bytes from the 232 side. wait_data_end: jbc ri, char_received jbc tf1, xmit_timing_byte jnb tf0, wait_data_end ;if the timer overflowed, end of data reached data_end: clr p1.6 ;reset flip-flop, puts us into 485->232 mode sjmp main_loop ;if the uart received a character, allow more time for 232->485 mode char_received: mov tl0, #48 clr tf0 sjmp wait_data_end ;this routine runs every 0.27778 ms (3600 Hz). we transmit an ;incrementing byte at a controlled rate, which the linux-based ;software will use as its time base. xmit_timing_byte: djnz r0, wait_data_end mov r0, #xmit_rate inc r1 mov sbuf, r1 sjmp wait_data_end