c51單片機浮點數及其彙編程序設計

2021-01-07 電子產品世界
在單片機應用系統的數據處理過程中,經常會遇到小數的運算問題,如求解BCD的增量算式、線性化處理等。因此,需要用二進位數來表示小數。表示小數的方法一般有兩種,定點數和浮點數。定點數結構簡單,與整數的運算過程相同,運算速度快。但隨著所表示數的範圍的擴大,其位數成倍增加,給運算和存儲帶來不便,而且也不能保證相對精度不變。浮點數的結構相對複雜,但它能夠以固定的字節長度保持相對精度不變,用較少的字節表示很大的數的範圍,便於存儲和運算,在處理的數據範圍較大和要求精度較高時,採用浮點數。

浮點數的概念

本文引用地址:http://www.eepw.com.cn/article/201611/319885.htm

常用的科學計數法來表示一個十進位數如

l234.75=1.23475E3=1.23475×103

在數據很大或很小時,採用科學計數避免了在有效數字前加0來確定小數點的位置,突出了數據的有效數字的位數,簡化了數據的表示。可以認為,科學計數法就是十進位數的浮點數表示方法。

在二進位效中,也可以用類似的方法來表示一個數,如

1234.75=10011010010.11(二進位)=0.1001101001011×211

一般表達式為

N=S×2p

在這種表示方法中,數值由四個部分組成,即尾數S及符號,階碼P及符號。

在二進位中,通過定義相應字節或位來表示這四部分,就形成了二進位浮點數。二進位浮點數可以有多種不同的表示方法,下面是一種常見的三字節浮點數的格式:

其中尾數佔16位,階碼佔6位,階符佔1位,數符佔1位。階碼通常用補碼來表示。

在這種表示方法中,小數點的實際位置要由階碼來確定,而階碼又是可變的,因此稱為浮點數。

1234.75用這種格式的浮點數表示就是:

0000 1011 1001 1010 0101 1000

用十六進位表示為

1234.75=0B9A58H

-1234.75=4B9A58H

0.171875=043B00H

-0.171875=443B00H

三字節浮點數所能表示的最大值為

1×263=9.22×1018

能表示的最小數的絕對值為

0.5×2-63=5.42×10-20

其所表示的數的絕對值範圍=(5.42×10-20~9.22×1018),由此可以看到,比三字節定點數表示的數的範圍大得多。

按同樣方法可以定義一個四字節的浮點數,以滿足更高精度的需要。

規格化浮點數

同一個數用浮點數表示可以是不同的,如

1234.75=0B9A58H=0C4D2CH=0D2696H

雖然這幾種表示其數值是相同的,但其尾數的有效數字的位數不同,分別為16位、15位和14位。在運算過程中,為了最大限度地保持運算精度,應儘量增加尾數的有效位數。這就需要對浮點數進行規格化處理。

在只考慮用二進位原碼表示尾數時,尾數的最高位為l,則該浮點數為規格化浮點數。在規格化浮點數中,用尾數為0和最小階碼表示0,三字節規格化浮點數的0表示為410000H。

浮點數在運算之前和運算之後都要進行規格化,規格化過程包括以下步驟:

(1)首先判斷尾是否為0,如果為0,規格化結果為410000H;

(2)如果尾數不為0,判斷層數的最高位是否為1,如果不為1,尾數左移,階碼減1;

(3)再判斷層數的最高位是否為1,如果不為1,繼續進行規格化操作,如果為1,則規格化結束。

浮點數運算

浮點數運算包括加、減、乘、除四則運算,比較運算,開方運算,多項式運算和函數運算。其它運算都可用這些基本運算的組合來完成。本節主要介紹浮點數四則運算及其子程序。

1.浮點數的加、減運算

浮點數的運算就是求結果的尾數、數符、階碼包括階符的過程。在加、減運算中,參加運算的浮點數的階碼可能是不同的,其尾數所代表的值也是不同的。在這種情況下,尾數不能直接相加或相減,必須首先使兩個數的階相同,這一過程稱為對階。一般是讓小階向大階對齊,尾數相應右移。對階相當於算術中的小數點對齊或代數中的通分。尾數相加或相減得到了結果的尾數。數符由尾數的運算結果的符號確定。階碼就是兩個數中較大的階碼。

