这不是一项任务,我只是想学习嵌入式C来远离Arduino。 (基于this interrupt LED example)
我正在尝试创建一个中断输入事件计数器。使用连接到P3.2的去抖动按钮开关增加LCD上的3位数字。 000在启动时显示,并且中断中的切换LED会切换到&打开,但显示数字没有递增。我的目标是:按1:显示001,按2:显示002等。按“重置”返回000。
我认为问题在于while()。当while()被注释时,LCD显示器快速闪烁并且不清楚读取,但我可以看到在按下开关时出现“1”(LED亮) - 当开关松开时LED熄灭(不切换)然而''1'清除了。随着while()取消注释,LCD显示屏仍然稳固。清除,LED熄灭&打开,但没有计数器增量。
代码:
// ****Event counter using external interrupt 0****
#include<reg51.h>
#include "lcd4bit.h"
void cct_init(void);
void InitINT0(void);
sbit LED = P2^3; // Int status LED
unsigned char str1[]="Line2";
char stringy[3] = {'0','0','0'};
char count = 0;
int number = 0;
void main()
{
char count = 0;
if (number != 0)
cct_init(); // Make all ports zero
InitINT0(); // Intialize INT0 interrupts
stringy[count]=(number%10)+48;
number/=10;
init_lcd();
gotoxy_lcd(1,1); //(Col, Line#)
print_lcd("Line One");
gotoxy_lcd(1,2);
print_lcd(stringy);
while(1)
{ }
}
void cct_init(void) // Init CCT function
{
P3 = 0x04; // Make P3.2 (INT0) pin high only
}
void InitINT0(void) // External INT0 pin interrupt init function
{
IT0 = 1; //Edge triggered interrupt mode (Neg)
EX0 = 1; //Enable external interrupt INT0
EA = 1; //Enable global interrupts
}
void external0_isr(void) interrupt 0 // Inturrupt 0 ISR
{
number = number + 1;
LED = ~LED; // Toggle LED
}
任何建议表示赞赏。
答案 0 :(得分:1)
我认为您误解了ISR的工作原理。除while(1) {}
之外的所有代码都在程序开始时执行一次。然后主线程就位于while
循环内部,以便执行其余的操作。
发生中断不会将主线程重置回main()
或其他任何内容。
此外,代码:
if (number != 0)
cct_init(); // Make all ports zero
InitINT0(); // Intialize INT0 interrupts
不会在此处cct_init()
致电number == 0
,然后调用InitINT0()
。 if
语句仅绑定到其后的一个语句,除非您使用{ }
对语句进行分组。
根据您链接的示例,这应该只是:
cct_init();
InitINT0();
如果您希望在中断触发后执行main()
中的代码,则必须更改while
循环以检测number
中的更改。
这可能有效:
// global var
volatile int number = 0;
// in main() instead of your existing while loop
int previous_number = 0;
while (1)
{
if ( number != previous_number )
{
previous_number = number;
// put your LCD updating code here
// possibly you should disable the interrupt before the LCD code
// and re-enable the interrupt afterwards
}
}
有一个潜在的错误,因为比较number != previous_number
可能不是原子的。对unsigned char
使用int
代替number
似乎是一种很好的预防措施。
这个关于原子性和操作的主题应该在8051所嵌入的平台的文档中提到,所以我试着去查看确认。