发 帖  
原厂入驻New
[资料]

自动波特率检测

2011-7-20 16:21:14  6967 寄存器 波特率 定时器
分享
此代码尝试自动检测用户的波特率,并初始化8051的内置UART -。更具体而言,采取这些步骤:
  • 如果代码是正确的波特率组装的,跳到第5步。
  • 如果我们先前检​​测到的波特率,跳到第5步。
  • 等待用户按下回车键(又名回车)及数位到达需要多长时间。
  • 计算用户的波特率所需的定时器重载值。
  • 商店的结果,使我们可以(希望)跳过检测波特率,如果这个代码又被称为。
  • 各种特殊功能寄存器进行初始化。
它是如何工作当用户按下回车键,他们的终端仿真程序发送13字节,这将发送如下所示:               0 1 0 1 1 0 0 0 0 1 | | | |启动位---- + - LSB MSB - +----停止位[size=-2]注:有一天,我就画了这个漂亮的图片,以取代cheezy ASCII艺术。
代码读取P3.0,这是RXD引脚,并等待,使其成为低,这被假定为起始位 。当它再次变高,timer1是在16位模式下启动 。等待上面显示的剩余转换的代码。在停止位的开始时,Timer1停止。如果一切顺利,在Timer1的16位值,应说明有多少个CPU周期,而代码等8 个数据位。
8051使用Timer1的生成其内置的UART时钟。虽然可以在任何模式中使用定时器,extreemly缓慢波特率需要是最有意义的,除非使用8位自动重装。此代码仅在8位自动重装模式下的Timer1配置。虽然这段代码使得配置内置的UART容易,应该注意到,8051的UART需要定时器产生波特率时钟,并不能在不影响UART的改变。
内置的UART需要16个时钟周期(由Timer1),每个位 。由于代码定时所有8位,将自动重载模式的定时器初始化需要的值是CPU周期数除以128计算。必须小心避免四舍五入的错误,将产生一个不准确的波特率值的。这种错误出现在PAULMON1。的代码提交,修复这个bug是相同的波特率自动检测代码 PAULMON2 。
可用的波特率因为8051的UART需要TIMER1,这是由晶体(12分),波特率8051的硬件可以产生时钟:
波特率=水晶/(12 * 16 * N)
其中“N”是一个从1到255之间的整数。此代码将选择可用的波特率,这是最接近收到的。通常情况下,约2.5%的错误仍然会管理沟通无麻烦,但大大超出,将有问题的,如果它工作在所有。许多晶体可用标准波特率的确切倍数。通常情况下,这些晶体提供更快的波特率,不是简单地切换到更快的晶体。例如,一个4 MHz晶振提供1200波特。切换到8 MHz的最大升幅为2400波特,但切换到3.6864 MHz的晶振将允许19200波特!
下面是一些标准的晶体和最高标准波特率应该与他们的总结:

