Tiny6410 时钟驱动笔记

来源:互联网 发布:平安普惠绑定网络账号 编辑:程序博客网 时间:2024/05/22 23:38

1. S3C6410内部有三种时钟信号:ARMCLK, HCLK, PCLK. 其中ARMCLK用于CPU, HCKL用于AXI/AHB总线上的设备,PCLK用于APB总线上的设备。

2. S3C6410内部有三个PLL电路,一个只用于产生ARMCLK, 第二个用于产生HCLK和PCLK,还有一个用于特殊的外设,尤其是音频相关的时钟。

  硬件结构如下图所示(从这个图可以知道哪些设备挂在哪条总线上,这样设置时钟时就有方向了。):


3. 关于时钟的选择

   PLL需要外部时钟作为参考, S3C6410可以选择用外部晶振还是外部时钟作输入。这是由OM[4:0]决定的,更准确的说是由OM[0]决定:当OM[0]为0时使用外部晶振,为1时使用外部时钟。


Tiny6410将OM0接地(注意电阻NC),即OM[0]=0, 所以使用的是外部晶振。

4. 时钟架构


        CLK_SRC寄存器的低三位CLK_SRC[2:0]分别控制三种工作时钟。当对应位被置位,则产生对应PLL的工作时钟。否则,不会产生对应的PLL工作时钟。

5. 时钟初始化

    时钟初始化涉及的寄存器还比较多,初看起来有点头晕的感觉,但这主要为了对时钟信号的产生提供更多的控制。对于一个典型的时钟需求,如ARMCLK=533MHz, HCLKx2=266MHz, HCLK=133MHz, PCLK=66MHz,只要按时钟架构图计算出各部件的取值,设置一下就好了。下面以此为线索,说明时钟初始化的步骤。


上图标明了时钟信号的产生路径,只要我们沿着路径把一个个寄存器设置好了,理论上时钟就会按我们的设想的频率运行。

要设置APLL产生533MHz频率, PLL的设置有一个公式: Fout = MDIV * Fin / (PDIV * 2^SDIV)

晶振输入频率 Fin=12MHz 是已知了的,所以这里就是选择适当的MDIV, PDIV, SDIV的值,使得Fout=533MHz.在S3C6410的手册上可以查得:MDIV=266, PDIV=3, SDIV=1. 简单验证一下可知这组值的确可使Fout=533MHz. 剩下的工作就是查S3C6410手册确定涉及寄存器的地址及做相应的操作就可以了。

6. 示例程序

.text.code 32.globl _start.equ  ELFIN_CLOCK_POWER_BASE, 0x7e00f000  .equ  OTHERS_OFFSET, 0×900.equ  APLL_LOCK_OFFSET, 0×00.equ  MPLL_LOCK_OFFSET, 0×04.equ  EPLL_LOCK_OFFSET, 0×08.equ  CLK_DIV0_OFFSET, 0×20.equ  APLL_CON_OFFSET, 0x0C.equ  CLK_SRC_OFFSET,  0x1C.equ GPKCON0, 0x7F008800.equ GPKDAT, 0x7F008808.equ GPKPUD, 0x7F00880C_start:@关闭看门狗ldr r0, =0x7e000000orr r0, r0, #0×4000mov r1, #0str r1, [r0]ldr r0, =ELFIN_CLOCK_POWER_BASE@让APLL为AHB, APB输出工作频率:OTHERS[6]=SYNCMUXSEL=1ldr r1, [r0, #OTHERS_OFFSET]mov r2, #0×40 orr r1, r1, r2str r1, [r0, #OTHERS_OFFSET]nopnopnopnopnop@同步工作模式:OTHERS[7]=SYNCMODE=1ldr r2, =0×80 orr r1, r1, r2str r1, [r0, #OTHERS_OFFSET]@测试是否已经工作在同步模式下:OTHERS[11:8]=SYNACK=1111check_syncack:ldr r1, [r0, #OTHERS_OFFSET]ldr r2, =0xf00and r1, r1, r2cmp r1, #0xf00bne check_syncack@当系统时钟修改之后要经过段LOCK时间mov r1, #0xff00 @设置变频锁定时间orr r1, r1, #0xffstr r1, [r0, #APLL_LOCK_OFFSET]str r1, [r0, #MPLL_LOCK_OFFSET]str r1, [r0, #EPLL_LOCK_OFFSET]@设置ARMCLK(533M), HCLKX2(266M), HCLK(133M), PCLK(66M)的分频ldr r1, [r0, #CLK_DIV0_OFFSET]bic r1, r1, #0×30000bic r1, r1, #0xff00bic r1, r1, #0xffldr r2, =((3<<12)|(1<<9)|(1<<8)|(1<<4)|0)orr r1, r1, r2str r1, [r0, #CLK_DIV0_OFFSET]@设置APLL锁相环(533M)ldr r1, =(1<<31 | 266<<16 | 3<<8 | 1)str r1, [r0, #APLL_CON_OFFSET]@设置对应时钟源寄存器,为各种外设提供时钟频率ldr r2, =0×1 @APLL_SEL=0ldr r1, [r0, #CLK_SRC_OFFSET]orr r1, r1, r2str r1, [r0, #CLK_SRC_OFFSET]@延时mov r1, #0×100001:subs r1, r1, #1bne 1bled_loop:    ldr r0,=GPKCON0    ldr r1,=0×11111111    str r1,[r0]    ldr r0,=GPKDAT    ldr r2,=0xffcf    str r2,[r0]        bl delay    ldr r0,=GPKDAT    ldr r2,=0xffff    str r2,[r0]    bl delay    b led_looploop:    b loopdelay:    ldr r1, =0×10000001:    subs r1, r1, #1    bne 1b    mov pc,lr