Chinaunix首页 | 论坛 | 博客
  • 博客访问: 42439
  • 博文数量: 10
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 9
  • 用 户 组: 普通用户
  • 注册时间: 2015-12-20 12:35
文章分类
文章存档

2016年(5)

2015年(5)

我的朋友

分类: 嵌入式

2015-12-30 17:16:52

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\n" /* 读出控制寄存器 */
    "orr r1, r1, #0xc0000000\n" /* 设置为“asynchronous bus mode” */
    "mcr p15, 0, r1, c1, c0, 0\n" /* 写入控制寄存器 */
    );

    /* 判断是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闪烁一次。

文件: timer.tar.bz2
大小: 3KB
下载: 下载

阅读(1271) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~