您的位置 首页 系统

AVR起步教程:从51到AVR编程篇

本文介绍了51和AVR在汇编编程上的移植一、DPTR的处理在51系统中,DPTR是十分重要的,51可以通过DPTR寻址,临时储存16位数据等等,下面仅仅先介绍2种51到AVR程序移

  本文介绍了51AVR在汇编编程上的移植

  一、DPTR的处理

  在51体系中,DPTR是十分重要的,51能够经过DPTR寻址,暂时贮存16位数据等等,下面只是先介绍2种51到AVR程序移植中DPTR的处理:

  (1)DPTR直接寻址

  比如: 51程序如下:

  MOV DPTR,#8000H;

  MOVX A,@DPTR;

  这个移植起来就比较简单了,咱们现在选用Z寄存器(R30,R31)作为DPTR,这个里不考虑实践地址的偏移,地址设为0x1100对应0x8000

  ldi r30,0x00

  ldi r31,0x11

  ld r24,z

  (2)DPTR变址寻址

  相似的,51的变址寻址也是相同的

  MOV DPTR,#8000H

  MOV A,#05H

  MOVX A,@A+DPTR

  AVR中能够移植成:

  ldi r30,0x00

  ldi r31,0x11

  adiw r30,0x05

  ld r24,z

  (3)DPTR与P2结合

  这种寻址办法在51中也较为常用

  MOV DPTR,#8100H

  MOV P2,#81H

  MOV R0,#10H

  MOVX A,@R0

  INC R0

  MOVX A,@R0

  这种寻址办法的时分,寻址的规模约束在了0x8100到0x81FF之间

  AVR中能够移植如下:

  ldi r31,0x11

  ldi r30,0X10

  lz r24,z

  inc r30

  lz r24,z

  二、DA的处理

  DA是十进制调整指令,详细的功用是对BCD码加法运算的成果进行有条件的批改,操作根据为:

  若(A)3~0>9∨(AC)=1,则A3~0←(A)3~0+6

  若(A)7~4>9∨(C)=1,则A7~4←(A)7~4+6

  若(A)7~4=9∧(A)3~0>9,则A7~4←(A)7~4+6

  举比如来说,假如DA的数字是0A,那么就给这个数字加上0x06,使之成为0x10,现在的0x10就代表了十进制的10了,

  #define u08 unsigned char

  u08 A,C

  void DA(void)

  {

  u08 tmp;

  tmp = A & 0x0F;

  if( tmp > 0x09 C & 0x20)

  A += 0x06;

  tmp = A & 0xF0;

  if( tmp > 0x90 C & 0x01)

  {

  A += 0x60;

  asm("sec");

  C = SREG;

  }

  tmp = A & 0xF0;

  if( tmp == 0x90)

  {

  tmp = A & 0x0F;

  if(tmp>0x09)

  {

  A += 0x60;

  asm("sec");

  C = SREG;

  }

  }

  }

  代码中的C便是SREG寄存器中的内容

  三、PSW中P的处理

  51中,假如A中1的个数为奇数,则P置位,反之则置0。在一些老的程序中,特别是有运用一种模仿旧式纸带传输的程序,P就用来检测数据传输的正确于否!

  在AVR中,咱们能够用3中办法来做:

  (1)、查表:

  咱们能够把0到255中的数字的做个表,然后去查表确认A中的数字1的P值,明显,不论做偶数表或许奇数的表,内存的耗费和时钟的耗费是难以让人忍耐的

  (2)、数数:

  已然查表在大多时分不可取,那么让咱们来数数,咱们把A拆分开来,一位一位去数

  咱们仍是嵌入汇编去处理

  #define u08 unsigned char

  u08 A,B;

  u08 CalcP(void)

  {

  asm volatile

  (

  "mov %0,%2" "nt" //保存A

  "clc" "nt" //清C标志

  "eor r1,r1" "nt"

  "mov %1,r1" "nt"

  "lsr %0" "nt"

  "adc %1,r1" "nt" //算了第一位

  "lsr %0" "nt"

  "adc %1,r1" "nt" //算了第二位

  "lsr %0" "nt"

  "adc %1,r1" "nt" //算了第三位

  "lsr %0" "nt"

  "adc %1,r1" "nt" //算了第四位

  "lsr %0" "nt"

  "adc %1,r1" "nt" //算了第五位

  "lsr %0" "nt"

  "adc %1,r1" "nt" //算了第六位

  "lsr %0" "nt"

  "adc %1,r1" "nt" //算了第七位

  "lsr %0" "nt"

  "adc %1,r1" "nt" //算了第八位

  "andi %1,0×01" "nt" //tmp &= 0x01

  : "=d" (B),"=d" (tmp),"=d" (A)

  : "0" (B),"1" (tmp),"2" (A)

  );

  return tmp;

  }

  这个办法中,咱们加上return共花了22条指令,比起查表而言,已经是省了许多时钟和内存单元了。

  (3)、算法:

  还有比数数还精简的代码吗?当然有,尽管精简的不多:)

  咱们知道,异或的法则是11为0,00为,10和01为1,这个办法的算法便是运用了异或来做的的,咱们以0xA1这个数来做比如

  #define u08 unsigned char

  u08 AvrCalcP(u08 Data)

  {

  u08 tmp1,tmp2;

  asm volatile

  (

  "mov %1,%0""nt" //tmp1 = 0xA1 1010 0001

  "swap %1""nt" //tmp1 = 0x1A 0001 1010

  "eor %1,%0""nt" //tmp1 = 0xBB 1011 1011

  "andi %1,0x0f""nt" //tmp1 = 0x0B 0000 1011

  "mov %2,%1""nt" //tmp2 = 0x0B

  "andi %2,0×03""nt" //tmp2 = 0x03 0000 0011

  "lsl %1""nt"

  "lsl %1""nt" //tmp1 = 0x02 0000 0010

  "eor %1,%2""nt" //tmp1 = 0x01 0000 0001

  "mov %2,%1""nt" //tmp2 = 0x01

  "andi %2,0×01 ""nt" //tmp2 = 0x01 0000 0001

  "lsl %1""nt" //tmp1 = 0x00 0000 0000

  "eor %1,%2 ""nt" //tmp1 = 0x00 0000 0001

  "andi %1,0x0f""nt" //tmp1 = 0x01

  : "=d" (Data),"=d" (tmp1),"=d" (tmp2)

  : "0" (Data),"1" (tmp1),"2" (tmp2)

  );

  return tmp1;

  }

  这个办法中,咱们加上return共花了15条指令,比办法2来讲,又省了7条指令。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/xitong/298523.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部