tiny6410裸机实验第3章--------------系统时钟(代码分析)

【说明】

               前面原理已经很清楚了,现在分析代码,放在2个博文中是方便大家同时打开2个博文,原理图和代码对应看

【源代码】

             工程文件如下,其中clock.S 用来初始化时钟,main.c 测试用的,依旧是LED灯,start.S 是程序最前面那一段

            

           

          1】  main.c

            

// 功能:流水灯

 
void delay()
{
        volatile int i = 0x10000;
        while (i--);
}

int main()
{
        int i = 0;

        volatile unsigned long *gpkcon0 = (volatile unsigned long *)0x7F008800;
        volatile unsigned long *gpkdat = (volatile unsigned long *)0x7F008808;

        *gpkcon0 = (*gpkcon0 & ~(0xffff<<16)) | (0x1111<<16);

        while (1)
        {
                *gpkdat = (*gpkdat & ~(0xf<<4)) | (i<<4);
                i++;
                if (i == 16)
                        i = 0;
                delay(0x10000);
        }

        return 0;
}


 

            2】 clock.S

            

// 功能:汇编初始化时钟
.global clock_init

clock_init:
        // 1. 设置各PLL的LOCK_TIME,使用默认值  
        ldr r0, =0x7E00F000                                             // APLL_LOCK,供cpu使用 
        ldr r1, =0x0000FFFF
        str r1, [r0]

        str r1, [r0, #4]                                                        // MPLL_LOCK,供AHB(存储/中断/lcd等控制器)/APB(看门狗,定时器,SD等)总线上的设备使用 
        str r1, [r0, #8]                                                        // EPLL_LOCK,供UART,IIS,IIC使用 

        // 2. 设置为异步模式(Asynchronous mode)  
        ldr r0, =0x7E00F900                                                     // OTHERS
                                                                                       // 《linux installation for u-boot》3.7中:用MPLL作为HCLK和PCLK的Source是异步(ASYNC)模式
                                                                                       // 用APLL是同步(SYNC)模式
        ldr r1, [r0]
        bic r1, r1, #0xc0                                                       // bit[6:7]清0,即SYNCMODE=0/SYNCMUXSEL=0
        str r1, [r0]
loop:
        ldr r0, =0x7E00F900
        ldr r1, [r0]
        and r1, r1, #0xf00
        cmp r1, #0
        bne loop

        // 3. 设置分频系数  
#define ARM_RATIO    0                                                  // ARMCLK      = DOUTAPLL / (ARM_RATIO + 1)     = 532/(0+1) = 532  MHz
#define MPLL_RATIO   0                                                  // DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1)   = 532/(0+1) = 532  MHz
#define HCLKX2_RATIO 1                                                  // HCLKX2      = HCLKX2IN / (HCLKX2_RATIO + 1) = 532/(1+1) = 266  MHz
#define HCLK_RATIO   1                                                  // HCLK        = HCLKX2   / (HCLK_RATIO + 1)   = 266/(1+1) = 133  MHz
#define PCLK_RATIO   3                                                  // PCLK        = HCLKX2   / (PCLK_RATIO + 1)   = 266/(3+1) = 66.5 MHz

        ldr r0, =0x7E00F020                                             // CLK_DIV0
        ldr r1, =(ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_RATIO << 12)
        str r1, [r0]

        // 4. 设置PLL,放大时钟  
        // 4.1 配置APLL  
#define APLL_CON_VAL  ((1<<31) | (266 << 16) | (3 << 8) | (1))
        ldr r0, =0x7E00F00C                                                     // APLL_CON
        ldr r1, =APLL_CON_VAL                                           // FOUT = MDIV X FIN / (PDIV X 2SDIV) = 266*12/(3*2^1) = 532MHz
        str r1, [r0]

        // 4.2 配置MPLL  
#define MPLL_CON_VAL  ((1<<31) | (266 << 16) | (3 << 8) | (1))
        ldr r0, =0x7E00F010                                                     // MPLL_CON
        ldr r1, =MPLL_CON_VAL                                           // FOUT = MDIV X FIN / (PDIV X 2SDIV) = 266*12/(3*2^1) = 532MHz
        str r1, [r0]

#define MPLL_SEL 1
#define APLL_SEL 1
        // 5.选择PLL的输出作为时钟源  
        ldr r0, =0x7E00F01C                                                     // CLK_SRC
        ldr r1, =(MPLL_SEL<<1) | (APLL_SEL<<0)
        str r1, [r0]

        mov pc, lr


 

                3】  start.S

                  

// 启动代码
.global _start

_start:

        // 把外设的基地址告诉CPU
        ldr r0, =0x70000000 
        orr r0, r0, #0x13
        mcr p15,0,r0,c15,c2,4

        // 关看门狗
        ldr r0, =0x7E004000
        mov r1, #0
        str r1, [r0] 

        // 设置栈
        ldr sp, =0x0C002000

        // 开启icaches
#ifdef  CONFIG_SYS_ICACHE_OFF
        bic r0, r0, #0x00001000                                 @ clear bit 12 (I) I-cache
#else
        orr r0, r0, #0x00001000                                 @ set bit 12 (I) I-cache
#endif
        mcr p15, 0, r0, c1, c0, 0

        // 设置时钟
        bl clock_init

        // 调用C函数点灯
        bl main

halt:
        b halt


 

            4】   Makefile

               

clock.bin: start.o clock.o main.o
        arm-linux-ld -Ttext 0 -o clock.elf start.o clock.o main.o
        arm-linux-objcopy -O binary clock.elf clock.bin
        arm-linux-objdump -D clock.elf > clock.dis

%.o : %.S
        arm-linux-gcc -o $@ $< -c

%.o : %.c
        arm-linux-gcc -o $@ $< -c

clean:
        rm *.o *.elf *.bin *.dis


 【烧写】

                同LED

 

【实验现象】

                  LED闪得非常快,因为CPU时钟现在比以前快多了

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值