This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F149 定时器 中断问题

我利用以下程序,使用定时器A产生固定的38KHz波形,利用定时器B中断开关暂停定时器A,以实现断断续续的38KHz波形。 可结果一直持续输出38KHz的波形,为什么?

#include <msp430x14x.h>

#define T_CYC 104 //get 38kHz (timer 2MHz out_module7)
#define T_ON 35 //duty cycle (timer 2MHz out_module7)


void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

volatile unsigned int i;

BCSCTL1 &= ~XT2OFF; // XT2= HF XTAL
do
{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for (i = 0xFF; i > 0; i--); // Time for flag to set
}
while ((IFG1 & OFIFG)); // OSCFault flag still set?
BCSCTL2 = SELM_2 + SELS + DIVS_1; // MCLK= XT2 SMCLK= XT2/2 (safe)

P1DIR = 0;
P1DIR |= BIT6;
P1SEL = 0;
P1SEL |= BIT6; //SET P1.6 TA1 OUT module
CCTL1 = 0;
CCTL1 |= OUTMOD_7;
CCR0 = T_CYC;
CCR1 = T_ON;
TACTL = 0;
TACTL = TASSEL_2 + TAIE; // SMCLK, contmode

P2DIR = BIT0;

TBCCR0 = 32333;
TBCCTL0 = 0;
TBCCTL0 |= CCIE;
TBCTL = 0;
TBCTL = CNTL_0 + TBSSEL_1 + MC_1 + TBIE; //定时器B时钟信号选择ACLK,同时设置定时器B计数模式为连续增计模式,TBR(MAX) = 0xFFFFh

TACTL |= MC_1;
_EINT(); //中断允许
for(;;)
_BIS_SR(LPM0_bits + GIE); // Enter LPM0
}

