• Tiny64140之初始化时钟


    简介:

      Tiny6410 时钟逻辑为整个芯片提供了3种时钟分别为FCLK、HCLK、PCLK有三个PLL 分别为APLL、MPLL、EPLL。
        APLL 专用于CPU
        MPLL 供AHB(存储/中断/LCD等控制器)/APB(看门狗、定时器,SD等)总线上的设备使用
        EPLL 供UART,IIC,IIS使用

    Tiny6410时钟设置参考图

    操作步骤:
    第一步:设置锁定时间
      设置好PLL后,时钟从Fin提升到目标频率时需要一定的时间,这段时间称之为锁定时间一般来说只要设置好[X]PLL_LOCK寄存器的默认值就可以了
    查看数据手册找到对应的[X]PLL_LOCK的寄存器地址


        REGISTER       ADDRSS      RESET VALUE
        APLL_LOCK     0x7E00_F000   0x0000_FFFF
        MPLL_LOCK    0x7E00_F004   0x0000_FFFF
        EPLL_LOCK     0x7E00_F008   0x0000_FFFF
    第二步:设置为异步模式


      Tiny6410硬性规定,用MPLL作为HCLK和PCLK的Source需要设置成异步(ASYNC)模式,若使用APLL则设置为同步(SYNC)模式通过时序电路图可以知道控制同/异步模式的寄存器为OTHERS通过OTHERS寄存器各位的减少可以知道,当OTHERS的bit[7] 为1时表示同步模式,为0时表示异步模式bit[6]位为模式的选择使能。过设置同/异步模式只需要将OTHERS寄存器的地bit[6],bit[7]置1或者置0


    第三步:设置分频系数


      FCLK、HCLK、PCLK三者的比例系数是可以改变的通过数据手册可以知道分频相关的就存器是CLK_DIV0地址是0x7E00_F020通过数据手册中给出的时钟设置参考值来设置CLK_DIV0对应的值(详细值见代码)
    第四步:设置PLL

      由于在第三步设置中将APLL和MPLL的输出(Fout)都设置成了533MHZ 由上图Fout的公式和TargetFout的参考表可MDIV=226,PDIV=3,SDIV=2

    实验现象:led灯跑得更加的快

    代码实现:

    汇编版:

      1 //启动的代码 start.S
      2 .global _start
      3 _start:
      4  //把外设的基地址告诉CPU
      5  ldr r0,=0x70000000
      6  orr r0 ,r0, #0x13
      7  mcr p15,0,r0,c15,c2,4
      8  
      9  //关看门狗
     10  ldr r0, =0x7E004000
     11  mov r1, #0
     12  str r1, [r0]
     13  
     14  //设置堆栈
     15  ldr sp,=0x0c002000
     16  ////cache控制寄存器
     17    ldr r0 =0x72000004
     18  //开启 icaches
     19 #ifdef CONFIG_SYS_ICACHE_OFF
     20     bic r0,r0,#0x00001000
     21 #else
     22     orr r0,r0,#0x00001000
     23 #endif
     24     mcr p15,0,r0,c1,c0,0
     25   //设置时钟
     26   bl clock_init
     27   
     28   //调用C函数点灯
     29   bl main
     30   
     31 halt:
     32     b halt
     33 
     34 ///////////////////////////
     35 //clock.S
     36 //功能:使用汇编初始化时钟
     37 .global clock_init
     38 
     39 clock_init:
     40 //1.设置各PLL的LOCK_TIME,使用默认值
     41 
     42   ldr r0,=0x7E00F000  //APLL_LOCK 供cpu使用
     43   ldr r1,=0x0000FFFF
     44   str r1,[r0]
     45   
     46   str r1,[r0,#4]  //MPLL_CLOCK 供AHB(存储、中断、lcd控制器) APB(看门狗、定时器、SD)总线上的设备使用
     47   str r1,[r0,#8]  //EPLL 供UART、IIC、IIS使用
     48   //2.设置为异步模式
     49   ldr r0,=0x7E00F900
     50   ldr r1,[r0]
     51   bic r1,r1,#0xc0   //bit[6],bit[7]两位清零
     52   str r1,[r0]
     53   
     54 loop:
     55     ldr r0,=0x7E00F900
     56     ldr r1,[r0]
     57     and r1,r1,#0xf00
     58     cmp r1,#0
     59     bne loop
     60   // 3. 设置分频系数  
     61 #define ARM_RATIO    0                           // ARMCLK     = DOUTAPLL / (ARM_RATIO + 1)      = 532/(0+1) = 532  MHz
     62 #define MPLL_RATIO   0                           // DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1)   = 532/(0+1) = 532  MHz
     63 #define HCLKX2_RATIO 1                           // HCLKX2     = HCLKX2IN / (HCLKX2_RATIO + 1) = 532/(1+1) = 266  MHz
     64 #define HCLK_RATIO   1                           // HCLK     = HCLKX2   / (HCLK_RATIO + 1)   = 266/(1+1) = 133  MHz
     65 #define PCLK_RATIO   3                           // PCLK       = HCLKX2   / (PCLK_RATIO + 1)   = 266/(3+1) = 66.5 MHz
     66 
     67     ldr r0, =0x7E00F020                        //CLK_DIV0
     68     ldr r1, =(ARM_RATIO) | (MPLL_RATIO<<4)|(HCLK_RATIO<<8)|(HCLKX2_RATIO<<9)|(PCLK_RATIO<<12)
     69     str r1,[r0]
     70     
     71 //4.设置PLL,放大时钟
     72 //4.1配置APLL
     73 #define APLL_CON_VAL ((1<<31)|(266<<16)|(3<<8)|(1))
     74     ldr r0,=0x7E00F00C      //APLL_CON 
     75     ldr r1, = APLL_CON_VAL      //FOUT = MDIV * FIN /(PDIV * 2SDIV) = 266*12 /(3*2^1) = 532MHZ
     76     str r1,[r0]
     77 //4.2配置MPLL
     78 #define MPLL_CON_VAL ((1<<31)|(266<<16)|(3<<8)|(1))
     79     ldr r0,=0x7E00F010   //MPLL_CON
     80     ldr r1,=MPLL_CON_VAL  //FOUT = MDIV * FIN /(PDIV *2 SDIV) = 266*12 /(3*2^1) = 532MHZ
     81     
     82     str r1,[r0]
     83     
     84 #define MPLL_SEL 1
     85 #define APLL_SEL 1
     86 
     87 //5.选择APLL作为是时钟源
     88     ldr r0,=0x7E00F00C
     89     ldr r1,=(MPLL_SEL<<1) | (APLL_SEL <<0)
     90     str r1,[r0]
     91     
     92     mov pc ,lr
     93     
     94 ////////////////////////////////////
     95 //Tiny6410Addr.h
     96 #ifndef _Tiny6410Addr_H
     97 #define _Tiny6410Addr_H
     98 //GPK 
     99 #define GPKIO_BASE (0x7F008800)
    100 #define rGPKCON0 (*(volatile unsigned*)(GPKIO_BASE+0x00))
    101 #define rGPKDAT  (*(volatile unsigned*)(GPKIO_BASE+0x08))
    102 
    103 #endif
    104 
    105 //////////////////////
    106 //test.c
    107 #include "Tiny6410Addr.h"
    108 #define GPK4_OUT  (1<<4*4)
    109 #define GPK5_OUT  (1<<4*5)
    110 #define GPK6_OUT  (1<<4*6)
    111 #define GPK7_OUT  (1<<4*7)
    112 //延时函数
    113 void delay()
    114 {
    115    volatile int i = 0x10000;
    116    while (i--);
    117 }
    118 
    119 int main()
    120 {
    121     unsigned int i = 0;
    122     //将GPK4-7设置为输出
    123     rGPKCON0 = GPK4_OUT | GPK5_OUT |GPK6_OUT |GPK7_OUT;
    124     //跑马灯式
    125     while (1)
    126     {
    127         rGPKDAT = i;
    128         i++;
    129         if(i == 16)
    130             i=0;
    131         delay();
    132     }
    133     
    134     return 0;
    135     }
    汇编 Code

    C语言版:

      1 //启动的代码
      2 .global _start
      3 _start:
      4  //把外设的基地址告诉CPU
      5  ldr r0,=0x70000000
      6  orr r0 ,r0, #0x13
      7  mcr p15,0,r0,c15,c2,4
      8  
      9  //关看门狗
     10  ldr r0, =0x7E004000
     11  mov r1, #0
     12  str r1, [r0]
     13  
     14  //设置堆栈
     15  ldr sp,=0x0c002000
     16   ////cache控制寄存器
     17    ldr r0 =0x72000004
     18  //开启 icaches
     19 #ifdef CONFIG_SYS_ICACHE_OFF
     20     bic r0,r0,#0x00001000
     21 #else
     22     orr r0,r0,#0x00001000
     23 #endif
     24     mcr p15,0,r0,c1,c0,0
     25   //设置时钟
     26   bl clock_init
     27   
     28   //调用C函数点灯
     29   bl main
     30   
     31 halt:
     32     b halt
     33 
     34 //////////////////////////    
     35 //Tiny6410Addr.h
     36 #ifndef _Tiny6410Addr_H
     37 #define _Tiny6410Addr_H
     38 //GPK 
     39 #define GPKIO_BASE (0x7F008800)
     40 #define rGPKCON0 (*((volatile unsigned long*)(GPKIO_BASE+0x00)))
     41 #define rGPKDAT  (*((volatile unsigned long*)(GPKIO_BASE+0x08)))
     42 
     43 //CLOCK
     44 #define APLL_LOCK (*((volatile unsigned long*)0x7E00F000))
     45 #define MPLL_LOCK (*((volatile unsigned lomg*)0x7E00F004))
     46 #define EPLL_LOCK (*((volatile unsigned long*)0x7E00F008))
     47 #define OTHER     (*((volatile unsigned long*)0x7E00F900))
     48 #define CLK_DIV0  (*((volatile unsigned long*)0x7E00F020))
     49 #define APLL_CON  (*((volatile unsigned long*)0x7E00F00C))
     50 #define MPLL_CON  (*((volatile unsigned long*)0x7F00F010))
     51 #define CLK_SRC   (*((volatile unsigned long*)0x7E00F01C))
     52 
     53 
     54 #endif
     55 
     56 /////////////////////////////////////////////
     57 //clock.c
     58 #include"Tiny6410Addr.h"
     59 
     60 #define ARM_RATIO    0                           // ARMCLK     = DOUTAPLL / (ARM_RATIO + 1)      = 532/(0+1) = 532 MHz
     61 #define MPLL_RATIO   0                           // DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1)   = 532/(0+1) = 532  MHz
     62 #define HCLKX2_RATIO 1                           // HCLKX2     = HCLKX2IN / (HCLKX2_RATIO + 1) = 532/(1+1) = 266  MHz
     63 #define HCLK_RATIO   1                           // HCLK     = HCLKX2   / (HCLK_RATIO + 1)   = 266/(1+1) = 133  MHz
     64 #define PCLK_RATIO   3                           // PCLK       = HCLKX2   / (PCLK_RATIO + 1)   = 266/(3+1) = 66.5 MHz
     65 
     66 #define APLL_CON_VAL ((1<<31)|(226<<16)|(3<<8)|(1))
     67 #define MPLL_CON_VAL ((1<<31)|(226<<16)|(3<<8)|(1))
     68 
     69 viod clock_init(void)
     70 {
     71     //设置各PLL的默认值 即锁定时间
     72     APLL_LOCK = 0xFFFF;
     73     MPLL_LOCK = 0xFFFF;
     74     EPLL_LOCK = 0xFFFF;
     75     
     76     //设置为异步模式
     77     OTHER &= ~0xc0;
     78     while((OTHER & 0xF00) !=0);
     79     
     80     //设置分屏系数
     81     CLK_DIV0 = (ARM_RATIO)|(MPLL_RATIO<<4)|(HCLK_RATIO<<8)|(HCLKX2_RATIO<<9)|(PCLK_RATIO<<12);
     82     
     83     //设置PLL,放大系数
     84     APLL_CON = APLL_CON_VAL;
     85     MPLL_CON = MPLL_CON_VAL;
     86     
     87     //选择PLL的输出作为时钟源
     88     CLK_SRC= 0x03;
     89 }
     90 
     91 ////////////////////////////////////////
     92 //Makefile
     93 clock.bin : start.o clock.o main.o
     94     arm-linux-ld -Ttext 0x50000000 -o clock.elf start.o clock.o main.o
     95     arm-linux-objcopy -O binary clock.elf clock.bin
     96     arm-linux-objdump -D clock.elf > clock.dis
     97     
     98 %.o : %.S
     99     arm-linux-gcc -o $@ $< -c
    100     
    101 %.o : %.c
    102     arm-linux-gcc -o $@ $< -c
    103     
    104 clean:
    105     rm *.o *.elf *.bin *.dis
    C Code
    海阔凭鱼跃,天高任鸟飞。
  • 相关阅读:
    枚举类型
    [ Java学习 ] “goto语句“ 和 “continue + 标号” 的不同待遇
    [ Java学习 ] 其他知识总结(重要)
    [ Java学习 ] Java变量以及内存分配(非常重要)
    [ Java学习 ] 包语句 package等语句的汇总整理
    [ Java学习 ] 破除思维定势之 C++ 和 Java 的差异 003
    P1601一道高精度的题
    啊哈,我又来了
    算了,有一道水题
    再水一道题
  • 原文地址:https://www.cnblogs.com/chenshikun/p/5814567.html
Copyright © 2020-2023  润新知