嵌入式学习-uboot-lesson6-时钟初始化


1 6410时钟体系

从上图以及原理图可以知道下面的内容:

1.采用12M的晶振

2 有三个分频器 APLL MPLL EPLL

3.产生了四个时钟 ACLK HCLK PCLK SCLK

下面是几个时钟的应用范围:

其中ACLK为系统时钟,HCLK和PCLK为各种外设和内部的时钟,SCLK暂且不考虑


2时钟初始化过程

从上图可以看出,SYSCLK为系统时钟,起初频率为12MHZ,当设置频率之后,系统频率为有一段时间为0,这一时间为lock time ,如果要设置,可以对其进行操作,但是,一般情况下不需要,保持默认即可.

设置时钟,需要进行一下几个步骤:

1设置lock time

2.设置分频系数

3.设置CPU到异步工作模式

4.设置APLL.MPLL输出频率

  • 1设置lock time

默认为初始值,所以不需要做

如上图,6410共有三个locktime 分别为 APLL_LOCK MPLL_LOCK EPLL_LOCK,其寄存器的默认值都为0XFFFF,因此保持不变,不需要改变

  • 2.设置分频系数

主要是设置 ACLK HCLK PCLK SCLK之间的比例关系或者说设置他们之间的频率范围

从上图可以简化出频率的产生过程

其中红色部分为本课时钟需要的频率,是根据uboot中6410的频率得来的,因此需要根据设置好的频率来设置参数,

看上面两幅图,可以得知,要想设置ARMCLK HCLKX2 HCLK PCLK的频率,需要设置

DIVarm DIVhclkx2 DIVhclk DIVpclk的值,

根据上图的红色编号,可以确定四个数的值

1.ARMCLK=533/(RATIO+1)=533 因此ARM_RATIO=0

即DIVarm=0

2.HCLKX2=533/(HCLKX2_RATIO+1)=266 因HCLKX2_RATIO=1

即DIVhclkx2=1

3.HCLK=HCLKX2/(HCLK_RATIO+1)=133 因此HCLK_RATIO=1

即DIVhclk=1

4.PCLK=HCLKX2/(PCLK_RATIO+1)=66 因此PCLK_RATIO=3

即DIVpclk=3

即:

#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]
  • 3.设置CPU到异步工作模式

当CPU工作时钟和内存的时钟不一样的时候,需要把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]
  • 4.设置APLL.MPLL输出频率

要想设置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,=PLL_VAL
        str r1,[r0]
  • 5选择时钟源

根据上图,需要选择使用是使用晶振频率或者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, r0, #0xd3   @0b10011 转化为16进制为0x13 同时为了屏蔽irq和fiq,可以将其设置为0b11010011即0xd3
    msr cpsr, r0        @将值送回cpsr寄存器
    mov pc, lr              @返回

set_peri_port:
    ldr r0, =0x70000000     @基地址
    orr r0, r0, #0x13       @256MB
    mcr p15,0,r0,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,0,r0,c7,c7,0    @使ICACHE 和DCACHE 无效
    mrc p15,0,r0,c1,c0,0    @read control register
    bic r0,r0,#0x00000007   @mmu 和 dcache置零
    mcr p15,0,r0,c1,c0,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,=CLK_DIV0 @设置分频系数
        ldr r1,=DIV_VAL
        str r1,[r0]

        ldr r0,=OTHERS   @设置异步工作模式 第7位为0 第6位为0(时钟选择器)
        ldr r1,[r0]
        bic r1,r1,#0xc0
        str r1,[r0]

        ldr r0,=APLL_CON @APLL设置为533Mhz
        ldr r1,=PLL_VAL
        str r1,[r0]

        ldr r0,=MPLL_CON @MPLL设置为533Mhz
        ldr r1,=PLL_VAL
        str r1,[r0]

        ldr r0, =CLK_SRC @选择时钟源为APLL MPLL还是外部
        mov r1, #0x3     @APLL MPLL
        str r1, [r0]
        mov pc,lr

#define GPMCON 0x7F008820       @控制寄存器
#define GPMDAT 0x7F008824   @数据寄存器
light_led:
        ldr r0,=GPMCON
        ldr r1,=0x1111  @输出模式
        str r1,[r0]

        ldr r0,=GPMDAT
        ldr r1,=0x00    @低电平点亮
        str r1,[r0]
        mov pc,lr

菜鸟一枚,如有错误,多多指教。。。

时间: 2024-10-10 09:26:29

嵌入式学习-uboot-lesson6-时钟初始化的相关文章

嵌入式学习-uboot-lesson7-内存初始化

6410所使用的内存为DDR 210使用的是DDR2 2440使用的是SDRAM,关于他们之间的区别,我在以前的文章中ok6410内存及启动流程简单介绍过,有兴趣的可以看看. 1. 地址空间 S3C6410处理器拥32位地址总线,其寻址空间为4GB.其中高2GB为保留区,低2GB区域又可划分为两部分:主存储区和外设区. 外设区主要是与6410寄存器相关,在核心初始化-外设基地址初始化中,有说明外设的寄存器的基地址为0x70000000 下面则是主存储区的地址分布,在以前的课程中有介绍,现在贴出来

