|
在另一个帖子讨论到,重新开个帖子方便需要的人
---------------------------------------------------------------------------------------
手册资料:
考虑到软件能够及时获得端口信号的变化, PINA/B/C/D输入为异步设计,直接反应端口的状态。但这样的做法也同时带来了一些信号同步的问题。建议用户在直接使用端口状态进行程序流程控制时,采用必要的软件滤波算法。 同时也避免直接使用PINA/B/C/D寄存器的值进行程序流程控制,而是首先使用IN指令将其读到内部寄存器,然后使用寄存器的值作后续处理。下面将给出建议的使用端口作为程序流程控制的代码
汇编代码实例
Label:
in r16, PINA
; Skip if PINA[1] is clear, avoid to use sbic directly
sbrc r16, 1
; Skip if PINA[1] is set, avoid to use sbis directly
sbrs r16,1
…..
C语言代码实例
volatile unsigned char pv; /*volatile is necessary to disable optimize on ‘pv’ */
/* wait until PINA[1] is set */
do {
pv = PINA;
} while ((pv&0x2) != 0x02); /* avoid to use while(PINA&0x2) */
手册中提到的这个问题其实很严重,如果没有按照手册中代码写,你的程序很可能运行着就自动复位或者跑飞了。 详细原因手册没有提及。简单原因就是LGT sbic 和 sbis指令针对PINA/B/C/D这几个寄存器操作有局限性。 只有当PIN脚的电平确定,不会变化时才可以用。其它内部IO,由于电平在一个指令周期内确定,因此不受影响。
因此我们在AVR中常用的,比如说检测一个按键 if(!(PINA & 1<<PA0)){xxx} 这样的代码在LGT中就不可以使用了。需要这样:- volatile unsigned char tempPina;
- tempPina = PINA;
- if(!(PINA & 1<<PA0)){xxx}
复制代码 那个变量必须加volatile限定,不然编译器会自动忽略这个变量,直接使用sbic指令了。
但是这样写法大大降低了效率,查看反汇编会发现,多了两条指令。总共需要4条指令。 4个时钟周期,如果是AVR的话,一条sbic需要2个时钟周期,这样LGT的速度就没AVR快了。- {
- volatile unsigned char tempPina;
- tempPina = PINA;
- 9e: 80 b1 in r24, 0x00 ; 0
- a0: 89 83 std Y+1, r24 ; 0x01
- if(!(tempPina & 1<<PA0))
- a2: 89 81 ldd r24, Y+1 ; 0x01
- a4: 80 fd sbrc r24, 0
- a6: fb cf rjmp .-10 ; 0x9e <main+0xa>
复制代码 那如何改进呢。 这里提供一个方法,把PINA重新定义一下。其它端口同理。- inline unsigned char LGT_PINA()
- {
- register unsigned char temp;
- temp=PINA;
- asm volatile ("" : "+r"(temp));
- return temp;
- }
- #undef PINA
- #define PINA LGT_PINA()
复制代码 这样代码可以写的和以前AVR一样:
if(!(PINA & 1<<PA0)){xxx}
看一下反汇编效果:- inline unsigned char LGT_PINA()
- {
- register unsigned char temp;
- temp=PINA;
- 94: 80 b1 in r24, 0x00 ; 0
- int main(void)
- {
- while(1)
- {
- if(!(PINA & 1<<PA0))
- 96: 80 fd sbrc r24, 0
- 98: fd cf rjmp .-6 ; 0x94 <main>
- {
- asm("nop");
- 9a: 00 00 nop
- 9c: fb cf rjmp .-10 ; 0x94 <main>
复制代码 这样就是两条指令了。 一个 in,一个sbrc 达到跟直接写汇编一样的效果。
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|