水晶(兆赫)最大波特率错误
1.003002.12%
1.843296000.00%
2.003000.79%
2.45763000.78%
3.0012000.16%
3.5795453000.23%
3.6864192000.00%
4.0012002.12%
4.19430424001.14%
4.9152012001.59%
5.0024001.36%
5.068824000.00%
6.0024000.16%
6.14412001.23%
7.3728384000.00%
8.0024002.12%
10.0048001.36%
10.73863524001.32%
11.00576000.54%
11.0592576000.00%
12.0048000.16%
12.28824001.23%
14.3181824000.23%
14.7456384000.00%
15.00384001.73%
16.0048002.12%
18.432192000.00%
20.0096001.36%
22.11841152000.00%
24.0096000.16%
24.57648001.23%
25.0048000.47%
28.0096001.27%
32.0096002.12%
[size=-1]一个位的Perl代码生成此表 ...
波特率(如发展与PAULMON)用晶体,它提供了一个更快的波特率可以是一个很大的改进,即使是较低的频率,速度是有限的应用。





  1. ; To set the baud rate, use this formula or set to 0 for auto detection
  2. ; baud_const = 256 - (crystal / (12 * 16 * baud))

  3. .equ    baud_const, 0           ;automatic baud rate detection
  4. ;.equ   baud_const, 255         ;57600 baud w/ 11.0592 MHz
  5. ;.equ   baud_const, 253         ;19200 baud w/ 11.0592 MHz
  6. ;.equ   baud_const, 252         ;19200 baud w/ 14.7456 MHz
  7. ;.equ   baud_const, 243         ;4808 baud w/ 12 MHz


  8. ;to do automatic baud rate detection, we assume the user will
  9. ;press the carriage return, which will cause this bit pattern
  10. ;to appear on port 3 pin 0 (CR = ascii code 13, assume 8N1 format)
  11. ;
  12. ;              0 1 0 1 1 0 0 0 0 1
  13. ;              | |             | |
  14. ; start bit----+ +--lsb   msb--+ +----stop bit
  15. ;
  16. ;we'll start timer #1 in 16 bit mode at the transition between the
  17. ;start bit and the LSB and stop it between the MBS and stop bit.
  18. ;That will give approx the number of cpu cycles for 8 bits.  Divide
  19. ;by 8 for one bit and by 16 since the built-in UART takes 16 timer
  20. ;oveRFlows for each bit.  We need to be careful about roundoff during
  21. ;division and the result has to be inverted since timer #1 counts up.  Of
  22. ;course, timer #1 gets used in 8-bit auto reload mode for generating the
  23. ;built-in UART's baud rate once we know what the reload value should be.

  24. autobaud:
  25.         mov     tmod, #0x11     ;get timer #1 ready for action (16 bit mode)
  26.         mov     tcon, #0x00
  27.         clr     a
  28.         mov     th1, a
  29.         mov     tl1, a
  30.         mov     a, #baud_const  ;skip IF user supplied baud rate constant
  31.         jnz     autoend
  32.         mov     a, 0x7B         ;is there a value from a previous boot?
  33.         xrl     0x7A, #01010101b
  34.         xrl     0x79, #11001100b
  35.         xrl     0x78, #00011101b
  36.         cjne    a, 0x7A, autob2
  37.         cjne    a, 0x79, autob2
  38.         cjne    a, 0x78, autob2
  39.         sjmp    autoend
  40. autob2: jb      p3.0, *         ;wait for start bit
  41.         jb      p3.0, autob2
  42.         jb      p3.0, autob2    ;  check it a few more times to make
  43.         jb      p3.0, autob2    ;  sure we don't trigger on some noise
  44.         jb      p3.0, autob2
  45.         jnb     p3.0, *         ;wait for bit #0 to begin
  46.         setb    tr1             ;and now we're timing it
  47.         jb      p3.0, *         ;wait for bit #1 to begin
  48.         jnb     p3.0, *         ;wait for bit #2 to begin
  49.         jb      p3.0, *         ;wait for bit #4 to begin
  50.         jnb     p3.0, *         ;wait for stop bit to begin
  51.         clr     tr1             ;stop timing
  52.         mov     a, tl1
  53.         mov     c, acc.6        ;save bit 6 for rounding up if necessary
  54.         mov     f0, c
  55.         mov     c, acc.7        ;grab bit 7... it's the lsb we want
  56.         mov     a, th1
  57.         rlc     a               ;do the div by 128
  58.         mov     c, f0
  59.         addc    a, #0           ;round off if necessary
  60.         cpl     a               ;invert since timer #1 will count up
  61.         inc     a               ;now acc has the correct reload value (I hope)
  62. autoend:mov     0x7B, a
  63.         mov     0x7A, a         ;store the baud rate for next wARM boot.
  64.         mov     0x79, a
  65.         mov     0x78, a
  66.         xrl     0x7A, #01010101b
  67.         xrl     0x79, #11001100b
  68.         xrl     0x78, #00011101b
  69.         mov     th1, a
  70.         mov     tl1, a
  71.         mov     tmod, #0x21     ;set timer #1 for 8 bit auto-reload
  72.         mov     pcon, #0x80     ;configure built-in uart
  73.         mov     scon, #0x52
  74.         setb    tr1             ;start the baud rate timer
  75.         mov     r0, #0
  76.         djnz    r0, *
  77.         djnz    r0, *
  78.         ret


复制代码



1
分享淘帖 显示全部楼层

只有小组成员才能发言,加入小组>>

483个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /8 下一条

快速回复 返回顶部 返回列表