|
$ G$ S3 W/ |8 p
如果你了解汇编语句,会对你的理解有帮助。所以不懂汇编是不能称为精通单片机的。
& b0 ?5 W) M# o* a# Z* ^C语言t=1000中的t,在CPU中必须用两个字节来表示,不妨起个名子叫NH和NL。t=NH,NL
" d% s4 H I: |' c你的主程序一直在等t=1000,也就等(NH,NL,16进制)=03E8H,但是CPU指令只能一个一个的判断,假设先判断NH=03,而后再判断NL=E8,逻辑上是没有毛病的。" F% t' w, ]& f8 I+ b, [- j7 H
你的中断是每1ms一次,中断发生时,你的程序运行到什么地方了呢?不太好确定吧,你的程序一直在等t=1000,估计多半会在此处中断。
; w: q1 K! U9 T( \# V注意,有个关键的特殊事件发生了,而且发生的概率还不了(程序不长)。
2 X( B: R8 b' F6 J8 t$ u- a中断发生在CPU已判断了NH,还未判定NL。而中断服务程序会做t++,也即(NH,NL)+1,这就修改NL的值,问题来了。
. ?' f4 ^# j$ K$ @0 r+ J0 s1 k例如:原先(NH,NL)=1000 = 03E8H,程序已确定NH=03,如果NL=E8,就反转LED灯。/ e3 m1 c* x% S, j9 K+ h$ C2 M
但是中断发生在NH=03判断之后,而NL还未判定,中断时你将t++,也即(NH,NL)++,变成了 03E9H,中断返回后,再判断NL却不是E8,而是E9了。
& j0 |8 Y- O7 z; V/ h如此,程序不会再做LED反转了。t将=1001,此后被加到65535,再回0,下次再加到1000。3 ?5 y4 y/ S1 k: g5 j
也即,只要t=1000时发生中断,如果中断发生在主程序判断:NH=03与NL=E8之间。则本次LED的显示,就会超出你的预期!而且t会走向65535,再回0。 |
|