嵌入式学习-uboot-lesson6-时钟初始化
1 6410时钟体系从上图和原理图可以知道下面的内容: 1.采取12M的晶振 2 有3个分频器 APLL MPLL EPLL 3.产生了4个时钟 ACLK HCLK PCLK SCLK 下面是几个时钟的利用范围: 其中ACLK为系统时钟,HCLK和PCLK为各种外设和内部的时钟,SCLK暂且不斟酌 2时钟初始化进程从上图可以看出,SYSCLK为系统时钟,起初频率为12MHZ,当设置频率以后,系统频率为有1段时间为0,这1时间为lock time ,如果要设置,可以对其进行操作,但是,1般情况下不需要,保持默许便可. 设置时钟,需要进行1下几个步骤:
默许为初始值,所以不需要做 如上图,6410共有3个locktime 分别为 APLL_LOCK MPLL_LOCK EPLL_LOCK,其寄存器的默许值都为0XFFFF,因此保持不变,不需要改变
主要是设置 ACLK HCLK PCLK SCLK之间的比例关系或说设置他们之间的频率范围 从上图可以简化出频率的产生进程 其中红色部份为本课时钟需要的频率,是根据uboot中6410的频率得来的,因此需要根据设置好的频率来设置参数, 看上面两幅图,可以得知,要想设置ARMCLK HCLKX2 HCLK PCLK的频率,需要设置 根据上图的红色编号,可以肯定4个数的值 #define CLK_DIV0 0x7e00f020
#define DIV_VAL ((0X0<<0)|(0X1<<9)|(0X1<<8)|(0X3<<12)) @
ldr r0,=CLK_DIV0 @设置分频系数
ldr r1,=DIV_VAL @将DIV_VAL的值写入寄存器
str r1,[r0]
当CPU工作时钟和内存的时钟不1样的时候,需要把CPU 的时钟模式设为异步模式 根据上图,需要把第7位设置为0异步工作模式,同时也需要把第6位设置为0,主要缘由是使HCLKx2获得到的时钟源来自MPLL而不是APLL,以下图所示。 #define OTHERS 0x7e00f900
ldr r0,=OTHERS @设置异步工作模式 第7位为0 第6位为0(时钟选择器)
ldr r1,[r0]
bic r1,r1,#0xc0 @
str r1,[r0]
要想设置APLL和MPLL的值为533Mhz,根据上图的计算公式和给出的表,可知需要设置 MDIV=266 PDIV=3 SDIV=1 根据下图,则配置相应的寄存器,同时 第31位 ENABLE位需要设置为1 #define MPLL_CON 0X7E00F010
#define APLL_CON 0X7E00F00c
#define PLL_VAL ((1<<31)|(266<<16)|(3<<8)|(1<<0))
ldr r0,=APLL_CON @设置为533Mhz
ldr r1,=PLL_VAL
str r1,[r0]
ldr r0,=MPLL_CON
ldr r1,[r0]
根据上图,需要选择使用是使用晶振频率或MPLL作为后续时钟源,因此需要设置CLK_SRC[1]=1 根据上面两幅图,将其寄存器配置为1 #define CLK_SRC 0x7e00f01c
ldr r0,=CLK_SRC @选择时钟源为APLL MPLL还是外部
mov r1,#0x3 @APLL MPLL
str r1,[r0]
mov pc,lr 总的代码: @****************************
@name: start.S
@by : stone
@time: 2016.6.26
@function:
@ 异常向量表
@ 设置SVC模式
@ 关闭看门狗
@ 关闭中断
@ 关闭MMU
@ 外设基地址初始化
@ 点亮LED
@ 时钟初始化
@****************************
.text
.global _start @将_start声明为全局变量
_start:
b reset
ldr pc,_undefined_instruction
ldr pc,_software_interrupt
ldr pc,_prefetch_abort
ldr pc,_data_abort
ldr pc,_not_used
ldr pc,_irq
ldr pc,_fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
undefined_instruction: @处理未定义指令异常
nop
software_interrupt: @软中断
nop
prefetch_abort: @预取指令异常
nop
data_abort: @数据访问异常
nop
not_used: @空位
nop
irq: @中断
nop
fiq: @快速中断
nop
reset: @reset
bl set_svc @设置为SVC模式
bl set_peri_port @外设基地址初始化
bl disable_watchdog @关闭看门狗
bl disable_interrupt @关闭中断
bl disable_mmu @关闭mmu
bl init_clock @时钟初始化
bl light_led @点亮LED
set_svc:
mrs r0,cpsr @将值取出cpsr寄存器
bic r0,r0,#0x1f @将后5位 即M[4:0]清零
orr r0,#0xd3 @0b10011 转化为16进制为0x13 同时为了屏蔽irq和fiq,可以将其设置为0b11010011即0xd3
msr cpsr,r0 @将值送回cpsr寄存器
mov pc,lr @返回
set_peri_port:
ldr r0,=0x70000000 @基地址
orr r0,#0x13 @256MB
mcr p15,0,c15,c2,4 @写入cp15
mov pc,lr
#define pwTCON 0x7E004000 @WTCON寄存器
disable_watchdog:
ldr r0,=pwTCON @把地址装载到R0
mov r1,#0x0 @置0,关闭看门狗
str r1,[r0]
mov pc,lr
disable_interrupt:
mvn r1,#0x0 @0x0 取反,给r1
ldr r0,=0x71200014 @VIC0
str r1,[r0]
ldr r0,=0x71300014 @VIC1
str r1,[r0]
mov pc,lr
disable_mmu:
mcr p15,c7,0 @使ICACHE 和DCACHE 无效
mrc p15,c1,c0,0 @read control register
bic r0,#0x00000007 @mmu 和 dcache置零
mcr p15,0 @write control register
mov pc,lr
#define CLK_DIV0 0x7e00f020
#define CLK_SRC 0x7e00f01c
#define OTHERS 0x7e00f900
#define MPLL_CON 0X7E00F010
#define APLL_CON 0X7E00F00c
#define PLL_VAL ((1<<31)|(266<<16)|(3<<8)|(1<<0))
#define DIV_VAL ((0X0<<0)|(0X1<<9)|(0X1<<8)|(0X3<<12))
init_clock:
ldr r0,=DIV_VAL
str r1,=OTHERS @设置异步工作模式 第7位为0 第6位为0(时钟选择器)
ldr r1,#0xc0
str r1,=APLL_CON @APLL设置为533Mhz
ldr r1,=MPLL_CON @MPLL设置为533Mhz
ldr r1,#0x3 @APLL MPLL
str r1,lr
#define GPMCON 0x7F008820 @控制寄存器
#define GPMDAT 0x7F008824 @数据寄存器
light_led:
ldr r0,=GPMCON
ldr r1,=0x1111 @输出模式
str r1,=GPMDAT
ldr r1,=0x00 @低电平点亮
str r1,[r0]
mov pc,lr 菜鸟1枚,如有毛病,多多指教。。。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |