• 时钟体系


    时钟概念:
    ★时钟脉冲:一个按一定电压幅度,一定时间间隔连续发出的脉冲信号;
    ★时钟频率:在单位时间(如:1秒)内产生的时钟秒冲数;
    作用:
    时钟信号是时序逻辑的基础
    时钟的产生-晶振
    晶振:晶体振荡器,是用石英晶体精密切割做成。
    时钟产生-PLL
    PLL:(锁相环)合成器=外部晶体+PLL电路。
    S3C2440的主时钟晶振来自外部晶振(XTIPLL),或者是外部时钟(EXTCLK)。时钟生成器包含了一个振荡器(振荡放大器),其连接外部晶振,可以产生需要的高频,通过引脚OM[3:2]来决定时钟源时Crystal还是EXTCLK.
    S3C2440有两个PLL:(1)MPLL和(2)UPLL,
    UPLL专用于USB设备。
    MPLL 用于CPU及其他外围器件。
    通过MPLL会产生三个部分的时钟频率:
    FCLK:用于CPU核;
    HCLK:用于AHB(常用于高速外设)总线的设备,比如:SDRAM;
    PCLK:用于APB(常用于低速外设)总线的设备,比如:UART.

     时钟启动流程:

          1.上电几毫秒后,外部晶振输出稳定,FCLK=外部晶振频率(12MHZ,nRESET

    信号恢复高电平后,CPU开始执行命令。

          2.在设置MPLL的几个寄存器后,需要等待一段时间(Lock Time,MPLL的输出才稳定。在这段时间(Lock Time)内,FCLK停振,CPU停止工作。

    Lock Time的长短由寄存器LOCKTIME设定。

         3.Lock Time之后,MPLL输出正常,CPU工作在新的FCLK(如:400MHZ)下。

    设置S3C2440的时钟频率就是设置相关的几个寄存器:

     

     CLKDIVN

    寄存器用于设置FCLK、HCLK、PCLK三者的比例
    ★  HDIVN:位[2:1],用来设置HCLK与FCLK比例关系
    ★  PDIVN:位[0],用来设置PCLK与HCLK比例关系
    例如:
    FCLK:HCLK:PCLK=4:2:1
    FCLK=400MHZ(主频)
    HCLK=200M
    PCLK=100M

     

     void Set_Clk(void)    

    {    
           int i;    
           U8 key;    
           U32 mpll_val = 0 ;  
           i = 2 ;                  
                                  
           switch ( i ) {  
      
           case 0:    //200   
                  key = 12;    
                  mpll_val = (92<<12)|(4<<4)|(1);    
                  break;   
           case 1:    //300    
                  key = 13;  
                  mpll_val = (67<<12)|(1<<4)|(1);   
                  break;    
           case 2:    //400    
                  key = 14;    
                  mpll_val = (92<<12)|(1<<4)|(1);  
                  break;  //FCLK=2*(92+8)*(12000000)/(3+2^1)=400000000=400MHz
      
           case 3:    //440!!!    
                  key = 14;   
                  mpll_val = (102<<12)|(1<<4)|(1);   
                  break;    
           default:    
                  key = 14;   
                  mpll_val = (92<<12)|(1<<4)|(1);    
                  break;    
           }               
           ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); //设置rMPLLCON得到FCLK
           ChangeClockDivider(key, 12);    //经过CLKDIVE设置,确定FCLK、HCLK、PCLK三者之间的关系       
    }  
    void ChangeClockDivider(int hdivn_val,int pdivn_val)
    {
        int hdivn=2, pdivn=0;
        
         // hdivn_val (FCLK:HCLK)ratio hdivn
         
    // 11           1:1       (0)
         
    // 12           2:1       (1)
         
    // 13           3:1       (3) 
         
    // 14           4:1       (2)
         
    // pdivn_val (HCLK:PCLK)ratio pdivn
         
    // 11           1:1       (0)
         
    // 12           2:1       (1)
        switch(hdivn_val) {
            case 11: hdivn=0break;
            case 12: hdivn=1break;
            case 13:
            case 16: hdivn=3break;
            case 14
            case 18: hdivn=2break;
        }
        
        switch(pdivn_val) {
            case 11: pdivn=0break;
            case 12: pdivn=1break;
        }
        
        //Uart_Printf("Clock division change [hdiv:%x, pdiv:%x] ", hdivn, pdivn);
        rCLKDIVN = (hdivn<<1) | pdivn;  PCLK HCLK 分频

        switch(hdivn_val) {   //摄像头时钟分频
            case 16:        // when 1, HCLK=FCLK/8.
                rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<8); 
            break
            case 18:     // when 1, HCLK=FCLK/6.
                rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<9); 
            break;
        }
        
        if(hdivn!=0)
            MMU_SetAsyncBusMode();
        else 
            MMU_SetFastBusMode();   

    }

     ARM920T有三种时钟模式:FastBus(快总线模式),synchronous(同步模式), asynchronous(异步模式)

    FastBus(快总线模式)
      该模式将时钟BCLK作为时钟GCLK的源,时钟FCLK被忽略。主要用于带有高速存储器的系统。
    synchronous(同步模式)
      该模式主要用于带有低速存储器的系统。时钟BCLK和时钟FCLK作为时钟GCLK的源,BCLK用于控制AMBA存储接口,FCLK用于控制内部的ARM9TDMI处理器核和任何cache缓存的操作。 FCLK的频率必须比BCLK高且是其整数陪,且在FCLK是高电平时BCLK才跳变。
    asynchronous(异步模式)
      该模式主要用于带有低速存储器的系统。时钟BCLK和时钟FCLK作为时钟GCLK的源,BCLK用于控制AMBA存储接口,FCLK用于控制内部的ARM9TDMI处理器核和任何cache缓存的操作。FCLK的频率只需比BCLK高。
    static void cal_cpu_bus_clk(void)   //cal“calculator”,计算器的简写
    {                                   //这个函数用来计算cpu总线时钟
     static U32 cpu_freq;
        static U32 UPLL;
     
     U32 val;
     U8 m, p, s;
     
     val = rMPLLCON;      //将rMPLLCON拆开
     m = (val>>12)&0xff;
     p = (val>>4)&0x3f;
     s = val&3;
     //(m+8)*FIN*2 不要超出32位数!
     FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100;     //FCLK=400M  FIN=12000000
     
     val = rCLKDIVN;     //将rCLKDIVN拆开
     m = (val>>1)&3;
     p = val&1
     val = rCAMDIVN;
     s = val>>8;
     
     switch (m) {
     case 0:
      HCLK = FCLK;
      break;
     case 1:
      HCLK = FCLK>>1;
      break;
     case 2:
      if(s&2)
       HCLK = FCLK>>3;
      else
       HCLK = FCLK>>2;
      break;
     case 3:
      if(s&1)
       HCLK = FCLK/6;
      else
       HCLK = FCLK/3;
      break;
     }
     
     if(p)
      PCLK = HCLK>>1;
     else
      PCLK = HCLK;
     
     if(s&0x10)
      cpu_freq = HCLK;
     else
      cpu_freq = FCLK;
      
     val = rUPLLCON;//rUPLLCON内存的值为0x00038022求出UPLL的值为48MHz;时钟分频控制寄存器CLKDIVN[3]=0时UCLK=UPLL
     m = (val>>12)&0xff;
     p = (val>>4)&0x3f;
     s = val&3;
     UPLL = ((m+8)*FIN)/((p+2)*(1<<s));
     UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;  USBCLK的值必须是48MHz
     Uart_Printf(" FCLK:%dMHz,HCLK:%dMHz,PCLK=%dMHZ ",FCLK/1000/1000,HCLK/1000/1000,PCLK/1000/1000);
    }
    /

    定时器

    频率 

     

     

     

     计数值

     

     

     

     


    void Timer0_init(void)  
      
    {     
      rTCFG0 = 49;              //pclk/(49+1)  
      rTCFG1 = 0x03;            //16分频=62500HZ  
                     
    //定时器频率= 1M /(49+1)/16=62500HZ
      rTCNTB0 = 62500/2;          //TCNTB0[15:0]=计数值      
      rTCMPB0 = 0;               //比较值
      
      rTCON |=(1<<1);           //计数值装入TCNTB0、TCMPB0    
      
      rTCON =0x09;               //1001 自动重载,启动。
     
    ClearPending(BIT_TIMER0);  //清除SRCPND、INTPND 此处课省略
      
    /*当达到0.5秒时,执行中断函数IRQ_Timer0_Handle */  
      
      pISR_TIMER0 = (U32)IRQ_Timer0_Handle;       //中断向量 = 中断函数
      
      EnableIrq(BIT_TIMER0);   //手动打开屏蔽 INTMSK  
    }  
      
    static void __irq IRQ_Timer0_Handle(void)    
    {    
        ClearPending(BIT_TIMER0);  //清中断   
        Led1_run();   

     

  • 相关阅读:
    关于unbox.any castclass ldobj
    SQL 语句 之 增删改查 (一)
    .NET(C#):使用SmtpClient发送带有图片和附件的电子邮件
    Ext.Net 1.2.0_演示 Ext.Net+QRCode 封装条形码控件
    局域网共享打印机(不需要密码)
    Windows 2003单用户单会话登录远程桌面
    不过如此
    CellMerge
    Windows Server 2008服务器支持iso文件下载的方法
    SQL2008 Express 无法打开备份设备 '‘xxxxx'。出现操作系统错误 5(拒绝访问。)。BACKUP DATABASE 正在异常终止。
  • 原文地址:https://www.cnblogs.com/liuchengchuxiao/p/4179080.html
Copyright © 2020-2023  润新知