欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2440的时钟初始化

程序员文章站 2022-03-13 17:24:36
...

一、时钟概览

2440的时钟初始化

下面图很好地总结了上面的图

2440的时钟初始化

时钟源:为了减少外界环境对开发板电磁干扰,降低制作成本,通常开发板的外部晶振时钟频率都很低,2440开发板由12MHz的晶振来提供时钟源,要想让CPU运行在更高的频率就要通过时钟控制逻辑单元PLL(锁相环)来提高主频。

S3C2440里有两个PLL:MPLL和UPLL,MPLL用来产生FCLK,HCLK,PCLK的高频工作时钟,UPLL用来为USB提供工作频率。

其中FCLK主要为ARM920T内核提供工作频率

HCLK主要为S3C2440 AHB总线(Advanced High performance Bus)上挂接硬件提供工作频率,AHB总线主要挂接有内存,NAND,LCD控制器等硬件

PCLK主要为APB总线提供工作频率,由图2-46所示,APB总线主要挂接UART串口,Watchdog等硬件控制器。

二、寄存器设置

1.设置时钟源

2440的时钟初始化

在硬件上,已经将这两个管脚接地,即选择晶振输入,开启两个PLL

2.LockTime PLL锁定时间由LOCKTIME寄存器设置

不做详细赘述,直接使用默认值即可

3.设置分频系数

CLKDIVN  = 0x05;            // FCLK:HCLK:PCLK=1:4:8

2440的时钟初始化

4.设置MPLL得到400MHZ的频率

 * 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV

 * 有如下计算公式:

 *  S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)

 *  其中: m = MDIV + 8, p = PDIV + 2, s = SDIV

 * 对于本开发板,Fin = 12MHz

2440的时钟初始化

#define S3C2440_MPLL_400MHZ     ((92<<12)|(1<<4)|(1<<0))

MPLLCON = S3C2440_MPLL_400MHZ;  

5、其他

 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode”

三、实验代码

1.Makefile

all:
	arm-linux-gcc -c -o start.o start.S
	arm-linux-gcc -c -o led.o led.c
	arm-linux-gcc -c -o init.o init.c
	arm-linux-ld -Ttext 0 start.o led.o init.o -o led_on.elf
	arm-linux-objcopy -O binary -S led_on.elf led_on.bin
clean:
	rm *.bin *.o *.elf 

2.start.S

.global _start
_start:
		
	//关闭看门狗
	ldr r0, =0  
	ldr r1, =0x53000000			
	str r0, [r1]
	
	ldr sp, =4096	
	
	bl clock_init
	
	bl led_blink
	
	b .

3.init.c

/*
 * init.c: 进行一些初始化
 */ 

#include "s3c24xx.h"
void clock_init(void);

#define S3C2440_MPLL_400MHZ     ((92<<12)|(1<<4)|(1<<0))
/*
 * 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV
 * 有如下计算公式:
 *  S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)
 *  其中: m = MDIV + 8, p = PDIV + 2, s = SDIV
 * 对于本开发板,Fin = 12MHz
 * 设置CLKDIVN,令分频比为:FCLK:HCLK:PCLK=1:4:8,
 * FCLK=400MHz,HCLK=100MHz,PCLK=50MHz
 */
void clock_init(void)
{
    LOCKTIME = 0xFFFFFFFF;   // 使用默认值即可
    CLKDIVN  = 0x05;            // FCLK:HCLK:PCLK=1:4:8

    /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
__asm__(
    "mrc    p15, 0, r1, c1, c0, 0\n"        /* 读出控制寄存器 */ 
    "orr    r1, r1, #0xc0000000\n"          /* 设置为“asynchronous bus mode” */ //R1_nF:OR:R1_iA
    "mcr    p15, 0, r1, c1, c0, 0\n"        /* 写入控制寄存器 */
    );

    MPLLCON = S3C2440_MPLL_400MHZ;  /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */      
}

4.led.c

#define GPFCON	0x56000050
#define GPFDAT	0x56000054

void delay(void);

// 该函数要实现led闪烁效果
void led_blink(void)
{
	// led初始化
	unsigned int *p = (unsigned int *)GPFCON;
	unsigned int *p1 = (unsigned int *)GPFDAT;
	*p = 0x1500;
	
	while (1)
	{
		// led亮
		*p1 = ((0<<4) | (0<<5) | (0<<6));
		// 延时
		delay();
		// led灭
		*p1 = ((1<<4) | (1<<5) | (1<<6));
		// 延时
		delay();
	}
}

