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 编译器。
您的代码缺乏适当的去抖动算法,并且您的电路设计可能存在缺陷。将按钮连接到中断是一种宝贵资源的浪费,尤其是在它缺少去抖动电路的情况下。暂且不提,您的 ISR 正在运行并执行至少 13000 毫秒的工作(以及“延迟”)!ISR 应该简短而快速。当它们发生时,它们会中断当时正在运行的任何代码,并且在没有任何硬/软去抖动机制的情况下,每次按下按钮可能会触发多次(在该按钮上放置一个范围)。这意味着您的 ISR 例程可能会在从第一次调用退出之前多次进入,但即使这取决于引脚配置,我们也只能猜测,因为您的 OP 中缺少相关代码。
通常,您会有一个主循环来完成需要发生的任何工作,而 ISR 只是通过标志、计数器或枚举来通知状态更改。当主循环检测到状态更改时,它会调用处理该更改的任何函数。在您的情况下,它可能需要检查当前时间和最后一次按下按钮的时间,并验证最短时间段已经过去(500ms 通常在具有合理上拉的引脚上就足够了)。如果没有足够的时间过去,它会重置标志,否则它会执行所需的工作。
请参阅设备规范的第 72 页。并注意有多个中断源,ISR 负责确定哪个源导致它触发。您的代码不会查看中断标志,也不会在退出前清除前一个中断,因此您永远不会看到来自任何特定来源的多个中断。
通过一些搜索,您应该能够找到免费代码,这些代码可以在处理按钮去抖动的特定 PIC 芯片上运行。我建议您找到并研究该代码。它将为您学习和发展您的项目提供一个很好的起点。