例1 計算132.25+69.75

解: 132.25+69.75=088444H+078B80H=088444H+0845C0H=08CA00H=202

由於兩個浮點數的階碼分別為8和7,先將加數的階碼變為8,其尾數右移1位。兩個數的階碼相同後,尾數直接相加即為和的尾數,和的尾數的最高位為1,為規格化浮點數。

例2 計算12.39-93.1

解: 12.39-93.1=04C651H-07BA33H=87A169H=-80.71

本例中被減數小於減數,差為負數,結果的數符為1。差的階碼為兩個數中較大的階碼。

2.浮點數乘法運算

如果設參加運算的兩個操作數分別表示為

Na=(-1)SSa×Sa×2Pa

Nb=(-1)SSb ×Sb×2Pb

它們的積為

N=Na×Nb=(-1)SSa+SSb×(Sa×Sb)×2Pa+Pb

式中SSa和SSb為兩個數的數符。

乘法運算可總結為:

(1)積的數符為乘數的符號位和被乘數的符號位按模2求和,即異或;

(2)積的階為乘數和被乘數的階的和;

(3)積的尾數為被乘數和乘數的尾數的積。

參加運算的浮點數一般都是規格化的浮點數,尾數的積小於1,不需進行右規格化處理。但有可能小於0.5,所以需進行左規格化處理,使積為規格化浮點數。如果乘數或被乘數的尾為0、則積為410000H。由於在尾數相乘時,積的低16位不能反映在結果中,因此,積可能會產生一定的誤差。

例3 算22.4l×4.23。

解: 22.41×4.23=05B349H×03875EH=07BD9AH=94.8

積的階為乘數和被乘數的和,即8。尾數相乘時,積小於0.5,進行左規格化處理,階碼變為7。

例4 計算2586.5×(-6.91)。

解: 2586.5×(-6.91)=0CA1BOH×83DD13H=8F8BA0H=-17872

被乘數為正數,數符為0,乘數為負數,數符為1,積的數符為0⊕1=1,積為負數。

3.浮點數的除法運算

除法運算可以表示為

N=Na/Nb=[(-1)SSa×Sa×2Pa]/[(-1)SSb×Sb×2Pb ]

=(-1)SSa-SSb×(Sa/Sb) ×2Pa-Pb

浮點數的除法運算可以總結為:

(1) 商的數符為被除數與除數的符號位的差;

(2) 商的階碼為被除數和除數的階碼的差;

(3) 商的尾數為被除數和除數的尾數的商。

規格化的浮點數進行除法運算時,尾數相除,商不會小於0.5,不需進行左規格化處理。但有可能大於1,有時需進行右規格化處理。

例5 計算390.67÷14.3l。

解: 390.67÷14.31=09C357H÷04E511H=05DA4EH=27.3

商的階碼為被除數與除數的階碼的差。尾數相除時,結果的最高位為1,商為規格化浮點數。

例6 計算 -6.02÷16.157。

解: -6.02÷16.157=83C0AAH÷058143H=FFBEC8H= -0.373

異號相除時,商為負數。由於被除數的尾數大於除數的尾數,所以被除數先進行右規格化,階碼變為4,商的階碼為 -1,用補碼來表示。

浮點數運算子程序

通過前面的分析可以看到,浮點運算比較複雜,有其特有的方法和規律。這裡介紹幾種常用的三字節浮點數運算子程序,通過分析、設計這些程序,可以進一步了解浮點數的運算過程和特點,熟悉複雜程序的設計方法。

1.浮點數通用規格化子程序

在浮點數運算過程中,有時需要左規格化,有時需要右規格化。通過規格化子程序既可實現左規格化,又可實現右規格化,其具體功能如下:

