一、系统时钟结构分析
- OM[3]、OM[2] 外部引脚接地使用晶振作为 MPLLin
- MPLLCON 控制 MPLL 输出时钟的 P /M/ S 三个参数, 直接决定了 FCLK
- MPLL 的计算公式
- CLKDIVN 寄存器控制从 FCLK 生成 HCLK 和 PCLK 的分频
二、代码编写
实验目的
时钟 FCLK=400M、HCLK=100M、PCLK=50M
CLKDIVN[2:1]=2’b10
CLKDIVN[0]=1’b1
CLKDIVN 设置为 0x05
MPLLCON 设置参考以下官方表格,MPLLCON[19:12]=92,MPLLCON[9:4]=1,MPLLCON[1:0]=1(92 << 12) | (1 << 4) | (1<<0)
cpu 需要设置为异步模式
- 注意汇编文件要要大写 S 格式
- 把汇编中时钟初始化部分屏蔽 led 闪烁频率会有明显区别
start.S
.text
.global _start
_start:
//**** 关闭看门狗 ****
ldr r0, =0x53000000
mov r1, #0
str r1, [r0]
//**** 设置 MPLL 时钟 ****
// 设置 LOCKTIME
ldr r0, =0x4C000000
ldr r1, =0xFFFFFFFF
str r1, [r0]
// 设置 CLKDIVN
ldr r0, =0x4C000014
ldr r1, =0x5
str r1, [r0]
// 设置 CPU 异步模式
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000 //R1_nF:OR:R1_iA
mcr p15,0,r0,c1,c0,0
// 设置 MPLLCON
ldr r0, =0x4C000004
ldr r1, =(92 << 12) | (1 << 4) | (1<<0)
str r1, [r0]
//**** 设置栈 ****
ldr sp, =4096 //nand 启动 设置在 4k 顶部
//ldr sp, =0x4000000 + 4096 //nor 启动
//**** 调用 main****
bl main
halt:
b halt
Makefile
objs = start.o led.o
dep_files := $(patsubst %, .%.d, $(objs))
dep_files := $(wildcard $(dep_files))
CFLAGS = -Iinclude
led.bin : $(objs)
arm-linux-ld -Ttext 0x00000000 $^ -o led_elf
arm-linux-objcopy -O binary -S led_elf $@
ifneq ($(dep_files),)
include $(dep_files)
endif
%.o : %.c
arm-linux-gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d
%.o : %.S
arm-linux-gcc -c -o $@ $^
clean:
rm *.o led_elf led.bin $(dep_files)
distclean:
rm $(dep_files)
.PHONY: clean
C 文件
#define GPBCON (*(volatile unsigned int *)0x56000010)
#define GPBDAT (*(volatile unsigned int *)0x56000014)
void delay(int tt);
int main(){
GPBCON = 0x00015400;
GPBDAT = 0x00000000;
GPBDAT |= (1<<5) | (1<<6) | (1<<7) | (1<<8);
while(1){GPBDAT &= ~(1<<6);
delay(10000);
GPBDAT |= (1<<6);
delay(10000);
}
}
void delay(int tt){
int a,b;
for(a=0;a<=tt;a++)
for(b=0;b<=100;b++);
}