怎么打开无线网络开关:S3C2440系统时钟

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 04:16:44
S3C2440系统时钟

MINI2440开发板在没有开启时钟前,整个开发板全靠一个12MHz的晶振提供频率来运行,也就是说CPU,内存,UART等需要用到时钟频率的硬件都工作12MHz下,而S3C2440A可以正常工作在400MHz下,两者速度相差可想而知,就好比牛车和动车。如果CPU工作在12MHz频率下,开发板的使用效率非常低,所有依赖系统时钟工作的硬件,其工作效率也很低,比如,我们电脑里面经常提到的超频,超频就是让CPU工作在更高的频率下,让电脑运算速度更快,虽然频率是越高越好,但是由于硬件特性决定了任何一个设备都不可能无止境的超频,电脑超频时要考虑到CPU或主板发热过大,烧坏的危险,同样开发板的主板上的外设和CPU也有一个频率限度,ARM920T内核的S3C2440的最高正常工作频率如下:
l   FCLK:400MHz
l   HCLK:100MHz
l   PCLK:50MHz
既然如此,那么怎样让CPU工作在400MHz,让牛车速度提高到动车的速度呢?
在对系统时钟进行提速之前,让我们先来了解下S3C2440上的工作时钟频率,FCLK,HCLK,PCLK,其中FCLK主要为ARM920T内核提供工作频率,如图2-44所示:

图2-44  ARM920T内核结构
HCLK主要为S3C2440 AHB总线(Advanced High performance Bus)上挂接硬件提供工作频率,AHB总线主要挂接有内存,NAND,LCD控制器等硬件,如图2-45所示:

图2-45 S3C2440 AHB总线上挂接硬件
PCLK主要为APB总线提供工作频率,由图2-46所示,APB总线主要挂接UART串口,Watchdog等硬件控制器。

图2-46 S3C2440 APB总线挂接硬件
也就是说,对于一些需要时钟工作的硬件,如果切断其时钟源 ,就不会再工作,从而达到降低功耗的目的,这也是便携嵌入式设备里的一个特点。
时钟源:为了减少外界环境对开发板电磁干扰,降低制作成本,通常开发板的外部晶振时钟频率都很低,MINI2440开发板由12MHz的晶振来提供时钟源,要想让CPU运行在更高的频率就要通过时钟控制逻辑单元PLL(锁相环)来提高主频。
S3C2440里有两个PLL:MPLL和UPLL,MPLL用来产生FCLK,HCLK,PCLK的高频工作时钟,UPLL用来为USB提供工作频率。

图2-47系统时钟初始化时序
开发板上电后,晶振OSC开始提供晶振时钟,由于系统刚刚上电,电压信号等都还不稳定,这时复位信号(nRESET)拉低,这时MPLL虽然默认启动,但是如果不向MPLLCON中写入值,那么外部晶振则直接作为系统时钟FCLK,过几毫秒后,复位信号上拉,CPU开始取指运行,这时可以通过代码设置启动MPLL,MPLL启动需要一定锁定时间(LockTime),这是因为MPLL输出频率还没有稳定,在这期间FCLK都停止输出,CPU停止工作,过了LockTime后时钟稳定输出,CPU工作在新设置的频率下,这时可以通过设置FCLK,HCLK和PCLK三者的频率比例来产生不同总线上需要的不同频率,下面详细介绍开启MPLL的过程:
l  设置LockTime变频锁定时间
l  设置FCLK与晶振输入频率(Fin)的倍数
l  设置FCLK,HCLK,PCLK三者之间的比例
LockTime变频锁定时间由LOCKTIME寄存器(见下表)来设置,由于变频后开发板所有依赖时钟工作的硬件都需要一小段调整时间,该时间计数通过设置LOCKTIME寄存器[31:16]来设置UPLL(USB时钟锁相环)调整时间,通过设置LOCKTIME寄存器 [15:0]设置MPLL调整时间,这两个调整时间数值一般用其默认值即可。
表2-8变频锁定时间寄存器(LOCKTIME)
寄存器名
地址
是否读写
描述
复位默认值
LOCKTIME
0x4C000000
R/W
变频锁定时间寄存器
0xFFFFFFFF
LOCKTIME

