Tiny64140之初始化时钟
Posted 凌潇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
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
以上是关于Tiny64140之初始化时钟的主要内容,如果未能解决你的问题,请参考以下文章
X-007 FriendlyARM tiny4412 u-boot移植之内存初始化
C++卷积神经网络实例:tiny_cnn代码详解——convolutional_layer类结构信息之成员变量与构造函数