项目之IC卡程序2

项目之IC卡程序2、


C51 从Keil到IAR

由于某些原因不能使用Keil编译51代码,所以转到IAR,发现很多地方不一样。

首先是sbit
IAR中不支持未定义,IAR中的位访问是通过位段的形式来实现的。所以在Keil中的sbit LED_POWER = P0^4;需要改为宏的形式:#define LED_POWER  P0_bit.pin5,而这里还需要头文件里做点修改,为了方便自己使用,我对P89V51RD2的头文件做了一点点改动:(看这个IO口的定义)
__sfr __no_init volatile union
{
  unsigned char P0; /* Port 0 */
  union{
    struct /* Port 0 */
    {
      unsigned char AD0 : 1;
      unsigned char AD1 : 1;
      unsigned char AD2 : 1;
      unsigned char AD3 : 1;
      unsigned char AD4 : 1;
      unsigned char AD5 : 1;
      unsigned char AD6 : 1;
      unsigned char AD7 : 1;
    };
    struct /* Port 0 */
    {
      unsigned char pin0 : 1;
      unsigned char pin1 : 1;
      unsigned char pin2 : 1;
      unsigned char pin3 : 1;
      unsigned char pin4 : 1;
      unsigned char pin5 : 1;
      unsigned char pin6 : 1;
      unsigned char pin7 : 1;
    };
  } P0_bit;
} @ 0x80;
增加了pin0到pin1的联合体内容,使得可以直接使用P0_bit.pinX的形式来访问,而不需要使用P0_bit.AD0的形式。

2.code和const
这个是最熟悉的,也很简单,只需要吧code关键字替换为const就行了。但是编译报错,说定义的常量数组太大,这是为什么。打开工程的option选项,首页右下角有个关于常量位置的设置,选择将常量放到代码空间即可。

3.寄存器位的访问
由于IAR中不支持直接的位访问,所以对于CY、TR0之类的寄存器位都要通过位段的形式来访问,好在51的寄存器不多。

4.中断函数的写法
在keil中,中断函数是如下形式
void Timer0_isr(void) interrupt 1
{
        //code
}
而在IAR中是这样
#pragma vector=timer0
__interrupt void Timer0_isr(void)
{
        //code
}
这里 __interrupt 表示Timer0_isr()是一个中断函数,#pragma vector 说明该中断函数的入口地址。

在IAR编译器里用关键字来__interrupt来定义一个中断函数。用#pragma vector来提供中断函数的入口地址。


#pragma vector = 0x12    //定时器0溢出中断入口地址
__interrupt void time0(void)
{
 ;
}
    上面的入口地址写成#pragma vector=TIMER0_OVF_vect更直观,每种中断的入口地址在头文件里有描述。函数名称time0可以为任意名称。中断函数会自动保护局部变量,但不会保护全局变量。

1 .内在函数也可以称为本征函数
        编译器自己编写的能够直接访问处理器底层特征的函数。在intrinsics.h中有描述完整类型在comp_a90.h里有进一步的简化书写方式

延时函数,以周期为标准
        __delay_cycles(unsigned long );
        如果处理器频率为1M,延时100us,如下:
        __delay_cycles(100 );
        当然你也可以对该函数进行修改:
        #define CPU_F 1000000
        #define delay_us (unsigned long) __delay_cycles((unsigned long )*CPU_F)
        #define delay_ms (unsigned long) __delay_cycles((unsigned long )*CPU_F/1000)

2.中断指令
   __disable_interrupt( );//插入CLI指令, 也可以用_CLI();也可以SREG_Bit7=0;
    __enable_interrupt( );// 插入SEI指令,也可以用_SEI();也可以SREG_Bit7=1;
    其实对于状态字的置位和清零只有BSET S 和BCLR S两条指令。像SEI不过是BSET 7;的另一个名字而已。AVR指令中还有很多类似的现象,如:ORI 和 SBR 指令完全一样,号称130多条指令的AVR其实没有那么多指令的。

3.从FLASH空间指定地址读取数据
__extended_load_program_memory(unsigned char __farflash *);
__load_program_memory(unsigned char __flash *);


4.乘法函数
__fracdtional_multiply_signed(signed char, signed char);
__fractional_multiply_signed_with_unsigned(signed char, unsigned char);
__fractional_multiply_unsigned(unsigned char, unsigned char);
//以上为定点小数乘法
__multiply_signed(signed char, signed char);//有符号数乘法
__multiply_signed_with_unsigned(signed char, unsigned char);
//有符号数和无符号数乘法
__multiply_unsigned(unsigned char, unsigned char);//无符号数乘法

 5.半字节交换指令
__swap_nibbles(unsigned char);

6.MCU控制指令
__no_operation();//空操作指令
_NOP();
__sleep();//休眠指令
_SLEEP();
__watchdog_reset();//看门狗清零
_WDR();








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值