乐趣区

韦东山一期视频学习笔记系统时钟

一、系统时钟结构分析

  • 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++);
}
退出移动版