huayuliang 发表于 2011-9-21 23:02:32

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;
}

山在桥那边 发表于 2014-6-7 17:58:55

mark mark mark
页: [1]
查看完整版本: EtherNut 的一个例子中的自动波特率检测。