嵌入式学习笔记101-uboot_1.1.6移植(1)

根据前篇博文(嵌入式学习笔记100-uboot1.1.6初体验)最后的结论,现在开始将其实现: a. 修改makefile的CROSS_COMPILE指定编译器 arm-linux-gcc -v –> gcc version 3.4.5 CROSS_COMPILE = /opt/EmbedSky/crosstools_3.4.5_softfloat/gcc-3.4.5-glibc-2.3.6/arm-linux/bin/arm-linux- chmod -R 777 u-boot-1.1.6/

嵌入式学习笔记103-uboot_1.1.6移植(3)

经过之前对uboot的整体flow分析,现在开始针对2440移植,需要注意的是移植的code可能包含支持部分的2410code 不过并没有在s3c2410板子实测过. 主要概括:第一阶段的汇编code尽量短小,能用C实现的就用C,由于2440的board和头文件是从2410 copy过来的 里面会有很多信息或者宏关于2410,并且很多.c文件的头文件由于include的是2410,所以新增的一些关于2440的结构体也会一并放在2410.h,移植的思想与前文类似, 根据code的执行流程来移植.

嵌入式学习笔记008-裸奔篇之串口

串口是个好东西,前几篇裸奔程序由于没有串口,自己调试都是有led等来表示的,比较"苦逼",终于可以用串口了~~~,这里主要采用上一篇博文(嵌入式学习笔记007-裸奔篇之定时器),也就是串口也是用中断实现的,而且也只是在前一篇博文增加串口的初始化uart0_init(),以及在中断处理函数增加对串口的处理.只要稍微改造前一篇博文就是一个通用的中断处理程序! 这里主要实现在串口输入一个字符,接受后+2再发送到串口,所以在串口输入a 会返回c---. 由于code都有相应的注释,读者自行查看

28.时钟初始化

28.时钟初始化 ARM系统时钟初始化: 这就需要知道什么是时钟脉冲信号,什么是时钟频率,什么是时钟源. 时钟脉冲信号: 时钟脉冲信号:按一定的电压幅度,一定的时间间隔连续发出的脉冲信号.时钟脉冲信号是时序逻辑的基础,它用于决定逻辑单元中的状态何时更新.数字芯片中众多的晶体管都工作在开关状态,它们的导通和关断动作无不是按照时钟信号的节奏进行的 时钟脉冲图解: 1.2时钟脉冲频率: 时钟脉冲频率:就是在单位时间,如1秒,内产生的时钟脉冲个数. 1.3信号产生: 如何产生时钟信号:1.晶振2.锁相环

嵌入式学习笔记104-uboot_1.1.6移植(4)

前面的4篇uboot博文基本概括了uboot的整体flow,现在使能支持启动linux,至此之前请先阅读<嵌入式学习笔记200-Linux kernel初体验>和<嵌入式学习笔记201-Linux kernel动起来>.准备kernel的镜像文件才可以立马检测uboot是否能够启动kernel.在u-boot-1.1.6\include\configs\tq2440.h 最后添加如下几行code: /****************** boot kernel setup ****

8.时钟初始化

ARM系统时钟初始化: ????这就需要知道什么是时钟脉冲信号,什么是时钟频率,什么是时钟源. 时钟脉冲信号: 时钟脉冲信号:按一定的电压幅度,一定的时间间隔连续发出的脉冲信号.时钟脉冲信号是时序逻辑的基础,它用于决定逻辑单元中的状态何时更新.数字芯片中众多的晶体管都工作在开关状态,它们的导通和关断动作无不是按照时钟信号的节奏进行的 时钟脉冲图解: ? ? ? ? ? ????1.2时钟脉冲频率: 时钟脉冲频率:就是在单位时间,如1秒,内产生的时钟脉冲个数. ????1.3信号产生: 如何产生时

[游戏学习28] MFC 时钟

>_<:这是一个时钟小程序 >_<:通过调用获得系统时间然后经过计算得出当前时间,然后再以3个圆环表示时分秒. >_<:TAO_CLOCK.h 1 class CMyApp : public CWinApp 2 { 3 public: 4 virtual BOOL InitInstance (); 5 }; 6 7 class CMainWindow : public CFrameWnd 8 { 9 protected: 10 11 12 int m_nPrevSeco

6410/2440/210时钟初始化笔记

时钟初始化有如下四步骤 1配置locktime(默认模式,一般不用更改) 2配置fclk 3设置异步模式(6410设置others寄存器,210不需要设置) 4设置fclk /////6410/////// #define CLK_DIV0 0x7e00f020            /*地址 #define OTHERS 0x7e00f900            /*地址#define MPLL_CON 0x7e00f010       /*地址#define APLL_CON 0x7e00