#pragma vector=TIMERB0_VECTOR //定时器B TACCR0中断处理
__interrupt void timer_b0(void)
{
_BIC_SR_IRQ(LPM0_bits); // Clear LPM0 bits from 0(SR)
TACTL ^= MC_1;
P2OUT ^= BIT0;
}

  •   能进中断么?

    建议两个 Timer 分开调,程序思路是可以的。手头没有149,我这边用另外一个片子试过两个Timer_A没问题。

  • TACTL ^= MC_1;这一句是有问题的,可能会操作到无关的bit位

  • dirtwillfly 说:

    TACTL |= MC_1这一句是有问题的,可能会操作到无关的bit位

    如何可能操作到无关的bit位,请说完。

  • 中断可以进的,p2.0接的是led指示灯,是在闪烁的,但是观察p1.1波形是连续的, 并没有停止的状态。

    >>我这边用另外一个片子试过两个Timer_A没问题。

    两个timerA是什么意思?你直接把我的程序编译一下看看,谢谢!

  • 额~

    这个怎么可能操作到其他位呢?1跟0或还是1, 0跟0或还是0。。。。。。

  • 149的程序没问题了,你试一下:(你用的是8MHz 和 32768的晶振么?)

    #include <msp430x14x.h>
    
    #define T_CYC 104 //get 38kHz (timer 2MHz out_module7)
    #define T_ON 35 //duty cycle (timer 2MHz out_module7)
    
    
    void main(void)
    {
        WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    
        volatile unsigned int i;
    
        BCSCTL1 &= ~XT2OFF; // XT2= HF XTAL
        do
        {
            IFG1 &= ~OFIFG; // Clear OSCFault flag
            for (i = 0xFF; i > 0; i--); // Time for flag to set
        }
        while ((IFG1 & OFIFG)); // OSCFault flag still set?
        BCSCTL2 = SELM_2 + SELS + DIVS_1; // MCLK= XT2 SMCLK= XT2/2 (safe)
    
        P1DIR = 0;
        P1DIR |= BIT6;
        P1SEL = 0;
        P1SEL |= BIT6; //SET P1.6 TA1 OUT module
        CCTL1 = 0;
        CCTL1 |= OUTMOD_7;
        CCR0 = T_CYC;
        CCR1 = T_ON;
        TACTL = 0;
        TACTL = TASSEL_2;// + TAIE; // SMCLK, contmode
    
        P2DIR = BIT0;
    
        TBCCR0 = 32333;
        TBCCTL0 = 0;
        TBCCTL0 |= CCIE;
        TBCTL = 0;
        TBCTL = CNTL_0 + TBSSEL_1 + MC_1;// + TBIE; //定时器B时钟信号选择ACLK,同时设置定时器B计数模式为连续增计模式,TBR(MAX) = 0xFFFFh
    
        TACTL |= MC_1;
    
        __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0 w/ interrupt
    
        while(1)
        {
            __no_operation();
        }
    }
    
    #pragma vector=TIMERB0_VECTOR //定时器B TACCR0中断处理
    __interrupt void timer_b0(void)
    {
        TACTL ^= MC_1;
        P2OUT ^= BIT0;
    }
    
  • LI CHUNLEI Panasonic Corporation of China 说:

    中断可以进的,p2.0接的是led指示灯,�在闪烁的,但是观察p1.1波形是连续的, 并没有停止的状态。

    >>我这边用另外一个片子试过两个Timer_A没问题。

    两个timerA是什么意思?你直接把我的程序编译一下看看,谢谢!

    P1.1? 程序里是P1.6输出啊

  • 笔误~ 不好意思~

    我试试你的程序,稍等~

  • 你好!非常感谢!

    你的这个程序是可以的,我也发现问题所在了,问题在于我打不打开 TBIE 中断,如果打开则一直连续输出38K。

    但是我不能理解啊~ TBIE 打开不是只有在定时器发生溢出时才响应的中断吗?我的TBCCR0固定32333啊~每次进中断后寄存器TAR不就又清空了吗?不会发生溢出啊~  怎么会跟开不开 TBIE 中断有关呢?谢谢!

    另外,程序执行到

    __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0 w/ interrupt
    就进入休眠模式了,
    在中断服务函数里边并没有把休眠关闭,cpu还是被禁用的,那么中断里边的两条代码由什么时钟来驱动执行?由谁来执行?
    
    
    以上~ 谢谢!期待您的回复。
  • LI CHUNLEI Panasonic Corporation of China 说:

    你好!非常感谢!

    你的这个程序��可以的,我也发现问题所在了,问题在于我打不打开 TBIE 中断,如果打开则一直连续输出38K。

    但是我不能理解啊~ TBIE 打开不是只有在定时器发生溢出时才响应的中断吗?我的TBCCR0固定32333啊~每次进中断后寄存器TAR不就又清空了吗?不会发生溢出啊~  怎么会跟开不开 TBIE 中断有关呢?谢谢!

    另外,程序执行到

    __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0 w/ interrupt
    就进入休眠模式了,
    在中断服务函数里边并没有把休眠关闭,cpu还是被禁用的,那么中断里边的两条代码由什么时钟来驱动执行?由谁来执行?
    
    
    以上~ 谢谢!期待您的回复。

    1. TBIE 打开不是只有在定时器发生溢出时才响应的中断吗?不是,

    如果开了某一个中断使能,而没有写对应的中断服务程序,那么代码可能就会跳转到一个默认的中断服务程序里。

    2. 430进入中断服务程序的时候,自动切换到 active 模式,执行完推出中断之前,再次自动进入低功耗模式。

  • 你好,还有一个问题,当在timerB中暂停timerA时,p1.6口的电平不定,我想把它设定为当timerA暂停时,p1.6口确定输出低电平,为此我将中断服务函数做了如下改造,可结果p1.6口电平还是不定,请问应该怎么办?
    __interrupt void timer_b0(void)
    {
        TACTL ^= MC_1;
                    if(!(TACTL & MC_1))
                    {
                               P1SEL &= ~BIT6;
                               P1OUT &= ~BIT6;
                               P1SEL |= BIT6;
                    }
        P2OUT ^= BIT0;
    }
  • LI CHUNLEI Panasonic Corporation of China 说:
    你好,还有一个问题,当在timerB中暂停timerA时,p1.6口的电平不定,我想把它设定为当timerA暂停时,p1.6口确定输出低电平,为此我将中断服务函数做了如下改造,可结果p1.6口电平还是不定,请问应该怎么办?
    __interrupt void timer_b0(void)
    {
        TACTL ^= MC_1;
                    if(!(TACTL & MC_1))
                    {
                               P1SEL &= ~BIT6;
                               P1OUT &= ~BIT6;
                               P1SEL |= BIT6;
                    }
        P2OUT ^= BIT0;
    }

    #pragma vector=TIMERB0_VECTOR //定时器B TACCR0中断处理
    __interrupt void timer_b0(void)
    {
        TACTL ^= MC_1;
        if(!(TACTL & MC_1))
        {
            P1SEL &= ~BIT6;
            P1OUT &= ~BIT6;
        }
        else
            P1SEL |= BIT6;
        P2OUT ^= BIT0;
    }