在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > AVR起步教程:從51到AVR編程篇

            AVR起步教程:從51到AVR編程篇

            作者: 時間:2016-10-07 來源:網(wǎng)絡(luò) 收藏

              本文介紹了在匯編編程上的移植

            本文引用地址:http://www.biyoush.com/article/201610/310916.htm

              一、DPTR的處理

              在系統(tǒng)中,DPTR是十分重要的,可以通過DPTR尋址,臨時儲存16位數(shù)據(jù)等等,下面僅僅先介紹2種51到程序移植中DPTR的處理:

              (1)DPTR直接尋址

              例子: 51程序如下:

              MOV DPTR,#8000H;

              MOVX A,@DPTR;

              這個移植起來就比較簡單了,我們現(xiàn)在選用Z寄存器(R30,R31)作為DPTR,這個里不考慮實際地址的偏移,地址設(shè)為0x1100對應(yīng)0x8000

              ldi r30,0x00

              ldi r31,0x11

              ld r24,z

              (2)DPTR變址尋址

              類似的,51的變址尋址也是一樣的

              MOV DPTR,#8000H

              MOV A,#05H

              MOVX A,@A+DPTR

              中可以移植成:

              ldi r30,0x00

              ldi r31,0x11

              adiw r30,0x05

              ld r24,z

              (3)DPTR與P2結(jié)合

              這種尋址方式在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是十進(jìn)制調(diào)整指令,具體的功能是對BCD碼加法運算的結(jié)果進(jìn)行有條件的修正,操作依據(jù)為:

              若(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的數(shù)字是0A,那么就給這個數(shù)字加上0x06,使之成為0x10,現(xiàn)在的0x10就代表了十進(jìn)制的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寄存器中的內(nèi)容

              三、PSW中P的處理

              51中,如果A中1的個數(shù)為奇數(shù),則P置位,反之則置0。在一些老的程序中,特別是有使用一種模擬老式紙帶傳輸?shù)某绦?,P就用來檢測數(shù)據(jù)傳輸?shù)恼_于否!

              在AVR中,我們可以用3中方式來做:

              (1)、查表:

              我們可以把0到255中的數(shù)字的做個表,然后去查表確定A中的數(shù)字1的P值,顯然,不管做偶數(shù)表或者奇數(shù)的表,內(nèi)存的消耗和時鐘的消耗是難以讓人忍受的

              (2)、數(shù)數(shù):

              既然查表在大多時候不可取,那么讓我們來數(shù)數(shù),我們把A拆分開來,一位一位去數(shù)

              我們還是嵌入?yún)R編去解決

              #define u08 unsigned char

              u08 A,B;

              u08 CalcP(void)

              {

              asm volatile

              (

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

              "clc" "nt" //清C標(biāo)志

              "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,0x01" "nt" //tmp &= 0x01

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

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

              );

              return tmp;

              }

              這個方法中,我們加上return共花了22條指令,比起查表而言,已經(jīng)是省了很多時鐘和內(nèi)存單元了。

              (3)、算法:

              還有比數(shù)數(shù)還精簡的代碼嗎?當(dāng)然有,雖然精簡的不多:)

              我們知道,異或的法則是11為0,00為,10和01為1,這個方法的算法就是使用了異或來做的的,我們以0xA1這個數(shù)來做例子

              #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,0x03""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,0x01 ""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條指令。



            關(guān)鍵詞: 51 AVR

            評論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