描述
初始值
U_TIME
[31:16]
UPLL对UCLK的锁定时间值
(U_TIME:300us)
0xFFFF
M_TIME
[15:0]
MPLL对于FCLK,HCLK,PCLK的锁定时间值(M_TIME:300us)
0xFFFF
FCLK与Fin的倍数通过MPLLCON寄存器设置,三者之前有以下关系:
MPLL(FCLK) = (2*m*Fin)/(p*2^s)
其中:m = MDIV + 8, p = PDIV + 2, s = SDIV
当设置完MPLL之后,就会自动进入LockTime变频锁定期间,LockTime之后,MPLL输出稳定时钟频率。
表2-9 MPLL配置寄存器(MPLLCON)
寄存器名
地址
是否读写
描述
复位默认值
MPLLCON
0x4C000004
R/W
MPLL配置寄存器
0x00096030
MPLLCON

描述
初始值
MDIV
[19:12]
主分频器控制位
0x96
PDIV
[9:4]
预分频器控制位
0x03
SDIV
[1:0]
后分频器控制位
0x0
通过上述算法比较难以找到合适的PLL值,下表给出了官方推荐的一些MPLL参考设置:
表2-10 官方推荐MPLL

FCLK,HCLK,PCLK三者之间的比例通过CLKDIVN寄存器进行设置,S3C2440时钟设置时,还要额外设置CAMDIVN寄存器,如下表,HCLK4_HALF,HCLK3_HALF分别与CAMDIVN[9:8]对应,下表列出了各种时钟比例:
表2-11 FCLK HCLK PCLK设置比例

如果HDIV设置为非0,CPU的总线模式要进行改变,默认情况下FCLK = HCLK,CPU工作在fast bus mode快速总线模式下,HDIV设置为非0后, FCLK与HCLK不再相等,要将CPU改为asynchronous bus mod异步总线模式,可以通过下面的嵌入汇编代码实现:
__asm{
mrc p15, 0, r1, c1, c0, 0         /* 读取CP15 C1寄存器 */
orr r1, r1, #0xc0000000         /* 设置CPU总线模式 */
mcr p15, 0, r1, c1, c0, 0         /* 写回CP15 C1寄存器 */
}
关于mrc与mcr指令,请查看MMU与内存保护的实现章节。
表2-12时钟分频器控制寄存器(CLKDIVN)
寄存器名
地址
是否读写
描述
复位默认值
CLKDIVN
0x4C000014
R/W
时钟分频器控制寄存器
0x00000000
CLKDIVN

描述
初始值
DIV_UPLL
[3]
UCLK选择寄存器(UCLK必须对USB提供48MHz)
0:UCLK=UPLL clock
1:UCLK=UPLL clock/2
0
HDIVN
[2:1]
00:HCLK = FCLK/1
01:HCLK = FCLK/2
10:HCLK = FCLK/4,当CAMIVN[9]=0
HCLK = FCLK/8,当CAMIVN[9]=1
11: HCLK = FCLK/3,当CAMIVN[8]=0
HCLK = FCLK/6,当CAMIVN[8]=1
0
PDIVN
[0]
0:PCLK是和HCLK/1相同时钟
1:PCLK是和HCLK/2相同时钟
0
表2-13摄像头时钟分频控制寄存器(CAMDIVN)
寄存器名
地址
是否读写
描述
复位默认值
CAMDIVN
0x4C000018
R/W
摄像头时钟分频控制寄存器
0x00000000
CAMDIVN

描述
初始值




HCLK4_HALF
[9]
HDIVN分频因子选择位(当CLKIVN[2:1]位为10b时有效)
0: HCLK=FCLK/4
1: HCLK=FCLK/8
0
HCLK3_HALF
[8]
HDIVN分频因子选择位(当CLKIVN[2:1]位为11b时有效)
0: HCLK=FCLK/3
1: HCLK=FCLK/6
0




