|
+ `" ?, V2 w( G0 d7 a6 r+ E
如果你了解汇编语句,会对你的理解有帮助。所以不懂汇编是不能称为精通单片机的。% b& }7 n: I, W- L
C语言t=1000中的t,在CPU中必须用两个字节来表示,不妨起个名子叫NH和NL。t=NH,NL
+ z+ P+ P# I/ p' D$ y8 y9 L你的主程序一直在等t=1000,也就等(NH,NL,16进制)=03E8H,但是CPU指令只能一个一个的判断,假设先判断NH=03,而后再判断NL=E8,逻辑上是没有毛病的。
) p6 q# |( v# F! t你的中断是每1ms一次,中断发生时,你的程序运行到什么地方了呢?不太好确定吧,你的程序一直在等t=1000,估计多半会在此处中断。
8 n# c& R0 s& h+ ?3 G. g注意,有个关键的特殊事件发生了,而且发生的概率还不了(程序不长)。
% `# h: p* O2 U5 y中断发生在CPU已判断了NH,还未判定NL。而中断服务程序会做t++,也即(NH,NL)+1,这就修改NL的值,问题来了。% e( p6 u) b) G. B; b8 C: C
例如:原先(NH,NL)=1000 = 03E8H,程序已确定NH=03,如果NL=E8,就反转LED灯。
1 B$ G& H! Z8 l/ B但是中断发生在NH=03判断之后,而NL还未判定,中断时你将t++,也即(NH,NL)++,变成了 03E9H,中断返回后,再判断NL却不是E8,而是E9了。
( ]) g% k6 U, v如此,程序不会再做LED反转了。t将=1001,此后被加到65535,再回0,下次再加到1000。
) K- A5 H# t$ d1 C0 Z, ^7 f. g也即,只要t=1000时发生中断,如果中断发生在主程序判断:NH=03与NL=E8之间。则本次LED的显示,就会超出你的预期!而且t会走向65535,再回0。 |
|