Chinaunix首页 | 论坛 | 博客
  • 博客访问: 164189
  • 博文数量: 36
  • 博客积分: 830
  • 博客等级: 准尉
  • 技术积分: 409
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-10 16:23
文章分类
文章存档

2013年(1)

2012年(35)

分类: 嵌入式

2012-08-29 10:09:08

 

   定时器的应用,这是第三个实验。在前面我们延时的时候,都是用的循环,也就是意思意思,达不到非常准确。我们要向准备的控制延时,我们就可以使用定时器。

   在使用定时器之前,首先得熟悉2440的时钟系统。

上图即是2440的时钟产生框图。主时钟源一般是外部晶振或者外部时钟,多数用得是外部晶振。我们mini2440上也是12M的外部晶振,这个可以通过OM[3:2]位来配置。但是这个频率还是不能满足需求,所以通过PLL锁存器来进行倍频,有分为MPLLUPLL,后者给USB使用,提供48M频率。而MPLL处理后得到3个时钟,FCLK,HCLK,PCLK.从上图可以看出,FCLK是主频时钟,用于ARM920T内核;HCLK用于AHB总线设备,如ARM920T,内存控制,中断控制,LCD控制,DMA以及USB主模块;PCLK用于APB总线设备,如外围设备的看门狗,IISI2CPWMMMC接口,ADCUARTGPIORTC以及SPI

   三个系统时钟是有一定比例关系的,这个关系就是通过CLKDIVN寄存器中的HDIVN位和PDIVN位来控制,因此知道了FCLK的话,其他两个也就知道了。

FCLK又如何得到呢?这个时钟经过MPLL倍率后,经过一个计算公式得到,这个计算公式需要三个参数MDIV,PDIV,SDIV,这个可以通过用户手册查看,这三个参数是经过寄存器MPLLCON配置得到的。

Mini2440上面外部晶振是12M,倍率后的FCLK400MHZ,而FCLK,HCLK,PCLK的比例为1:4:8

因为HCLK100MPCLK50MHZ。我们在启动文件中,已经把相关的寄存器已经设置好了,这里你只需要了解它的原理。

    了解了时钟控制部分,那么我们就可以看定时器中断了。

首先看时钟,它是由PCLK引出来的,在它的基础上,经过一个八位分频和一个时钟分频。所以得到定时器的输出时钟频率为PCLK ÷ (prescaler+1) ÷ divider 其中prescaler值由TCFG0决定,divider值由TCFG1决定,而prescaler只能取0~255之间的整数,divider只能取24816

比如已知PCLK50MHz,而我们想得到某一定时器的输出时钟频率为25kHz,则依据公式可以使PCLK ÷ (prescaler+1) ÷ divider prescaler等于249divider等于8

25Khz 这个频率是用来给计数器TCNTB0使用的,如果设置TCNTB0等于25000,那么TCNTB025000减到0就是1秒。

 

当它减到0的时候,那么就会产生定时器中断,当然你的把中断相关的屏蔽打开,定时中断服务程序。并且在TCON中更新你设置的TCNTB0的值,然后启动定时器。

这个寄存器我们需要认真看一下,首先自动重载功能,这个就是说,你的TCNTB0会自动重载TCNT0中的值,那么刚开始的话你就需要设置一个初始值给TCNTB0,后面你可以改动它,它会自动重载新的值。然后就是手动更新位,这个主要就是刚开始使用的时候,你把你的初始值更新给它,然后关闭这一位,必须关闭,不然出问题。接下来就是启动了。

  我们这次这个实验的话,利用定时器来控制蜂鸣器,让它前面隔一秒叫一声,第五次之后,就把频率改变。在中断服务程序,我们改变TCNTB0的值来改变它的频率,由于自动重载,那么它就会重载我新设置的值。

  下面贴出主要程序代码。

  int dat = 0;

  void __irq interupt(void)

  {  

      static int i=0;

     

      rSRCPND |= (1<<14);

      rINTPND |= (1<<14);

     

      dat = ~dat;

      rGPBDAT = dat ;

     

      i++;

      if(i == 5 )

        rTCNTB4 = 250;//改变它的值那么将会重载这个新设置的值beep响的频率也//是加快

  }

    

  void Main(void) 

  {

       

     Set_Clk();

     MMU_Init();

  

     rGPBCON &= ~3;

     rGPBCON |= 1;

     rINTMSK &= ~(1<<14);

     //50M / 250 =200k

     rTCFG0 &=~(0xff<<8);

     rTCFG0 |=(249<<8);

     //200k / 8 =25k

     rTCFG1 &=(0xf<<16);

     rTCFG1 |=(2<<16);

     //1s = 25000*1/25k

     rTCNTB4 = 25000;

     //更新TCNTB4

     rTCON |= (3<<21);

     //关闭更新

     rTCON &= ~(1<<21);//这里必须要关闭更新,不然效果出不来,2440用户手册上也//说明了

   

     //中断服务程序

      pISR_TIMER4 = (U32)interupt;

     //启动定时器4

      rTCON |= 1<<20;

        

   

     while(1);

  

  

  

  }

 

阅读(3441) | 评论(0) | 转发(0) |
0

上一篇:breakfast or lunch

下一篇:最近小感受

给主人留下些什么吧!~~