2
系统时钟驱动可以分别用ARM汇编和C语言两个版本实现。
ARM汇编版本:
; 以下为时钟相关寄存器地址
LOCKTIME                                    EQU     0x4c000000
MPLLCON                                 EQU                   0x4c000004
CLKDIVN                                  EQU                   0x4c000014
CAMDIVN                                          EQU                   0x4c000018
clock_init                                                            ; 时钟初始化代码
; 设置变频锁定时间
ldr r0, =LOCKTIME
ldr r1, =0x00ffffff
str r1, [r0]
; 设置分频比FCLK:HCLK:PCLK=1:4:8
; 由于CAMDIVN[9]位初始值为0,寄存器CAMDIVN未使用,这儿不用再设置其值
ldr r0, =CLKDIVN
mov r1, #0x05
str r1, [r0]
; 修改CPU总线模式
mrc   p15, 0, r1, c1, c0, 0
orr    r1, r1, #0xc0000000
mcr     p15, 0, r1, c1, c0, 0
ldr r0, =MPLLCON
ldr r1, =0x5c011                                ; MPLL = 400MHz
str r1, [r0]
mov pc, lr                                           ; 函数调用返回
该汇编代码入口处先设置了变频锁定时间为0x00ffffff,然后设置FCLK:HCLK:PCLK的分频比,由于系统时钟已经改变,需要修改CPU总线模式,最后设置系统时钟工作频率。
C语言版本:
/* 通过MPLL计算公式可以算出:MDIV=92,PDIV=1,SDIV=0时,MPLL=400MHz
#define MPLL_400MHz ((92 << 12)|(1 << 4)|(1 << 0))
void clock_init(void){
/* 设置变频锁定时间 */
LOCKTIME = 0x00ffffff;
/* 设置分频比FCLK:HCLK:PCLK=1:4:8,CAMDIVN初始值为0,不用再对其设置 */
CLKDIVN  = 0x05;
/* 修改CPU总线模式 */
__asm{
mrc   p15, 0, r1, c1, c0, 0
orr     r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
}
MPLLCON = MPLL_400MHz;
}
C语言版本与汇编版本一样,只是由于修改CPU总线模式时要使用mrc指令,因此只能使用C语言嵌入汇编方式来实现。
系统时钟驱动实验:
;
; 系统时钟初始化实验
;
WTCON                        EQU          0x53000000        ; 看门狗控制寄存器
WTDAT                         EQU          0x53000004        ; 看门狗数据寄存器
LOCKTIME                  EQU     0x4c000000         ; 变频锁定时间寄存器
MPLLCON                   EQU          0x4c000004        ; MPLL寄存器
CLKDIVN                    EQU          0x4c000014        ; 分频比寄存器
GPBCON                      EQU      0x56000010        ; LED控制寄存器
GPBDAT                       EQU      0x56000014        ; LED数据寄存器
GPBUP                         EQU      0x56000018        ; 上拉电阻设置寄存器
DELAYVAL                  EQU      0x8fff                  ; 延时数值
AREA    CLOCK, CODE, READONLY
ENTRY
start
ldr r0, = 0x53000000                      ; 看门狗关闭代码
mov  r1, #0
str  r1, [r0]
bl  clock_init                                  ; 调用时钟初始化函数
bl  led_on                                      ; 调用点亮Led函数
clock_init                                                  ; 时钟初始化代码
; 设置锁频时间
ldr r0, =LOCKTIME                         ; 取得LOCKTIME寄存器地址
ldr r1, =0x00ffffff                              ; LOCKTIME寄存器设置数据
str r1, [r0]                                          ; 将LOCKTIME设置数据写入LOCKTIME寄存器
; 设置分频数
ldr r0, =CLKDIVN                           ; 取得CLKDIVN寄存器地址
mov r1, #0x05                                   ; CLKDIVN寄存器设置数据
str r1, [r0]                                          ; 将CLKDIVN设置数据写入CLKDIVN寄存器
; 修改CPU总线模式
mrc    p15, 0, r1, c1, c0, 0
orr    r1, r1, #0xc0000000
mcr    p15, 0, r1, c1, c0, 0
ldr r0, =MPLLCON
ldr r1, =0x5c011                                ; MPLL is 400MHz
str r1, [r0]
mov pc, lr
led_on                                                        ; 亮点Led函数
; Led初始化开始
ldr  r0,=GPBCON                        ; 将LED控制寄存器地址放入r0
ldr  r1,[r0]                                        ; 将控制寄存器里的值读出放入r1
bic  r1,r1,#0x3fc00                          ; 将r1里的值(控制寄存器里的值)
; bit[10]~bit[17]清位,其它位不变
orr  r1,r1,#0x15400                         ; 设置控制寄存器
str  r1,[r0]                                        ; 将r1里的值写入控制寄存器
; 禁止GPF4-GPF7端口的上拉电阻
ldr  r0,=GPBUP
ldr  r1,[r0]
orr  r1,r1,#0x1e0
str  r1,[r0]
; Led初始化结束
led_loop                                                     ; 循环点亮Led
ldr  r2,=GPBDAT                                     ; 将LED数据寄存器的地址放入r2
ldr  r3,[r2]                                        ; 将数据寄存器(r2)里的值放入r3
bic  r3,r3,#0x1e0                              ; 清除bit[5]~bit[8],bit[n]代表led1~led4
orr  r3,r3,#0x1c0                              ; 清对应Led位-亮灯,设置相应位-灭灯(点亮led1)
str  r3,[r2]                                       ; 将控制亮灯数据写入数据寄存器r2
ldr r0,=DELAYVAL                         ; 设置延迟数
bl   delay                                         ; 调用延迟子程序
ldr  r3,[r2]                                        ; 将数据寄存器(r2)里的值放入r3
bic  r3,r3,#0x1e0                              ; 清除bit[5]~bit[8],bit[n]代表led1~led4
orr  r3,r3,#0x1a0                              ; 清对应Led位-亮灯,设置相应位-灭灯(点亮led2)
str  r3,[r2]                                       ; 将控制亮灯数据写入数据寄存器r2
ldr r0,=DELAYVAL                         ; 设置延迟数
bl   delay                                       ; 调用延迟子程序
ldr  r3,[r2]                                        ; 将数据寄存器(r2)里的值放入r3
bic  r3,r3,#0x1e0                              ; 清除bit[5]~bit[8],bit[n]代表led1~led4
orr  r3,r3,#0x160                             ; 清对应Led位-亮灯,设置相应位-灭灯(点亮led3)
str  r3,[r2]                                       ; 将控制亮灯数据写入数据寄存器r2
ldr r0,=DELAYVAL                         ; 设置延迟数
bl   delay                                       ; 调用延迟子程序
ldr  r3,[r2]                                        ; 将数据寄存器(r2)里的值放入r3
bic  r3,r3,#0x1e0                              ; 清除bit[5]~bit[8],bit[n]代表led1~led4
orr  r3,r3,#0xe0                               ; 清对应Led位-亮灯,设置相应位-灭灯(点亮led4)
str  r3,[r2]                                       ; 将控制亮灯数据写入数据寄存器r2
ldr r0,=DELAYVAL                         ; 设置延迟数
bl   delay                                      ; 调用延迟子程序
b led_loop
delay
sub r0,r0,#1                             ; r0=r0-1
cmp r0,#0x0                                   ; 将r0的值与0相比较
bne delay                                                  ; 比较的结果不为0,继续调用delay
mov pc,lr                                        ; 返回
END                                ; 程序结束符
该实验首先关闭了看门狗定时器,然后修改系统时钟,将默认系统工作频率12MHz提高到400MHz,由于CPU工作在较高频率下,其执行速度明显比未启动系统时钟时高的多,可以通过注释掉系统时钟初始化代码跳转指令 bl clock_init,对比LED的跑马灯效果可以证明。
分享到:
上一篇:S3C2440看门狗定时器(Watchdog)
下一篇:S3C2440 SDRAM内存驱动
公司简介|招贤纳士|广告服务|银行汇款帐号|联系方式|版权声明|法律顾问|问题报告
北京创新乐知信息技术有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
江苏乐知网络技术有限公司 提供商务支持
Email:webmaster@csdn.net
Copyright ? 1999-2011, CSDN.NET, All Rights Reserved