當Cy=0時,進行右規格化:F0=0時.對R6(階)R2R3(尾數)右規格化1位;F0=1時,對R7(階)R4R5(尾數)右規格化1位。

當Cy=1時,對R6(階)R3R3(尾數)執行左規格化。

程序開始時,判斷是執行左規格化還是右規格化。如果是右規格化,還要判斷是對R6(階)R2R3(尾數)還是對R7(階)R4R5(尾數)進行規格化。如果是左規格化,直至把操作數變為規格化浮點數。其程序框圖如圖4-13所示。程序為:

FSDT: JC LNORMS

MOV C, 39H ;進行右規格化

JB F0, NR7

MOV A, R2 ;R2R3右移一位

RRC A ;(Cy)移入尾數最高位

MOV R2, A

MOV A, R3

RRC A

MOV R3, A

INC R6 ;階碼加1

RET

NR7: MOV A, R4

RRC A

MOV R4, A

MOV A, R5

RRC A

MOV R5, A

INC R7

RET

LNORMS: MOV A, R7

JNZ LSHIFT

CJNE R3, #00H, LSBIT8 ;尾數為0,階碼41H

MOV R6, #41H

LSEND : RET

LSHIFT: JB ACC.7, LSEND

LSBIT8: MOV C, F0

MOV A, R3

RLC A

MOV R3, A

MOV A, R2

RLC A

MOV R2, A

CLR F0

DEC R6

SJMP LNORMS

2.浮點數加減運算子程序

參加運算的浮點數可能是正數,也可能是負數。對於加法運算.當加數和被加數的數符相同時,尾數相加,不同時尾數相減;對於減法運算,當減數和被減數的數符相同時,尾數相減、不同時尾數相加。當兩個浮點數的階碼不同時,要進行對階,使小階與大階相等,因此,結果的階碼與其較大的階碼相同。

在執行加法運算時,尾數有可能大於1,因此要進行右規格化處理;執行減法運算時,尾數有可能小於0.5,因此,要進行左規格化處理。

下面是三字節浮點數加、減法處理於程序,具體功能為:

R6(階)R2R3(尾)±R7(階)R4R5(尾)→R4(階)R2R3(尾);

當位3AH=0時,執行加法;

當位3AH=1時,執行減法。

程序框圖如圖4—14所示。程序如下:

FABP: MOV A, R6

MOV C, ACC.7

MOV 38H, C ;存被加數數符

XRL A, R7

JNB ACC.7, FAB1 ;數符相同則轉

CPL 3AH ;數符不等,求反運算標誌

圖4-14

FAB1: MOV A, R6

MOV C, ACC.6 ;擴展階碼符號位

MOV ACC.7, C

MOV R6, A

MOV A, R7

CLR C

MOV A, R6

SUBB A, R7

JZ FAB2 ;階碼相同則轉

CLR F0

JB ACC.7, FAB6

CJNE R4, #00H, FAB7

CJNE R5, #00H, FAB7

FAB2: JB 3AH, FAB9 ;轉向尾數減法

MOV A, R3 ;執行尾數加法

ADD A, R5

MOV R3, A

ADD A, R2

ADDC A, R4

MOV R2, A

JNC FAB4

SETB 39H

CLR C

FAB3: CLR F0

LCALL FSDT

FAB4: CJNE R2, #00H, FAB5

CJNE R3, #00H, FAB5

MOV R4, #41 ;結果為0,規格化

RET

FAB5: MOV A, R6

MOV C, 38H

MOV ACC.7, C

XCH A, R4

MOV R6, A

RET

FAB6: CJNE R2, #00H, FAB8

CJNE R3, #00H, FAB8

MOV A, R7

MOV R6, A

SJMP FAB2

FAB7: CPL F0

FAB8: CLR C

LCALL FSDT

SJMP FAB1

FAB9: MOV A, R3 ;尾數相減

CLR C

SUBB A, R5

MOV R3, A

MOV A, R2

SUBB A, R4

MOV R2, A

JNC FAB10

CLR A

CLR C

SUBB A, R3

MOV R3, A

CLR A

