|
本帖最后由 neo 于 2014-5-3 09:07 编辑
CVAVR下的程序
- #include <mega16.h>
- #define LED PORTA.4
- void main( void )
- {
- DDRA=0x10;
- LED=0;
- }
复制代码
对应的反汇编
- --- 无源文件 -----------------------------------------------------------------------
- --- C:\Users\AX\Desktop\avr_test2\main.c ---------------------------------------
- DDRA=0x10;
- 00000048 LDI R30,0x10 Load immediate
- 00000049 OUT 0x1A,R30 Out to I/O location
- LED=0;
- 0000004A CBI 0x1B,4 Clear bit in I/O register
- --- 无源文件 -----------------------------------------------------------------------
- 0000004B RJMP PC-0x0000 Relative jump
- 0000004C NOP Undefined
- 0000004D NOP Undefined
复制代码 在winAVR里没有和CVAVR里同样的位操作指令,在网上看到一篇帖子WINAVR中avr单片机的位操作 其中提到了位域的方法,从C编写的角度看该方法和CVAVR里的比较类似,对应的C代码如下:
- #include<avr/io.h>
- // 定义一个寄存器(Register)或端口(Port)的八个位
- typedef struct _bit_struct
- {
- unsigned char bit0:1 ;
- unsigned char bit1:1 ;
- unsigned char bit2:1 ;
- unsigned char bit3:1 ;
- unsigned char bit4: 1 ;
- unsigned char bit5: 1 ;
- unsigned char bit6: 1 ;
- unsigned char bit7: 1 ;
- }bit_field;
- //定义一个宏,用来得到每一位的值
- #define GET_BITFIELD(addr) (*((volatile bit_field *) (addr)))
- //定义每一个位
- #define LED GET_BITFIELD(PORTA).bit4
- int main( void )
- {
- DDRA=0x10;
- LED=0;
- return 0;
- }
复制代码 其反汇编如下:
- --- C:\Users\AX\Desktop\avr_test/main.c ----------------------------------------
- {
- DDRA=0x10;
- 00000036 LDI R24,0x10 Load immediate
- 00000037 OUT 0x1A,R24 Out to I/O location
- LED=0;
- 00000038 IN R30,0x1B In from I/O location
- 00000039 LDI R31,0x00 Load immediate
- 0000003A LDD R24,Z+0 Load indirect with displacement
- 0000003B ANDI R24,0xEF Logical AND with immediate
- 0000003C STD Z+0,R24 Store indirect with displacement
- }
- 0000003D LDI R24,0x00 Load immediate
- 0000003E LDI R25,0x00 Load immediate
- 0000003F RET Subroutine return
- --- 无源文件 -----------------------------------------------------------------------
- 00000040 CLI Global Interrupt Disable
- 00000041 RJMP PC-0x0000 Relative jump
-
复制代码
从中可见CVAVR使用的是CBI指令对PORTA.4进行操作。WINAVR位域的方法是使用掩码的间接实现方法对PORTA.4进行操作,共使用了5条指令,代码效率不高。
CVAVR这种PORTA.x这种赋值方法有一大好处就是可以实现如下的定义
当LED点灯电路使用的是OC接法时
- #define OFF 1
- #define ON 0
- #define LED PORTA.4
复制代码
如果LED电路是直接高电平驱动则定义
- #define OFF 0
- #define ON 1
- #define LED PORTA.4
复制代码
对应的点亮部分只需执行LED=ON就可以了,不必要关心硬件电路究竟如何,这样就非常方便硬件的调试。不知WinAVR里有没有类似的方法。
1、C接口友好。
2、直接使用SBI CBI对端口位操作。
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|