EtherNut 的一个例子中的自动波特率检测。
看到有人翻这东西,干脆摘出点代码来~~/*
* Automatic baudrate detection.
*
* Switch to different baud rates and wait
* for a space character.
*/
int DetectSpeed(void)
{
#if defined (__AVR__)
u_char bstab[] = {
1, /* 115200 @3.6864 */
7, /* 115200 @ 14.7456 */
23, /* 9600 @3.6864, 19200 @7.3728, 38400 @ 14.7456 */
11, /*19200 @3.6864, 38400 @7.3728, 76800 @ 14.7456 */
12, /*19200 @4.0000, 38400 @8.0000, 57600 @ 12.0000, 76800 @ 16.0000 */
25, /* 9600 @4.0000, 19200 @8.0000, 38400 @ 16.0000 */
5, /*38400 @3.6864, 76800 @7.3728 */
47, /* 9600 @7.3728, 19200 @ 14.7456 */
51, /* 9600 @8.0000, 19200 @ 16.0000 */
3, /* 115200 @7.3728 */
9, /* 115200 @ 18.4320 */
2, /*76800 @3.6864 */
14, /*76800 @ 18.4320 */
29, /*38400 @ 18.4320 */
64, /*19200 @ 20.0000 */
59, /*19200 @ 18.4320 */
95, /* 9600 @ 14.7456 */
103, /* 9600 @ 16.0000 */
119, /* 9600 @ 18.4320 */
129, /* 9600 @ 20.0000 */
77 /* 9600 @ 12.0000 */
};
u_char bsx;
int bs;
u_short i;
u_char t;
u_char rec;
u_char ict; /* Imagecraft dummy */
/*
* Enable UART transmitter and receiver.
*/
outb(UCR, _BV(RXEN) | _BV(TXEN));
/*
* Sixteen retries.
*/
for (t = 1; t < 16; t++) {
for (bsx = 0; bsx < sizeof(bstab); bsx++) {
bs = bstab;
/*
* Set baudrate selector.
*/
Delay(1000);
if ((inb(USR) & _BV(RXC)) != 0)
ict = inb(UDR);
outb(UBRR, (u_char) bs);
Delay(1000);
if ((inb(USR) & _BV(RXC)) != 0)
ict = inb(UDR);
/*
* Now wait for some time for a character received.
*/
for (i = 0; i < 40; i++) {
if ((inb(USR) & _BV(RXC)) != 0)
break;
Delay(1000);
}
rec = 0;
for (i = 1; i; i++) {
if ((inb(USR) & _BV(RXC)) != 0) {
if (inb(UDR) == 32) {
if (rec++)
return bs;
i = 1;
} else {
rec = 0;
break;
}
} else if (rec)
Delay(100);
}
}
}
outb(UBRR, 23);
#endif
return -1;
} mark mark mark
页:
[1]