Chinaunix首页 | 论坛 | 博客
  • 博客访问: 344910
  • 博文数量: 92
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 960
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-21 19:38
文章分类

全部博文(92)

文章存档

2010年(71)

2009年(21)

我的朋友

分类: 嵌入式

2010-03-25 20:19:42

PWM AND TIMER

定时器有两种使用方式:

1.    TCNTBn每次减1,直到等于TCMPBnTOUTn数值翻转。

2.     TCNTBn每次减1,直到等于0,中断触发。

首先要解决定时器的频率问题,即TCNTBn每次减一所需的时间(即定时器输出频率),具体的计算公式如下:

定时器输出时钟频率=PCLK/(prescaler+1)/devider

其中prescaler值由TCFG0决定,diveder值由TCFG1决定,而prescaler只能取0~255之间的 整数,diveder只能取2,4816。比如已知PCLK50MHZ,而我们想得到某一定时器输出时钟频率为25KHZ,则依据公式可以使prescaler等于249divider等于8。于是通过设置TCNTBn我们可以得到任意与0.04毫秒成整数倍的时间间隔。例如我们想得到1秒的延时,则使TCNTBn25000

 

现在就用两种方法解决问题(1.自翻转法 2.中断法)用定时器0,让蜂鸣器每2秒钟响一次,持续0.5秒。

1.自翻转法

void Test_PWM(void)

{

        

         rGPBCON &= ~3;                        //设置GPB B0TOUT0输出 PWM输出管脚

         rGPBCON |= 2;

         rGPBDAT &=~1;                  //设置开始状态,蜂鸣器不响

                  

         rTCFG0 &= ~0xff;

         rTCFG0 |= 249;                            //prescaler = 249+1

         rTCFG1 &= ~0xf;

         rTCFG1 |= 2;                                //mux = 1/8   timer0的时钟频率为50M/250/8 = 0.025MHz(0.04毫秒)

                  rTCFG0 &= ~0xff;

         rTCFG0 |= 249;                            //prescaler = 249+1

         rTCFG1 &= ~0xf;

         rTCFG1 |= 2;                                //mux = 1/8   timer0的时钟频率为50M/250/8 = 0.025MHz(0.04毫秒)

         rTCNTB0 =50000;                   //设置timer0初值,62500*0.04=2

         rTCMPB0 =37500;                     // 当计数到1.5秒时TOUT0翻转,并保持0.5秒,当TCNTB0减到0TOUT0又发生翻转

         rTCON &= ~0x1f;                      

         rTCON |= 0xf;                     //自动重载, 反向打开, 手动刷新, 启动timer0

         rTCON &= ~2;                    //clear manual update bit

}

3.    中断法

#define       EnableIrq(bit)            rINTMSK &= ~(bit)

 

__inline void ClearPending(int bit)

{

  register i;

  rSRCPND = bit;

  rINTPND = bit;

  i = rINTPND;

}

 

void __irq Timer0_Handler(void);

{

  static int count;

  count ++;

  ClearPending(BIT_TIMER0);

  if(count%4==0)

            {

                     rGBDAT &=~1;

                     rGBDAT |=1;                       //蜂鸣器响

            }

  else

                     rGBDAT &=~1;

}

 

void Main(void)

{

  pISR_TIMER0 = (unsigned)Timer0_Handler;       //中断函数的入口地址

 

  rGPBCON &= ~3;                        //设置GPB B0TOUT0输出 PWM输出管脚

  rGPBCON |= 2;

  rGPBDAT &=~1;                  //设置开始状态,蜂鸣器不响

  ClearPending(BIT_TIMER0);

  EnableIrq(BIT_TIMER0);

 

  rTCFG0 &= ~0xff;

  rTCFG0 |= 249;                            //prescaler = 249+1

  rTCFG1 &= ~0xf;

  rTCFG1 |= 2;                                //mux = 1/8   timer0的时钟频率为50M/250/8 = 0.025MHz(0.04毫秒)

  rTCNTB0 =12500;                   //设置timer0初值,12500*0.04=0.5

  rTCON &= ~0x1f;                      

  rTCON |= 0xb;                    //自动重载, 反向关闭, 手动刷新, 启动timer0

  rTCON &= ~2;                    //clear manual update bit

 

}

 

参考网页:

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

上一篇:RTC

下一篇:Bootloader 概述

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