;******************************************************************** ; Listing 1 -- RS-232 TRANSMISSION-RATE DETECTION ROUTINE ; ; "uC detects transmission rate of RS-232 interface," ; EDN, Sept 30, 1999, pg 114. ; http://www.ednmag.com/ednmag/reg/1999/093099/designideas.htm#20di2 ; ;******************************************************************** Autobaud clrf AUTOBAUD_LOW ; reset register clrf AUTOBAUD_HIGH ; reset register clrf AUTOHALF_LOW ; reset register clrf AUTOHALF_HIGH ; reset register clrf AUTOB_STATUS ; reset autobaud status ; register TestStartBit btfsc PORTA, RX ; check for start-bit goto TestStartBit ; Start-bit not found TestBitHigh btfsc PORTA, RX ; Test for end of bit ; stream goto Calculate ; End of bit stream, now ; calculate ; bit time for one bit incfsz AUTOBAUD_LOW, f ; increment Autobaud ;low register goto TestBitHigh ; test for high bit incfsz AUTOBAUD_HIGH, f ; increment high byte ; of autobaud ; register goto TestBitHigh ; test for end of bit stream goto Signal2Slow ; High byte got an overflow. ; Transmitted ; signal is too slow for clock ; speed of the uC ; divide by measure time by 6 (6 one's where transmitted) Calculate movlw 0x03 ; Initialize count register movwf COUNTER ; Counter for number for rotates ; = 3 Divide bcf STATUS, C ; clear carry bit rrf AUTOBAUD_HIGH,f ; rotate autobaud high register rrf AUTOBAUD_LOW, f ; rotate autobaud low register decfsz COUNTER, f ; decrement counter goto Divide ; divide ; Calculate half the bit time CalcHalfBit bcf STATUS, C ; clear carry bit rrf AUTOBAUD_HIGH,w ; rotate autobaud high register movwf AUTOHALF_HIGH ; copy result into AUTOHALF_HIGH ; register rrf AUTOBAUD_LOW, w ; rotate autobaud high register movwf AUTOHALF_LOW ; copy result into AUTOHALF_LOW ; register AdjustLowByte movlw 0x3 ; 18-19 instruction cycles ;overhead from ; transmit and receive routine. subwf AUTOBAUD_LOW, f ; Adjust low byte from Autobaud ;counter btfss STATUS, C ; Is result negative? (equal=0 ; will be checked ; at ErrorCheck). C=0 result is ; negative goto Signal2Fast ; Signal is too fast for receive ;and transmit routine movlw 0x02 ; substract 2 from low byte of ; half the bit time subwf AUTOHALF_LOW, f ; substract from low byte of half ; the bit time btfss STATUS, C ; Is result negative? (equal=0 ; will be checked ; at ErrorCheck). C=0 result is ; negative goto Signal2Fast ; Signal is too fast for receive ; and transmit routine ; check if AUTOBAUD_HIGH and AUTOBAUD_LOW are zero. This ; means the transmission time for one byte is too high ErrorCheck movf AUTOBAUD_HIGH,w ; copy high byte of autobaud ;counter register into ; w-register xorwf AUTOBAUD_LOW, w ; AUTOBAUD_HIGH = AUTOBAUD_LOW? btfss STATUS, Z ; is result zero? goto ErrorCheckHalf ; Result is not zero, therefore ; finish autobaud routine goto Signal2Fast ; Signal is too fast for routine ErrorCheckHalf movf AUTOHALF_HIGH,w ; copy high byte of ; autobaud ;counter register into ; w-register xorwf AUTOHALF_LOW, w ; AUTOBAUD_HIGH = ; AUTOBAUD_LOW? btfss STATUS, Z ;is result zero? goto EndAutoBaud ; Result is not zero, ; therefore finish autobaud ; routine ; Error: delay for half the bit time is zero, therefore a ; delay cannot be generated with the delay routines. ; Incoming signal is too fast for clock speed. Signal2Fast bsf AUTOB_STATUS, SIGNAL_FAST ; set error flag retlw 0x00 ; return to OS Signal2Slow bsf AUTOB_STATUS, SIGNAL_SLOW ; set error ;flag EndAutoBaud retlw 0x00 ; Return to operating system Page - 3/3 -