|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2012-6-4 14:27:57
|
显示全部楼层
logicgreen 发表于 2012-6-3 20:40 ![](static/image/common/back.gif)
LZ读端口建议用IN W,PINA
再判断W,因为LGT读IO是异步的,所以用IN指令同步一下试试。 ...
谢谢!
听了你的建议,把那段代码,读IO的地方先读到一个寄存器,然后用sbrc/sbrs指令,而不是直接sbic/sbis。 这样居然就解决了最早困惑我的问题。 不用中断方式也很稳定,而且试了很多次都不会出现程序复位的问题。 但是一旦换成sbic/sbis来做就有问题。
由于在C里把变量用volatile 生命会导致出来的代码效率很糟,所以直接用汇编写了段代码来实现。 代码见下面。- .globl infiniteRun
- infiniteRun:
- in r24, PINA
- lds r25, pinMask
- and r24, r25
- cp r25, r24
- breq infiniteRun1
- cbi PORTD, PD1
- rjmp infiniteRun2
-
- infiniteRun1:
- sbi PORTD, PD1
- infiniteRun2:
- #ifdef NO_SBISC
- in r24, PIND
- sbrs r24, PD0
- #else
- sbis PIND, PD0
- #endif
- rjmp infiniteRun3
- in r24, PORTA
- lds r25, pinMask
- or r24, r25
- out PORTA, r24
- rjmp infiniteRun
- infiniteRun3:
- in r24, PORTA
- lds r25, pinMaskInv
- and r24, r25
- out PORTA, r24
- rjmp infiniteRun
复制代码 上面的代码,一旦宏NO_SBISC 没有定义,进入这个死循环后,工作一阵子后系统就会复位或者死机。
很奇怪,为什么在这段代码里用sbis会导致系统复位?
另外系统中还有其他地方,比如读按键状态,最终也会翻译成sbis/sbic。 这些地方用这个会不会也会导致异常呢?
如果都需要改岂不是有很多地方都得换。C语言里就不能用 PINA & 1<<PA0 之类的语句了。
(不过这个问题解决了,也证明我那段工作异常的代码 跟镊子碰引脚会引起系统复位没有关系,至少还是可以安心使用了。) |
|