如何实现两次按钮中断PIC

hop*_*man 0 c embedded microcontroller interrupt pic

我正在使用 16F1703 PIC mcu,我想通过触摸按钮(A1)开始一个 7 段液晶循环(0-9)循环,之后如果我触摸按钮(A1)两次,我想要图片进入睡眠模式。

为此,我实现了这个:

#include <test_interrupt.h>
byte const DataExit[10]={0b01000100,
                               0b01011111,  
                               0b01100010,
                               0b01001010,
                               0b01011001,
                               0b11001000,
                               0b11000000,
                               0b01011110,
                               0b01000000,
                               0b01001000};
byte const bitMask[8]={1,2,4,8,16,32,64,128};

//show seven numbers
void segmentCycle(void){
   int i, j; 
   for(i=0;i<10;i++){
         for (j=0; j<8;j++){
            output_low(CLK);
            output_bit(DATA,DataExit[i] & bitMask[j]);
            output_high(CLK);  
         }

         delay_ms(7000);
         output_low(CLR);
         delay_ms(6000);
         output_high(CLR); 
   }
}

#INT_IOC
void  IOC_isr(void) 
{
  segmentCycle(); 
  sleep(); 

}

void main()
{
   port_a_pullups(0x02);
   enable_interrupts(INT_IOC_A1);
   enable_interrupts(INT_IOC_A1_H2L);
   enable_interrupts(GLOBAL);

   while(TRUE);

}
Run Code Online (Sandbox Code Playgroud)

现在,如果我触摸按钮,有时它会启动,否则不会。你有什么建议?

我正在使用 ccs 编译器。

jwd*_*hue 5

您的代码缺乏适当的去抖动算法,并且您的电路设计可能存在缺陷。将按钮连接到中断是一种宝贵资源的浪费,尤其是在它缺少去抖动电路的情况下。暂且不提,您的 ISR 正在运行并执行至少 13000 毫秒的工作(以及“延迟”)!ISR 应该简短而快速。当它们发生时,它们会中断当时正在运行的任何代码,并且在没有任何硬/软去抖动机制的情况下,每次按下按钮可能会触发多次(在该按钮上放置一个范围)。这意味着您的 ISR 例程可能会在从第一次调用退出之前多次进入,但即使这取决于引脚配置,我们也只能猜测,因为您的 OP 中缺少相关代码。

通常,您会有一个主循环来完成需要发生的任何工作,而 ISR 只是通过标志、计数器或枚举来通知状态更改。当主循环检测到状态更改时,它会调用处理该更改的任何函数。在您的情况下,它可能需要检查当前时间和最后一次按下按钮的时间,并验证最短时间段已经过去(500ms 通常在具有合理上拉的引脚上就足够了)。如果没有足够的时间过去,它会重置标志,否则它会执行所需的工作。

请参阅设备规范的第 72 页。并注意有多个中断源,ISR 负责确定哪个源导致它触发。您的代码不会查看中断标志,也不会在退出前清除前一个中断,因此您永远不会看到来自任何特定来源的多个中断。

通过一些搜索,您应该能够找到免费代码,这些代码可以在处理按钮去抖动的特定 PIC 芯片上运行。我建议您找到并研究该代码。它将为您学习和发展您的项目提供一个很好的起点。