The Problem: How can you automatically detect and set the hardware USART to match the incoming baudrate of an external source?
In the example below you will find my initial solution written entirely in PBP. It requires only one character be sent for synchronization (I chose the ascii space character as my baud rate detect character).
The original idea for this came from an article written by Eddy Carroll www.iol.ie/~ecarroll/autobaud.html in April of 1989. The idea of which was, that a given character would be interpreted in unique bit patterns if sent at different baud rates, and assuming the receiver was set to a "fixed" baud rate.Code:'******************************************* ' USART Auto Baud Rate Detection ' Author: Michael St. Pierre ' Date: 10/25/2005 ' Notes: Based on Eddy Carroll article, ' April 1989 '******************************************* DEFINE LOADER_USED 1 ' use for Boot Loader DEFINE OSC 40 '============================================ ' Equates (for PIC18F252 or PIC18F452) '============================================ baudset var bit rxdata var byte Clear RCIF VAR PIR1.5 ' USART receive interrupt flag BRGH VAR TXSTA.2 ' High Baud Rate Select bit OERR VAR RCSTA.1 ' Overrun Error bit CREN VAR RCSTA.4 ' Continuous Receive Enable bit '============================================ ' Initialize USART '============================================ ' Set-up USART for initial 19.2K Baud Operation for 40 Mhz oscillator SPBRG = 129 TXSTA = %00100100 RCSTA = %10010000 '============================================ ' Program Start (MAIN) '============================================ mainloop: While RCIF = 0: Wend ; loop until data present in USART buffer rxdata = RCREG ; retrieve data. If baudset = 0 Then ; If this is the initial pass... Gosub Autobaud ; detect and set baudrate, baudset = 1 ; deactivate Auto-Baud Rate Detection, Goto mainloop ; and skip data send. Endif TXREG = rxdata ; Send valid data bytes only! Goto mainloop '============================================ ' Auto Baud Rate Detection Routine ' (Entry Baud Rate set to 19.2K) '============================================ ; A single space " " character required for auto detect function ; !!! No other characters should be sent prior to space !!! ; Format of data upon reception of space " " character: ; 4800 baud: 0 128 (2 bytes) ; 9600 baud: 0 248 (2 bytes) ; 19.2k baud: 32 ; 38.4k baud: 244 or 252 (slight amount of uncertainty in data) Autobaud: If rxdata = 0 Then ; If 1st byte received = 0 then... While RCIF = 0: Wend ; Loop until 2nd valid byte received, rxdata = RCREG ; and fetch data. Endif Select Case rxdata Case 128 ; @4800 Baud (2nd of two data bytes received) BRGH = 0 SPBRG = 129 Case 248 ; @9600 Baud (2nd of two data bytes received) BRGH = 0 SPBRG = 64 Case 32 ; @19.2K Baud (1st and only data byte received) BRGH = 1 SPBRG = 129 Case Else ; @38.4K Baud (1st and only data byte received) BRGH = 1 SPBRG = 64 End Select If OERR Then ; If receive buffer overflowed, clear it! CREN = 0 CREN = 1 Endif Return ; Done, baud rate now set!
In my example, I have enabled 4 different baud rate frequencies to be detected (4800, 9600, 19.2K, 38.4K). These just happened to be the 4 that would properly work with an oscillator freq = 40 Mhz, without producing excessive bit errors. Other ranges can be used, but will require a crystal change, and different SPBRG and BRGH settings, and possibly different comparison strings based on the incoming data.
Any ideas on how to impove it?


Tantalum and ceramic are the one i use.


Bookmarks