TI中文支持网
TI专业的中文技术问题搜集分享网站

我写的关于MSP430F2132单片机的定时器程序正确吗?

注:请大家帮了看一下以下程序,我运行了后,LED一直亮着(闪烁快,人眼分不清)

问大家的目的是帮我确认定时器确实是500us中断一次,我看到TI例程里的中断里有写

TA0CCR0 += 500; ,不明白为什么要加这一个语句?

还有要不在在中断里加 :关闭CPU,开启总中断语句?

 __bis_SR_register(LPM4_bits+GIE);           // 关闭CPU,开启总中断

例:

#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void)
{
  P1OUT ^= 0x01; // 用于测试P1.0口的LED来判断定时器起作用,定时器周期为500us/次

// TA0CCR0 += 500; //好像不能要,不知道为什么?

  __bis_SR_register(LPM4_bits+GIE);           // 关闭CPU,开启总中断
}

 

完整的例程如下:

//******************************************************************************************************//
//  说明:基于MSP430F2132单片机的定时器TimerA0周期为500us/次的例程                                       //
//  程序编写:xxx 2013年23时52分                                                                                                                 //
//  本程序在IAR Assembler for MSP430 5.30.1 (5.30.1.50284)上编译                                                 //
//******************************************************************************************************//

#include"msp430X21X2.h"

//声明初始化函数
void Init_CLK(void);                      //初始化时钟Init_CLK()函数
void Init_TimerA0(void);                  //初始化定时器TimerA0()函数

//*****************************************************//
//     初始化函数 Init_CLK() (OK)                      //
//     MCLK = SMCLK = LFXT1 = HF XTAL(8Mhz)            //
//*****************************************************//

void Init_CLK(void)
{
  unsigned int i;

  BCSCTL1 = 0X00;                           // 将寄存器的内容清零
  BCSCTL1 |= XTS;                           // (ACLK = 8Mhz), ACLK = LFXT1 = HF XTAL(外部晶振8Mhz)
  BCSCTL3 |= LFXT1S1;                       // LFXT1S1 = 3-16Mhz(外部晶振8Mhz)

  do
  {
    IFG1 &= ~OFIFG;                         // 清除OSCFault标志
    i = 0xFF;                               // i = 延时
    while (i–);                            // 延时等待起振
   }
  while (OFIFG & IFG1);                     // 如果OSCFault = 1?

  BCSCTL2 = 0X00;                           // 将寄存器的内容清零
  BCSCTL2 |= SELM_3;                        // (MCLK  = 8Mhz),  MCLK  = LFXT1 = HF XTAL, 分频因子默认为1
  BCSCTL2 |= SELS;                          // (SMCLK = 8Mhz), SMCLK  = LFXT1 = HF XTAL, 分频因子默认为1
  return;
}
//结束初始化函数 Init_CLK()

//*****************************************//
//     初始化函数 Init_TimerA0() (OK)      //
//*****************************************//

void Init_TimerA0(void)
{
   TA0CCTL0 = CCIE;                          //TA0CCR0中断使能
   TA0CTL = TASSEL_2 + MC_1 + ID_3 + TACLR;  //TASSEL_2:选择SMCLK(8Mhz); MC_1:增至CCR0记数模式; ID_3:1/8分频后为1MHz;TACLR清除TAR
   TA0CCR0 = 500;                            //时间间隔 (即500us),对于MSP430单片机而言,SMCLK分频为1MHz时,正好1Hz等于1us(us为微秒)
                                            //定时器TA0CCR0设为500,即为500us/次
  return;
}
//结束初始化函数 Init_TimerA0()

 

 

void main(void){
  WDTCTL=WDTPW+WDTHOLD;                     // 关闭看门狗
    _DINT();                             // 关闭中断 
    P1DIR |= (BIT0);                          // 设置P1.0(接上-Res500-LED)
  P1OUT &= ~(BIT0);                         // 初始化P1.0为低电平,关闭LED灯

  Init_CLK();                               //初始化时钟
  Init_TimerA0();                           //初始化定时器TimerA0

  _EINT();                                  // 打开中断   //循环处理
  while(1);

}//结束main()

// Timer_A0中断处理程序:每500us亮或灭一次LED
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void)
{
  P1OUT ^= 0x01; // 用于测试P1.0口的LED来判断定时器起作用,定时器周期为500us/次

  __bis_SR_register(LPM4_bits+GIE);           // 关闭CPU,开启总中断
}

 

 

Bruce Wei:

楼主你好!

1、楼主可以借助示波器判断中断周期是否确实是500us;

2、TA0CCR0 += 500; 即是将目前 TA0CCR0 值读出来,然后再增加 500作为下次中断的计数值;

3、定时器的用法很灵活,具体请参考user guide;

Triton Zhang:

回复 Bruce Wei:

你的代码中有明显的问题,

__bis_SR_register(LPM4_bits+GIE);           // 关闭CPU,开启总中断

在定时器中断中你使用了上面这条语句,使得CPU进入LPM4的工作模式,在该工作模式下所有的clock都是关闭的,TIMER不能中断唤醒CPU。所以你看到的LED长亮并非是因为闪烁时间过短造成的。你可以利用示波器或者逻辑分析仪看到LED口线的变化.

其他地方未见明显错误.TIMER中断后建议软件清除中断标志。

Shi JianHua:

回复 Triton Zhang:

定时器没理解怎么用,还要好好看看定时器部分,定时器的工作方式有多种,我估计楼主是想用定时器唤醒单片机定时的中断来完成一些工作。所以才那样做。低功耗的应用这块还要多看看。

赞(0)
未经允许不得转载:TI中文支持网 » 我写的关于MSP430F2132单片机的定时器程序正确吗?
分享到: 更多 (0)