SUBB A, R2

MOV R2, A

CPL 38H

FAB10: SETB C

SJMP FAB3

3. 浮點數乘法運算子程序

浮點數相乘時,階碼直接相加即獲得積的階碼,尾數相乘時,結果可能小於0.5,需進行左規格化處理。下面是三字節浮點數乘法運算子程序,具體功能為:

(Ro)指向的三字節浮點數×(R1)指向的三字節浮點數→R4(階)R2R3(尾數)。

圖4-15三字節浮點數乘法的程序框圖。程序為:

FMUL: LCALL FMLD ;傳送浮點數

MOV A, R6 ;求積的數符

XRL A, R7

MOV C, ACC.7

MOV 38H, C

LCALL DMUL ;調用雙字節無符號數乘法子程序

MOV A, R7

MOV C, ACC.7

MOV F0, C

MOV A, @R0

ADD A, @R1

MOV R6, A

SETB C

LCALL FSDT ;進行規格化操作

圖4-15 三字節浮點數乘法子程序

MOV A, R6

MOV C, 38H

MOV ACC.7, C ;置積的數符

MOV R4, A

RET

註:(1)FMLD為浮點數取數子程序,功能為:將(R0)指向的三字節浮點數送入R6(階)R2R3(尾數)中,將(R1)指向的三字節浮點數送入R7(階)R4R5(尾數)中。

(2)DMUL為雙字節無符號數乘法子程序。

4.浮點數除法運算子程序

在進行除法運算時,被除數的尾數可能比除數的尾數大很多,使結果大於1。為避免這種情況,如果被除數尾數大於除數的尾數,先將被除數的尾數右移,使其小於除數的尾數。階碼也相應增加,保持其數值不變。下面是三字節浮點數除法運算程序,其功能為:(R0)指向的三字節浮點數除以(R1)指向的三字節浮點數→R4(階)R2R3(尾數)中。

程序框圖如圖4-16所示。程序為:

FDIV: LCALL FMLD

MOV A, R6

XRL A, R7 ;求商的數符

MOV C, ACC.7

MOV 38H, C

CLR A

MOV R6, A

MOV R7, A

CJNE R4, #00H, FDIV1

CJNE R5, #00H, FDIV1

SETB C

RET ;除數為0返回

FDIV1: MOV A, R3 ;比較被除數與

SUBB A, R5 ;除數的尾數

MOV A, R2

SUBB A, R4

JC FDIV2

CLR F0

CLR 39H

LCALL FDST

RRC A

MOV R7, A

CLR C

SJMP FDIV1

FDIV2: CLR A

XCH A, R6

PUSH ACC

LCALL DDIV ;調用雙字節除法程序

POP ACC

ADD A, @R0

CLR C

SUBB A, @R1

MOV C, 38H

MOV ACC.7, C

MOV R4, A

CLR C

RET

