×
单片机 > 单片机程序设计 > 详情

s3c2440硬件篇之六:系统时钟和定时器

发布时间:2020-05-16 发布时间:
|

S3C2440有三种时钟:FCLK(用于CPU核),HCLK(用于主机模块),PCLK(用于外设).两种PLL(锁相环):MPLL(用于设置FCLK,HCLK,PCLK),UPLL(用于设置USB设备),.

S3C2440的CPU核工作电压为1.2V时,主频FCLK可以达到300M,CPU核工作电压为1.3V时,主频FCLK可以达到400M.为了降低电磁干扰,降低板间的布线要求,s3c2410/s3c2440外接的晶振通常很小,一般为12M,那么如何达到主频FCLK的400M的呢?------PLL倍频。

 

一.设置主频FCLK主要是通过MPLL来软件实现倍频。MPLL主要由3个值MDIV,PDIV,SDIV来决定。而这3个值是由MPLLCON寄存器决定的,MPLLCON的第12位到第19位的值为MDIV,如下所示。

 

 * 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV
 * 有如下计算公式:
 * S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
 * S3C2410: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)
 * 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV
 * 对于本开发板,Fin = 12MHz


二.设置好了MPLLCON寄存器也就基本上算是设置好了FCLK,可以在此基础上设置HCLK,PCLK,主要是设置分频比,主要通过设置CLKDIV寄存器设置。

三.代码详解:(参考韦东山大哥代码)

1.设置/启动MPLL

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

    CLKDIVN = 0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1


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

    /* 判断是S3C2410还是S3C2440 */
    if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
    {
        MPLLCON = S3C2410_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */
    }
    else
    {
        MPLLCON = S3C2440_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */
    } 
}

2.初始化定时器0,并设置中断。

/*
 * Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
 * {prescaler value} = 0~255
 * {divider value} = 2, 4, 8, 16
 * 本实验的Timer0的时钟频率=100MHz/(99+1)/(16)=62500Hz
 * 设置Timer0 0.5秒钟触发一次中断:
 */
void timer0_init(void)
{
    TCFG0 = 99; // 预分频器0 = 99 

    TCFG1 = 0x03; // 选择16分频

    TCNTB0 = 31250; // 0.5秒钟触发一次中断

    TCON |= (1<<1); // 手动更新

    TCON = 0x09; // 自动加载,清“手动更新”位,启动定时器0

}

/*
 * 定时器0中断使能
 */ 
void init_irq(void)

    // 定时器0中断使能

    INTMSK &= (~(1<<10));
}


3.执行make生成timer.bin。烧入Nandflash中后运行,即可看到4个LED每1S闪烁一次。




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
如何升级STM32单片机的代码