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.

[参考译文] MSP430G2553:在向上计数模式下使用定时器捕获比较来区分短按和长按按钮:正常工作、但正确吗?

Guru**** 2540720 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/587310/msp430g2553-using-timer-capture-compare-in-up-mode-to-distinguish-between-short-and-long-button-press-works-but-is-it-correct

器件型号:MSP430G2553

你(们)好 我有用于切换两个 LED 的工作代码、一个用于短按按钮、另一个用于长按。 我的问题是、这是不是一种非常规的方法、例如、我只去去除下降沿等? 感谢您分享任何想法。

我的设计。 计时器;TA1、向上计数模式、对应于1秒的比较值、捕获/比较中断使能、SMCLK (1MHz) 4分频、CCR0值40、000 (应每秒触发一次中断)。 按下按钮;内部上拉、首先在下降沿中断、使用 WDT 检查按钮是否稳定、然后在 WDT ISR 中将中断设置为上升沿。 使用 TA1 ISR 的第二次计数、根据印刷持续时间切换特定的 LED。

这是工作代码。

#include 

#define PB1 BIT4
#define LED_SHORT BIT0
#define LED_long BIT6
#define CCREGISTER 40000
volatile int longbtnPress = 0;
volatile int buttonPressed = 0;
volatile int timerCounter = 0;

int main (void){
WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
//设置 LED
P1SEL = 0;
P1SEL2 = 0;
P1OUT &=~(LED_SHORT + LED_long);//预加载这些关闭
P1DIR |=(LED_SHORT + LED_Long);
P1OUT |= LED_SHORT;//短接启动
//设置按钮
P2SEL = 0;
P2SEL2 = 0;
P2DIR &=~PB1;//设置为输入引脚
P2REN |= PB1;//启用上拉/下拉电阻器
P2OUT |= PB1;//选择上拉
P2IES |= PB1;//启用中断以在下降沿触发
P2IFG &=~PB1;//清除中断标志
P2IE |= PB1;//在此引脚上启用中断
/*
*设置计时器
* MC_1递增模式、TASSEL_2 SMCLK 1MHz、ID_2输入4分频
每个计时器溢出* 40000 x 1E-6 / 4 = 1.0秒
*
TA1CCR0 = CCREGISTER;
TA1CTL = MC_1 + TASSEL_2 + ID_2;
TA1CCTL0 &=~CCIFG;//CLEAR 标志
_enable_interrupt ();
for (;;){
//做您的事情
}
返回0;
}

#pragma vector = port2_vector
__interrupt void port2_ISR (void)
{
//哪个中断?
if (P2IFG & PB1){
P2IE &=~PB1;//禁用中断
P2IFG &=~PB1;//清除标志
if (buttonPressed = 1)
{
//测试长按或短按
if (longbtnPress = 1)
{
P1OUT ^= LED_Long;//切换长 LED
longBtnPress = 0;
}否则
{
P1OUT ^= LED_SHORT;//切换短路 LED
}
buttonPressed = 0;
//禁用 TA1 CCR0中断
TA1CCTL0 &=~CCIE;
timerCounter = 0;

P2IES |= PB1;//在下降边沿触发
P2IE |= PB1;//为 PB1打开中断
}否则
{//开始并设置 WD 计时器32ms 以进行 Btn 去抖
WDTCTL = WDT_MDLY_32;
IFG1 &=~WDTIFG;//清除标志
IE1 |= WDTIE;//启用 WDT 中断
//启用 CCR0中断
TA1CCTL0 = CCIE;
}
}
其他
{
P2IFG = 0;//清除所有标志
}
}
#pragma vector = WDT_vector
__interrupt void WDT_ISR (void)
{
IE1 &=~WDTIE;//禁用 WDT
IFG1 &=~WDTIFG;//清除标志
WDTCTL = WDTPW | WDTHOLD;//停止 WD
//测试端口2 PB1是否为低电平
如果(!(P2IN 和 PB1))
{
buttonPressed = 1;
longBtnPress = 0;
}
在上升沿上为//触发
P2IES &=~PB1;
//为 PB1打开中断
P2IE |= PB1;
}

#pragma vector = Timer1_A0_vector
_中断空 Timer1_A0_CCR0_ISR (空)
{
如果(timerCounter > 2)//3溢出= 3秒
{
longBtnPress = 1;
}否则{
timerCounter = timerCounter + 1;
}
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果上升沿不触发任何操作、则无需去抖。 (但上升沿上的任何抖动也会触发下降沿逻辑、因此您无论如何都会得到去电。)

    我在该代码中看不到任何明显的错误。 (但请注意 C.A.R.是什么 Hoare 所说的明显错误。)