相關焦點

  • PIC單片機的浮點數格式及轉換
    在我們設計的儀表中採用PIC系列單片機,碰到了浮點數的運算問題,查閱其有關資料發現,其浮點數的格式及其與十進位數之間的轉換,與我們常用的MCS-51單片機所提供的三字節、四字節浮點數完全不同,本文將說明其浮點數的格式及其與十進位數之間的轉換和程序設計步驟。
  • 單片機浮點數的運算原理及表達方式
    打開APP 單片機浮點數的運算原理及表達方式 發表於 2019-04-18 15:38:39 單片機一般浮點數均採用士MxC的形式來表示
  • 單片機浮點數的實用快速除法介紹
    作為單片機程式設計師來說,在編寫程序時經常要檢驗程序中的浮點數運算結果是否正確,但手中又沒有合適的檢驗工具,非常麻煩。而一般單片機是沒有浮點數運算指令的,必須自行編制相應軟體。在進行除法計算時,通常使用的方法是比較除法,即利用循環移位和減法操作來得到24~32位商,效率很低。這裡給出一種浮點數除法運算的實用快速算法。該方法以數值計算中的預估-修正方法為指導,充分利用了16位單片機的乘除法功能,很輕易地實現了浮點數的除法。
  • 單片機彙編指令入門學習和查看
    在進行彙編程序設計時,MSP430的指令系統是程序的主體,但為了方便程序編制,還定義了一些指令,這些指令不參與和影響程序的執行,也不在計算機中運行,這類指令稱為偽指令。一般彙編器偽指令能幫助用戶完成以下事情:·將代碼和數據彙編到規定的段中·在存儲器中用未初始化的變量保留空間·控制彙編後列表文件的格式·初始化存儲器·彙編條件塊·定義全局變量·規定彙編器可以從中獲得宏的庫
  • c51單片機編程要點總結
    c51單片機編程要點總結1、頭文件:#include (我用的是 STC 89C54RD+)2、預定義
  • 單片機彙編延時程序的理解
    單片機彙編實現延遲的程序代碼:本文引用地址:http://www.eepw.com.cn/article/171019.htmDELAY:
  • PIC單片機C語言程序實例
    編者按:為了幫助具有PIC單片機彙編語言知識的技術人員或工程師,快速掌握利用C語言編寫PIC單片機程序的方法,本刊特推出《PIC單片機C語言程序設計》系列連載文章。丈中給出的C語言程序實例,均是可執行的,讀者可以放心引用。      一、彙編語言與C語言      早期的單片機程序多採用彙編語言編寫。
  • 51單片機彙編指令的記憶方法
    MCS-51使用彙編語言指令,它共有44個操作碼助記符,33種功能,其操作數有#data、direct、Rn、@Ri等。這裡先介紹指令助記符及其相關符號的記憶方法。一、助記符號的記憶方法1 表格列舉法把44個指令助記符按功能分為五類,每類列表記憶。此處從略,請讀者自己總結。
  • 四點二次插值的單片機彙編程序實現
    採用多項式插值時,若提高多項式次數,除了增加計算量(在高速實時控制的程序中,計算速度是很重要的問題)外,從數學上看還有若干缺點,故實際應用中一般不用太高的次數。拋物線插值(三點二次插值)是常用的一種。    提高精度的另一途徑是增加節點密度。對於三點二次插值,節點密度若能提高二倍,則截斷誤差大約可以縮小到原來的1/8。
  • Keil C51的一些有趣特性
    Keil C51的一些有趣特性 Keil c51號稱作為51系列單片機最好的開發環境,大家一定都很熟悉。那麼看一下下面的程序。void fun1(unsigned char i){ …} 正常情況參數i通過R7傳入函數,那麼它的實際地址在什麼地方呢?就是R7嗎?回答這個問題之前我們先來了解keil c51的幾個有趣的特性(不考慮重入函數)。
  • Proteus 與 kilec51聯機調試入門實驗
    聯機調試,可就是不行;問題是kile運行中不會出現startup.a51這個東東好鬱悶,換到3.0就行了;應該是我下的那個版本不行;今天晚上終於把聯機小實驗調通了,以後就可以全心全意的進行單片機仿真了;以下是我的實驗,至於具體Proteus 與 kilec51的具體設置,咱會在下一篇說明
  • 基於C51單片機的遙控小車設計與製版
    手動布局、布線;二、設計思路此次試驗採用基於C51單片機的遙控小車的設計。1.1、存儲器89C51 片內有 ROM(程序存儲器,只能讀)和 RAM(數據存儲器,可讀可寫) 兩類, 他們有各自獨立的存儲地址空間, 與一般微機的存儲器配置方式很不相同。1、程序存儲器(ROM) 存放程序,一些原始數據和表格。89C51 及 8751 的片內程序存儲器容量為 4KB,地址從 0000H 開始,用於存放程序和表格常數。
  • PIC單片機C語言程序設計(2)
    1.C語言的標識符  所謂標識符,實際上是一些由程序編寫者自定義的名稱,類似於PIC單片機彙編語言中給寄存器(RAM)的命名。數據是實現功能的過程,功能是數據運算(或處理)的結果,沒有數據,C程序就無法實現單片機規定的功能,可見數據在C語言程序中的重要性。  C語言的數據類型,有基本型、構造型、指針型三類。對此,筆者將在使用時逐一介紹。
  • 單片機編程軟體大佬:明確單片機編程軟體編寫單片機程序步驟
    單片機用什麼軟體編程?單片機開發中除必要的硬體外,同樣離不開軟體,我們寫的彙編語言源程序要變為CPU可以執行的機器碼有兩種方法,一種是手工彙編,另一種是機器彙編,目前已極少使用手工彙編的方法了。機器彙編是通過彙編軟體將源程序變為機器碼,用於MCS-51單片機的彙編軟體有早期的A51,隨著單片機開發技術的不斷發展,從普遍使用彙編語言到逐漸使用高級語言開發,單片機的開發軟體也在不斷發展,Keil軟體是目前最流行開發MCS-51系列單片機的軟體,這從近年來各仿真機廠商紛紛宣布全面支持Keil即可看出。
  • 單片機c語言教程:C51循環語句
    它是 一個無條件的轉向語句,只要執行到這個語句,程序指針就會跳轉到 goto 後的標號所在的 程序段。它的語法如下:goto 語句標號; 其中的語句標號為一個帶冒號的標識符。這段程序的意思是在程序開始處用標識符「start:」標識,表示程序這是程序的開始,「end:」標識程序的 結束,標識符的定義應遵循前面所講的標識符定義原則,不能用 C 的關鍵字也不能和其它變 量和函數名相同,不然就會出錯了。程序執行 a++,a 的值加 1,當 a 等於 10 時程序會跳到 end 標識處結束程序,不然跳回到 start 標識處繼續 a++,直到 a 等於 10。
  • STC12C2052單片機製作數字電壓表彙編程序
    用STC12C2052單片機晶片自帶的ad進行採樣得到電壓並顯示在數碼管上面,下面是彙編語言源程序:;===================數字電壓表模擬採樣===================================
  • 談談51單片機延時子程序
    延時程序在單片機編程中使用非常廣泛,但一些讀者在學習中不知道延時程序怎麼編程,不知道機器周期和指令周期的區別,不知道延時程序指令的用法, ,本文就此問題從延時程序的基本概念、機器周期和指本文引用地址:http://www.eepw.com.cn/article/201611/321877.htm令周期的區別和聯繫
  • 用C51編寫單片機延時函數
    參考了51單片機 Keil C 延時程序的簡單研究,自己也親身測試和計算了一些已有的延時函數。這裡假定單片機是時鐘頻率為12MHz,則一個機器周期為:1us.
  • 單片機c語言教程:C51運算符和表達式
    這個語句就是 typedef,這是個很好用的語句,但我卻不常用它,通常我定義變量的數據類型時都是使 用標準的關鍵字,這樣別人能很方便的研讀你的程序。如果你是個DELPHI 編程愛好者或是DELPHI程式設計師,你對變量的定義也許習慣了DELPHI 的關鍵字,如 int 類型常會用關鍵字Integer來定義,在用 單片機c語言時你還想用回這個的話,你能這樣寫:本文引用地址:http://www.eepw.com.cn/article/170888.htmtypedef int integer;
  • 基於單片機的ADC0809數字電壓表設計報告(彙編語言)
    1.5 設計方案硬體電路設計由6個部分組成; A/D轉換電路,STC89C51單片機、LED顯示系統、時鐘電路、復位電路以及測量電壓輸入電路。硬體電路設計框圖如圖1.1所示。當振蕩器工作時,RST引腳出現兩個機器周期以上高電平將使單片機復位。圖2.1 單片機引腳圖EA/VPP:外部訪問允許。欲使CPU僅訪問外部程序存儲器(地址為0000H-FFFFH ) 。 EA端必須保持低電平(接地)。需注意的是:如果加密位LB1被編程,復位時內部會鎖存EA端狀態。  如EA端為高電平(接VCC端),CPU則執行內部程序存儲器中的指令。