要正确计算串口波特率,首先要搞清楚芯片的时钟工作原理,这部分在
s3c2410/s3c2440datasheet上写的比较详细,但对新手来说结合thisway同志
“s3c2410完全开发流程”中的TIMER和CLOCK两个实验,边做实验边看资料,更容易
理解。
我这里只根据我的失败经验谈一下设置波特率寄存器UBRDIVn的值的计算要注意的一
个问题。
datasheet上UBRDIVn寄存器部分写着:
UART BAUD RATE DIVISOR REGISTER
There are three UART baud rate divisor registers including UBRDIV0,
UBRDIV1 and UBRDIV2 in the UART block.
The value stored in the baud rate divisor register (UBRDIVn), is used to
determine the serial Tx/Rx clock rate (baudrate) as follows:
UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
( UART clock: PCLK, FCLK/n or UEXTCLK )
Where, UBRDIVn should be from 1 to (216-1), but can be set zero only
using the UEXTCLK which should be smaller than PCLK.
For example, if the baud-rate is 115200 bps and UART clock is 40 MHz,
UBRDIVn is:
UBRDIVn = (int)(40000000 / (115200 x 16) ) -1
= (int)(21.7) -1 [round to the nearest whole number]
= 22 -1 = 21
也就是说,只要知道这个UART clock 就计算出UBRDIVn 的值,下面分别讲:
1. UEXTCLK
查手册:The UART can support bit rates up to 115.2K bps using system
clock. If an external device provides the UART with UEXTCLK, then the
UART can operate at higher speed.是说当用系统时钟(system clock)时UART波
特率最高可达到115200,但是如果用这个UEXTCLK(external clocks for the UART
operation)串口外设时钟,可以设置115200以上的波特率。
2. PCLK和FCLK/n
这里又分两种情况:使用MPLL和不使用MPLL
我们知道s3c2410最高频率可达266M,s3c2440最高频率可达533M,而一般外接晶振
只有几十M,如何使几十M变成几百M呢?这就是MPLL的功劳了
s3c2410有两个pll(phase locked loop,锁相环,在高频中学过,可以实现倍频,
s3c2410的高频就是由此电路产生的)。其中一个是MPLL,M即为main,用来产生三
种时钟信号:Fclk(给CPU核供给时钟信号,我们所说的s3c2410的cpu主频为200MHz
,就是指的这个时钟信号,相应的,1/Fclk即为cpu时钟周期)、Hclk(为AHB bus
peripherals供给时钟信号,AHB为advanced high-performance bus)、Pclk(为
APB bus peripherals供给时钟信号,APB为advanced peripherals bus)。AHB和
APB这两种总线所连的外设是有区别的。AHB总线连接高速外设,低速外设则通过APB
总线互连。显然,对不同总线上的外设,应该使用不同的时钟信号,AHB总线对应
Hclk,APB总线对应Pclk。那么事先就应该弄清楚,每条总线对应的外设有那些,这
样在设置好时钟信号后,对应外设的初始化的值就要依此而确定了。
当不使用MPLL(即不设置MPLLCON寄存器)时,外部晶振直接作为系统时钟。一般外
部晶振有两个,一是用于系统时钟,为12MHz(或其他,由具体板子决定);一个用
于实时时钟(RTC,real time clock,根据CPU的要求送出或设定时钟、日历的各种
数据),为32.768KHz。此时,PCLK即为12MHz。
当使用MPLL时,要通过对寄存器MPLLCON和CLKDIVN的设置来得到FCLK、HCLK和PCLK
。
得到这个UART clock(PCLK, FCLK/n or UEXTCLK ),根据公式
UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
来计算就简单了。