void delay(void)
{
	unsigned int i = 200000;		
	while (i--);				
}

5.s3c24xx.h

/* WOTCH DOG register */
#define     WTCON           (*(volatile unsigned long *)0x53000000)

/* SDRAM regisers */
#define     MEM_CTL_BASE    0x48000000
#define     SDRAM_BASE      0x30000000

/* NAND Flash registers */
#define NFCONF              (*(volatile unsigned int  *)0x4e000000)
#define NFCMD               (*(volatile unsigned char *)0x4e000004)
#define NFADDR              (*(volatile unsigned char *)0x4e000008)
#define NFDATA              (*(volatile unsigned char *)0x4e00000c)
#define NFSTAT              (*(volatile unsigned char *)0x4e000010)

/*GPIO registers*/
#define GPBCON              (*(volatile unsigned long *)0x56000010)
#define GPBDAT              (*(volatile unsigned long *)0x56000014)

#define GPFCON              (*(volatile unsigned long *)0x56000050)
#define GPFDAT              (*(volatile unsigned long *)0x56000054)
#define GPFUP               (*(volatile unsigned long *)0x56000058)

#define GPGCON              (*(volatile unsigned long *)0x56000060)
#define GPGDAT              (*(volatile unsigned long *)0x56000064)
#define GPGUP               (*(volatile unsigned long *)0x56000068)

#define GPHCON              (*(volatile unsigned long *)0x56000070)
#define GPHDAT              (*(volatile unsigned long *)0x56000074)
#define GPHUP               (*(volatile unsigned long *)0x56000078)



/*UART registers*/
#define ULCON0              (*(volatile unsigned long *)0x50000000)
#define UCON0               (*(volatile unsigned long *)0x50000004)
#define UFCON0              (*(volatile unsigned long *)0x50000008)
#define UMCON0              (*(volatile unsigned long *)0x5000000c)
#define UTRSTAT0            (*(volatile unsigned long *)0x50000010)
#define UTXH0               (*(volatile unsigned char *)0x50000020)
#define URXH0               (*(volatile unsigned char *)0x50000024)
#define UBRDIV0             (*(volatile unsigned long *)0x50000028)


/*interrupt registes*/
#define SRCPND              (*(volatile unsigned long *)0x4A000000)
#define INTMOD              (*(volatile unsigned long *)0x4A000004)
#define INTMSK              (*(volatile unsigned long *)0x4A000008)
#define PRIORITY            (*(volatile unsigned long *)0x4A00000c)
#define INTPND              (*(volatile unsigned long *)0x4A000010)
#define INTOFFSET           (*(volatile unsigned long *)0x4A000014)
#define SUBSRCPND           (*(volatile unsigned long *)0x4A000018)
#define INTSUBMSK           (*(volatile unsigned long *)0x4A00001c)

/*external interrupt registers*/
#define EINTMASK            (*(volatile unsigned long *)0x560000a4)
#define EINTPEND            (*(volatile unsigned long *)0x560000a8)

/*clock registers*/
#define	LOCKTIME		(*(volatile unsigned long *)0x4c000000)
#define	MPLLCON		(*(volatile unsigned long *)0x4c000004)
#define	UPLLCON		(*(volatile unsigned long *)0x4c000008)
#define	CLKCON		(*(volatile unsigned long *)0x4c00000c)
#define	CLKSLOW		(*(volatile unsigned long *)0x4c000010)
#define	CLKDIVN		(*(volatile unsigned long *)0x4c000014)


/*PWM & Timer registers*/
#define	TCFG0		(*(volatile unsigned long *)0x51000000)
#define	TCFG1		(*(volatile unsigned long *)0x51000004)
#define	TCON		(*(volatile unsigned long *)0x51000008)
#define	TCNTB0		(*(volatile unsigned long *)0x5100000c)
#define	TCMPB0		(*(volatile unsigned long *)0x51000010)
#define	TCNTO0		(*(volatile unsigned long *)0x51000014)

#define GSTATUS1    (*(volatile unsigned long *)0x560000B0)

结果分析:

将bin文件烧写进开发板,可以看到LED的闪烁速度比没有进行时钟初始化的时候快了好多。


参考链接:

https://blog.csdn.net/mr_raptor/article/details/6555734

http://wiki.100ask.org/%E7%AC%AC010%E8%AF%BE_%E6%8E%8C%E6%8F%A1ARM%E8%8A%AF%E7%89%87%E6%97%B6%E9%92%9F%E4%BD%93%E7%B3%BB

韦老师代码

相关标签: ARM