系统时钟 裸板

来源:互联网 发布:查找词语的软件 编辑:程序博客网 时间:2024/06/08 17:38

1、板子上我们的晶振提供的时钟只有12M,但6410号称可以跑5、6百兆,这是怎么回事呢?

显然,从晶振出来的12M时钟 到给CPU提供的时钟中间经过了某个部件的处理。这个部件就叫做PLL。它将12M的时钟提高到五、六百兆,再供给CPU。
我们今天就来设置这个PLL,让它实现这样的功能。

2、怎么设置这个PLL呢?

查看6410手册S3C6410X.pdf,

3、还是从代码来分析吧

1)以下是启动代码 :start.S

.globl _start_start:/* 硬件相关的设置 : 把外设的基地址告诉CPU*/    /* Peri port setup */    ldr r0, =0x70000000    orr r0, r0, #0x13    mcr p15,0,r0,c15,c2,4       @ 256M(0x70000000-0x7fffffff)    /* 关看门狗 *//* 往WTCON(0x7E004000)写0 */ldr r0, =0x7E004000mov r1, #0str r1, [r0]/*设置时钟 */bl clock_init/* 设置栈, 调用C函数 */ldr sp, =8*1024bl mainhalt:b halt
2)下面是点led的测试程序:led.c

void delay(){volatile int i = 0x10000;while (i--);}int main(){int i = 0;volatile unsigned long *gpmcon = (volatile unsigned long *)0x7F008820;volatile unsigned long *gpmdat = (volatile unsigned long *)0x7F008824;/* gpm0,1,2,3设为输出引脚 */*gpmcon = 0x1111;while (1){*gpmdat = i;i++;if (i == 16)i = 0;delay();}return 0;}
3)以下是时钟设置的代码:clock.S
.globl clock_initclock_init:/* 1.设置LOCK_TIME */ldr r0, =0x7E00F000  /* APLL_LOCK */ldr r1, =0x0000FFFFstr r1, [r0]str r1, [r0, #4] /* MPLL_LOCK */str r1, [r0, #8] /* EPLL_LOCK */#define OTHERS0x7e00f900@ set async mode  /* 当CPU时钟 != HCLK时,要设为异步模式 */ldr r0, =OTHERSldr r1, [r0]bic r1, r1, #0xc0/* 1100,0000 */str r1, [r0]loop1:/* 等待,直到CPU进入异步模式 */ldr r0, =OTHERSldr r1, [r0]and r1, r1, #0xf00cmp r1, #0bne loop1/* SYNC667 *//* MISC_CON[19] = 0 */#define ARM_RATIO    0   /* ARMCLK = DOUTAPLL / (ARM_RATIO + 1)    */#define HCLKX2_RATIO 1   /* HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) */#define HCLK_RATIO   1   /* HCLK = HCLKX2 / (HCLK_RATIO + 1)       */#define PCLK_RATIO   3   /* PCLK   = HCLKX2 / (PCLK_RATIO + 1)     */#define MPLL_RATIO   0   /* DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1)     */ldr r0, =0x7E00F020  /* CLK_DIV0 */ldr r1, =(ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_RATIO << 12)str r1, [r0]/* 2.配置时钟 *//* 2.1 配置APLL *//* 2.1.1 设置APLL * 2.1.2 MUXAPLL * 2.1.3 SYNC667 * 2.1.4 DIVAPLL */#define APLL_CON_VAL  ((1<<31) | (266 << 16) | (3 << 8) | (1))ldr r0, =0x7E00F00Cldr r1, =APLL_CON_VALstr r1, [r0]/* APLL_CON, FOUTAPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz  *//* 2.2 配置MPLL *//* 2.2.1 设置MPLL * 2.2.2 MUXMPLL * 2.2.3 SYNCMUX * 2.2.4 SYNC667 * 2.2.5 HCLKX2_RATIO * 2.2.6 PCLK_RATIO */#define MPLL_CON_VAL  ((1<<31) | (266 << 16) | (3 << 8) | (1))ldr r0, =0x7E00F010ldr r1, =MPLL_CON_VALstr r1, [r0]/* MPLL_CON, FOUTMPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz  *//* 3.选择PLL的输出作为时钟源 */ldr r0, =0x7E00F01Cldr r1, =0x03str r1, [r0]mov pc, lr
1> 我们要把12M时钟提高到5 6百兆,不可能瞬间完成,需要一个时间差,这个时间差就是LOCK_TIME.            以下是时序图:

LOCK_TIME 就是锁定时间,在这段时间PLL就开始工作,把时钟提高。

2>  APP  MPLL EPLL

这里有3个PLL,分别是给不同的控件提供时钟的,APLL是给CPU用的,MPLL是给HCLK( 一般是我们的内存,DDR ),PCLK(片上外设),EPLL给其它设备用的。

上面是汇编的,以下是其时钟设置C版,功能都一样:

#define APLL_LOCK (*((volatile unsigned long *)0x7E00F000))#define MPLL_LOCK (*((volatile unsigned long *)0x7E00F004))#define EPLL_LOCK (*((volatile unsigned long *)0x7E00F008))#define OTHERS    (*((volatile unsigned long *)0x7e00f900))#define CLK_DIV0  (*((volatile unsigned long *)0x7E00F020))#define ARM_RATIO    0   /* ARMCLK = DOUTAPLL / (ARM_RATIO + 1)    */#define HCLKX2_RATIO 4   /* HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) = 100MHz */#define HCLK_RATIO   0   /* HCLK = HCLKX2 / (HCLK_RATIO + 1)   = 100MHz       */#define PCLK_RATIO   1   /* PCLK   = HCLKX2 / (PCLK_RATIO + 1) = 50MHz    */#define MPLL_RATIO   0   /* DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1)     */#define APLL_CON  (*((volatile unsigned long *)0x7E00F00C))#define APLL_CON_VAL  ((1<<31) | (250 << 16) | (3 << 8) | (1))#define MPLL_CON  (*((volatile unsigned long *)0x7E00F010))#define MPLL_CON_VAL  ((1<<31) | (250 << 16) | (3 << 8) | (1))#define CLK_SRC  (*((volatile unsigned long *)0x7E00F01C))void clock_init(void){APLL_LOCK = 0xffff;MPLL_LOCK = 0xffff;EPLL_LOCK = 0xffff;/* set async mode 当CPU时钟 != HCLK时,要设为异步模式 */OTHERS &= ~0xc0;while ((OTHERS & 0xf00) != 0);CLK_DIV0 = (ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_RATIO << 12);APLL_CON = APLL_CON_VAL;  /* 500MHz */MPLL_CON = MPLL_CON_VAL;  /* 500MHz */CLK_SRC = 0x03;}

0 0
原创粉丝点击