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.

[参考译文] CCS/MSP430G2553:ISR 代码不会按动 n#39;t 暂停 PWM 占空比的变化

Guru**** 2589265 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/626736/ccs-msp430g2553-code-for-isr-pushbutton-doesn-t-pause-variation-of-the-pwm-duty-cycle

器件型号:MSP430G2553

工具/软件:Code Composer Studio

我正在尝试在 MSP430 Launchpad 中为按钮添加中断服务例程(ISR)、以便按下按钮可以暂停 PWM 占空比的变化(因此红色 LED 亮度保持恒定)。 再次按下按钮时,PWM 变化恢复(在按下第一个按钮之前,在相同的占空比值和“方向”)。 但是、当我按下按钮时、没有任何反应;红色 LED 会继续改变强度。 有人可以帮助我、看看按钮为什么不工作?

我在 timerA.c 中执行了 PWM 实现

#include "LED.h"
#include "timerA.h"

void ConfigureTimerA (void)
{
TA0CTL =(MC0 | TACLR);
TA0CTL |=(tassel_2 |ID_2 | MC_1);
//将值分配给时间 A0;捕获/比较寄存器0
TA0CCR0 = TA0CC499


;TA0CCTL1 = TA0CC0
|启用 TA0CC0 | TA0CCTR1;TA0CC0 = TA0CCTR1
= TAIE;
}
无符号整型方向= 0;
#pragma vector = TIMER0_A0_VECTOR
// CCIFG0
的中断服务例程__INTERRUPT void Timer0_A0_routine (void)
{
//最小强度下的光
IF (TACCR1 =0)
方向= 1;
//光处于最大强度
、否则(TACCR0 = TACCR1)
方向= 0;

}

#pragma vector = TIMER0_A1_vector
// CCIFG1和 TAIFG
的中断服务例程__interrupt void Timer0_A1_routine (void)
{
//如果同时指示了 TAIFG (开)和 CCR1 (关)中断、则会对 LED 产生净影响
//为空。
无符号 ON、OFF; //(16位)
关闭= TA0CTL 和 TAIFG;
ON = TA0CCTL1 & CCIFG;
如果(开和关){
//不执行任何操作
TA0CTL &=~TAIFG;
TA0CCTL1 &=~CCIFG;
}
如果(关闭)为{、则为其他值
TO_OFF_LED1;
TA0CTL &=~TAIFG;
}
否则、如果(开){
TON_LED1;
TA0CCTL1 &=~CCIFG;
}
否则{
对于(;;);//不应是可能
的}
if (on){// CCR1
//在最小增加占空比时亮起
if (DIRECTION ==0)
TACCR1 --;
//最大减小占空比时的光
否则、如果(DIRECTION = 1)
TACCR1++;
}

}

这是我实现按钮的位置

#include "button.h"
#include "LED.h"

void InitializePushButtonPortPin (void)
{

P1DIR &=~BIT3;
P1REN |= BIT3;
P1OUT |= BIT3;
P1IE |= BIT3;
P1DIR &=~BIT6;
}

#pragma vector = Port1_vector
//按钮中断服务例程
__interrupt void button_routine (void)
{
TA0CCTL0 ^= CCIE;
P1IFG &=~BIT3;
}

 这是我的主要方法

#include 
#include "LED.h"
#include "button.h"
#include "timerA.h"

//全局变量
char LEDBit = LED1;

//函数原型
void ConfigureClockModule (void);

void main (void)
{
//停止看门狗计时器,并配置时钟模块。
WDTCTL = WDTPW + WDTHOLD;
ConfigureClockModule();

//初始化与 LED 关联的端口引脚,然后关闭 LED。
InitializeLEDPortPins();


//配置计时器 A 以生成所需的中断。
ConfigureTimerA();

enable_interrupts ();

//无限循环
while (1){

}
}
void TimeDelay (unsigned int delay、unsigned int resolution){
无符号 i;
TA0CTL =(MC_0 |TACLR);
TA0CCR0 =分辨率;
TA0CTL =(tassel_2|ID_2|MC_1);

对于(i=0;i 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Maria:

    我找不到代码中调用 InitializePushButtonPortPin()的位置。 因此、看起来您从未初始化按钮引脚。 此外、我建议添加去抖例程、以便 ISR 不会通过一个按钮按压多次触发。

    最后、在您的按钮按 ISR 中、我建议使用 TA0CCTL0 &=~CCIE 清除 CCIE、而不是对寄存器进行 XORing。

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我已初始化 pushbutton.h 文件上的按钮
    #ifndef button_H
    #define PUTTOUTTON _H
    #define 按钮 BIT3


    #include

    //原型
    void InitializePushButtonPortPin (void);

    #endif
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Maria:

    这仍然不是对 InitializePushButtonPortPin 例程的调用。 它只是一个函数原型。 这意味着永远不会执行初始化代码。

    当您在按钮 ISR 内放置断点并按下按钮时、代码是否会进入 ISR? 否则、这意味着该按钮未被初始化。 您应该在 main()中向 InitializePushButtonPortPin 例程添加调用。

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    靠近 InitializeLEDPortPins()是一个好地方。 ^μ A)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在主程序上完成了此操作、但现在按钮将 LED 关闭、而不是保持 LED 的强度
    void main (void)

    //停止看门狗计时器,并配置时钟模块。
    WDTCTL = WDTPW + WDTHOLD;
    ConfigureClockModule();

    //初始化与 LED 关联的端口引脚,然后关闭 LED。
    InitializeLEDPortPins();

    //初始化与按钮关联的端口引脚
    InitializePushButtonPortPin();

    //配置计时器 A 以生成所需的中断。
    ConfigureTimerA();

    enable_interrupts ();

    //无限循环
    while (1){


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    正如我所理解的、您希望继续闪烁、但(a)按钮按 N 停止递增/递减 CCR1、然后(b)按(N+1)重新启动它? 因此、您希望使状态机保持运行(闪烁)、而不是改变 CCR1。

    我建议一个状态变量:
    易失性 uint8_t 失速;//初始未失速

    然后、当您要更改 CCR1时、添加一个条件、使扫描不会"停顿":
    如果(打开&&(!STALLED)){// CCR1

    然后在端口中断中、在0和1之间翻转变量(而不是 CCIE):
    STALLED ^= 1;//如果正在运行则停止,如果已停止则运行

    Caleb 提到了去抖、他是对的。 我的观察结果是 G2 Launchpad 按钮的抖动不会太大、因此您可能暂时忽略它、以便让其他事情发生。 不过、您很长时间不能忽略它;当您开始看到明显的多个按钮按压时、请使用 google "ganssle debounce"。 我认为他的文章是一个标准文本----既有趣又有用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我执行了您所说的操作、但当我按下按钮时、LED 指示灯将熄灭。 它应该保持强度
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我想您没有删除该行
    > TA0CCTL0 ^= CCIE;
    从 button_routine 中删除。