c - 如何实现两次按键中断PIC

标签 c embedded microcontroller interrupt pic

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

为此,我实现了这个:

#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);

}

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

我正在使用 ccs 编译器。

最佳答案

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

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

See page 72 of the device spec.请注意,有多个中断源,ISR 负责确定是哪个中断源触发的。您的代码不会查看中断标志,也不会在退出前清除前一个中断,因此您永远不会看到来自任何特定源的多个中断。

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

关于c - 如何实现两次按键中断PIC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48568158/

相关文章:

c - 从我的 makefile 运行时 GCC 忽略库

c++ - 指针稳定吗?

c - 在 C 中查找特定模式并读取该模式后面的数字

c - 尝试理解 c 中的 for 循环和 getchar()

Lauterbach 调试器无法在特定函数中设置断点

c++ - 具有深度 sleep 模式的低功耗ESP32 + LoRa (TTGO LoRa32 OLED Board V1.0)

embedded - (STM32)删除闪存并写入闪存会出现HAL_FLASH_ERROR_PGP错误(使用HAL)

c - 指示使用的 I/O 引脚的宏

c - 为什么我的 TIMER0 不使用 Atmega644 Controller 上 XTAL1 和 XTAL2 之间的振荡器?

C Atmega328P String 到 Int 转换 block RX 中断