我有这个问题: 我想区分触发器(BTN0 和 BTN1 - 这 2 个按钮的引脚在同一个中断向量 - PCINT2 中)。我怎么知道是谁触发了 ISR?
这是 BTN0 的代码(我需要添加什么才能使用这两个按钮?):
#pragma vector=PCINT2_vect
__interrupt void btn01_press(void)
{
unsigned char current_btn0_state = BTN0;
unsigned char prev_btn0_state = !current_btn0_state;
unsigned char current_btn1_state = BTN=1;
unsigned char prev_btn1state = !current_btn1_state;
if(current_btn0_state == BTN_RELEASED && prev_btn0_state == BTN_PRESSED)
{
if(LED0 == LED_OFF)
{
if(current_btn0_state && BTN0 == BTN_RELEASED) // for debouncing
{
led_PowerOn_number(L0);
current_btn0_state = !current_btn0_state;
}
}
else
{
if(BTN0 == BTN_RELEASED)
{
led_PowerOff_number(L0);
current_btn0_state = !current_btn0_state;
}
}
return;
}
// this is is also true, and is executed with first (for BTN0), but i want to be triggered separately.
//
// if(current_btn1_state == BTN_RELEASED && prev_btn1_state == BTN_PRESSED)
// {
//
// if(LED1 == LED_OFF)
// {
// if(current_btn1_state && BTN1 == BTN_RELEASED)
// {
// led_PowerOn_number(1);
// initial_btn1_state = !initial_btn1_state;
// }
// }
// else
// {
// if(BTN1 == BTN_RELEASED)
// {
// led_PowerOff_number(1);
// initial_btn1_state = !initial_btn1_state;
// }
// }
// return;
// }
}
一些答案。一个办法。谢谢
我解决了。部分地。问题出在我按下/释放按钮的逻辑中(按下== 0)。现在我需要一个没有软延迟的去抖解决方案。
#pragma vector=PCINT2_vect
__interrupt void btn01_press(void)
{
unsigned char current_btn0_state = BTN0;
unsigned char current_btn1_state = BTN1;
if(current_btn0_state == BTN_PRESSED) // ISR for BTN0
{
if(LED0 == LED_OFF)
{
led_Sdelay(DEBOUNCING_TIME);
led_PowerOn_number(L0);
current_btn0_state = !current_btn0_state;
}
else
{
led_Sdelay(DEBOUNCING_TIME);
led_PowerOff_number(L0);
current_btn0_state = !current_btn0_state;
}
return;
}
if(current_btn1_state == BTN_PRESSED) // ISR for BTN0
{
if(LED1 == LED_OFF)
{
led_Sdelay(DEBOUNCING_TIME);
led_PowerOn_number(L1);
current_btn1_state = !current_btn1_state;
}
else
{
led_Sdelay(DEBOUNCING_TIME);
led_PowerOff_number(L1);
current_btn1_state = !current_btn1_state;
}
return;
}
}
对按钮使用中断是个坏主意 - 这是可能的,但比你在这里复杂得多 - ISR 中的去抖动方式不可靠,因为你会在弹跳期间捕获很多虚假中断。
专业的解决办法是改用一个间隔5ms或10ms的循环定时器中断。让 ISR 只关心去抖动。将有关按下哪个按钮等的决定留给周围的按钮驱动程序。
它可能看起来像(伪代码):
static volatile uint8_t buttons;
static void timer_isr (void) // called every 5/10ms etc
{
static uint8_t prev_port;
uint8_t port = PORT; // read the register
if(port == prev_port)
{
buttons = port; // only use values that have been stable for 5ms/10ms etc
}
prev_port = port;
/* clear flags, reset timer etc as required by the timer peripheral */
}
bool is_button_x_pressed (void) // public function called by the user
{
return buttons & BUTTON_X_MASK;
}