1. 單片機如何寫絕對值語句
單片機如何寫絕對值語如下說明。
C語言abs()函數用於求整數的絕對值。fabs()函數用於求雙精度浮點數的絕對值。abs() 數調用添加頭文件math.h或者stdlib.h,fabs()函數調用添加頭文件math.h。
1,#include<stdio.h>。
2,#include<math.h>。
3,int main()。
4,{ int a = -3, b。
5,float c=-5.2, d,e。 //為變數賦初值。
6,b = abs(a)。 //求a的絕對值。
7,d = abs(c)。 //求b的絕對值。
8,e=fabs(c-a)。
9,printf("%d %d ", c, d)。
10,return 0}。
當前的單片機種類很多,但是51是最基礎的,因此單片機的學習最好也是從51開始,不僅容易上手,而且相當實用。然而51單片機畢竟過於基礎,後來的很多單片機在功能上都有很大的擴展,因此按照我們實驗室多數人的路線接下來大多數人會學習AVR單片機, AVR單片機在功能上較51有很大提升,集成了AD,快速PWM等很多實用的功能,而且和很多大型的單片機在功能上有很多類似之處,因此如果以後還想掌握其他單片機AVR無疑是一個很好的跳板。現在因收購的原因可以學微芯的單片機。
學習單片機最終要的是當然是練,我所說的學習跟課堂上的單片機學習不同,我以前也看過一些單片機教材,有些教材講的是單片機的工作原理和內部結構,這些東西對於我們暫時並不需要,等以後開課的時候在學習好了。現在要學習的是暫時拋開內部結構原理不談,如何能用單片機寫一些簡單的小程序,是從實用性的角度出發,先實踐後理論的學習方法,最主要是培養興趣。
2. 51單片機中,兩數相減得負的程序怎麼寫
51單片機中兩數相減得負,那麼借位C為1,所以減運算後判斷C就可以得出結論了。
3. 氣體感測器怎麼接到51單片機上以TGS4160為例~~
二氧化碳感測器TGS4160中文資料
TGS4160是FIGARO(弗加邏)公司生產的一種固態電化學型二氧化碳(CO2)感測器,該器件除具有體積小、壽命長、選擇性和穩定性好等特性外,同時還具有耐高濕和耐低溫等特點。因而可廣泛用於自動通風換氣系統或CO2氣體的長期監測等應用場合。文中敘述了該感測器的內部結構和工作原理,給出了一個用TGS4160設計的專用模塊的基本應用電路原理圖。
1.TGS4160概述
TGS4160二氧化碳感測器是FIGARO(弗加羅)公司生產的固態電化學型氣體敏感元件。這種二氧化碳感測器除具有體積小、壽命長、選擇性和穩定性好等特點外,同時還具有耐高濕低溫的特性
可廣泛用於自動通風換氣系統或是CO2氣體的長期監測等應用場合。但是,由於TGS4160的預熱時間較長(一般為2小時),所以,該器件比較適合於在室溫下長時間通電連續工作。此外,為了方便客戶使用,FI-GARO公司還專門設計了帶溫度補償的感測器處理模塊AM-4。該模塊採用微處理器進行控制,CO2氣體濃度的輸出信號電平為0.0~3.0V,相當於0~3000ppm的濃度,並有中繼轉接控制口,可輸出高、低兩種門限信號以供外接控制使用。TGS4160感測器的主要技術參數如下:
●測量范圍:0~5000ppm;
●使用壽命:2000天;
●加熱器電壓:5.0±0.2VDC;
●加熱器電流:250mA;
●加熱器功耗:1.25W;
●內部熱敏電阻(補償用):100kΩ±5%;
●使用溫度:-10~+50℃
●使用濕度:5~95%RH;
●產品尺寸:最大外徑Φ24mm,高24mm,引腳長5.8mm。
2.TGS4160內部結構
TGS4160二氧化碳感測器是一種內含熱敏電阻的混合式CO2敏感元件。該元件在兩個電極之間充有陽離子固體電解質。它的陰極由鋰碳酸鹽和鍍金材料製成,而陽極只是鍍金材料。該敏感元件的基襯是用對苯二酯聚乙烯和玻璃纖維加固,然後採用不銹鋼網做圓柱型封裝。元件的內層採用100目雙層不銹鋼網套在鍍鎳銅環上,並用高強度樹脂粘合劑與基襯固定在一起。其外層頂蓋上又罩上了一層60目的不銹鋼網。為了達到降低干擾氣體影響的目的,TGS4160在內外兩層不銹鋼網之間還填充有吸附材料(沸石)。感測器的6個引腳通過0.1mm的箔導線與內部相連。其等效的內部結構見圖1所示。圖中,陽極與感測器的第3腳S(+)相連,陰極與感測器的第4腳S(-)相連,Pt加熱器與感測器的第1,6腳相連,內部熱敏電阻與感測器的第2,5腳相連。內部熱敏電阻的作用是通過該電阻探測環境溫度,以便對該感測器進行溫度補償,從而使校正後的測量值更加准確。
3.TGS4160工作原理
TGS4160型CO2感測器是一種電化學型氣體的敏感元件,當該元件暴露在CO2氣體環境中時,就會產生電化學反應。其反應式如下:
陰極反應方程:
4Li++2CO2+O2+4e-=2Li2CO3
陽極反應方程:
4Na++O2+4e-=2Na2O
總的化學反應方程:
Li2CO3+2Na+=Na2O+2Li++CO2
作為電化學反應的結果,根據耐斯特方程(Nernst),該過程將產生如下電勢(EMF):
EMF=Ec-(RF)/(2F)ln(PCO2)
式中:PCO2為CO2的分壓;Ec為常數;R是氣體常數;T為溫度值(K);F是法拉第常數。
從上式看出,通過監測S(+)、S(-)兩個電極之間所產生的電勢值EMF,就可以測量CO2的濃度值。為了使該感測器保持在最敏感的溫度上,一般需要給加熱器提供加熱電壓進行加熱,但加熱電壓的變化將直接影響感測器的穩定性,因此加熱電壓必須穩定,其范圍應在5.0±0.2VDC之內。為了保證CO2的准確測量,除了保證加熱電壓穩定及對環境溫度的變化進行溫度補償外,更主要的是要測量兩電極之間變化的電勢值ΔEMF,而不是絕對電勢值EMF,因為ΔEMF與CO2濃度變化之間有一個較好的線性關系。雖然EMF絕對值隨環境溫度的上升而上升,ΔEMF卻保持常量,而且它在-10℃~+50℃溫度范圍內,基本不受溫度的影響。
ΔEMF值可由下式求得:
ΔEMF=EMF1-EMF2
其中,EMF1為350ppm的CO2中的EMF值;EMF2為所測量的CO2的EMF值。
在溫度為20℃±2℃、濕度為65±5%RH、加熱電壓為5.0±0.05VDC、預熱時間為7天或大於7天的條件下,測得感測器在濃度為350ppm中的EMF值是220~490mV,而ΔEMF在350~3500ppm的CO2濃度中的值是44~72mV,因此在實際測量應用電路中,要根據感測器的特點要求,除使用高輸入阻抗(≥100GΩ)、低偏置電流(≤1pA)的運算放大器外,還要對測得的信號進行處理。處理該信號通常有兩種方案可供選擇:一是使用費加羅(FIGARO)公司的FIC98646專用處理器模塊,二是選用其它型號的單片機並通過自己編程進行信號處理。
4.TGS4160應用電路
利用TGS4160感測器並通過高輸入阻抗、低偏置電流的運放進行放大,再作一些簡單的運算處理,就可以在CO2濃度為300~5000ppm的范圍內測得信號,該信號為0~幾百毫伏的電壓信號,可以供高精度A/D采樣使用。如果使用費加羅(FIGARO)公司提供的AM-4CO2感測器模塊,則可直接應用於自動通風換氣系統或是CO2氣體監測。該模塊內部帶有A/D轉換器,並已對數據進行了采樣並作了處理。它輸出的電壓信號與CO2濃度值呈線性關系,輸出的電壓信號為0~3.0V,相當於0~3000ppm的CO2濃度。另外,該模塊還提供有中繼轉接控制信號。當CO2濃度高於設定值時,輸出的轉接控制信號為高電平5V,該信號可以使得紅LED點亮;反之,它將轉接控制信號為低電平0V以使綠LED點亮。但是,該模塊的設定值是分檔的,而不是連續可調的。共分為四檔(可通過線路板上的跳線來實現),表1和表2分別給出了門限開關信號的濃度值及跳線連接方法。AM-4模塊的實用電路原理圖見圖2所示。
點擊看原圖
表1門限信號濃度
控制信號門限
檔次 開 關
Ⅰ 800ppm 720ppm
Ⅱ 1000ppm 900ppm
Ⅲ 1500ppm 1350ppm
Ⅳ 2000ppm 1800ppm
表2跳線連接
連接方式
檔次 JP5 JP6 JP7 JP8
Ⅰ 連 連 連 斷
Ⅱ 連 連 斷 連
Ⅲ 連 斷 連 連
Ⅳ 斷 連 連 連
如果認為使用AM-4模塊不方便或是認為價格太高,也可以自行設計電路,並自行編寫程序進行處理。
5結束語
TGS4160型CO2感測器特別適合於連續監測CO2的場所,它不需斷電,其穩定性好。但TGS4160感測器不適於做攜帶型或手持式CO2測量儀器。因為預熱時間太長,不能即時測量,同時感測器的功率也較大。此外,感測器暴露在某些氣體中(如氯氣)會降低靈敏度,由於沸石可以對某些干擾氣體(如乙醇)加以濾除。因此,不用時可置於乾燥劑中,並用專用袋進行密封。
4. 51單片機做科學計算器的c語言程序
給些子程序吧
好的就加分,其實我也是收藏別人的
嵌入式系統>51單片機浮點運運算元程序庫
1: FSDT 功能:浮點數格式化
2: FADD 功能:浮點數加法
3: FSUB 功能:浮點數減法
4: FMUL 功能:浮點數乘法
5: FDIV 功能:浮點數除法
6: FCLR 功能:浮點數清零
7: FZER 功能:浮點數判零
8: FMOV 功能:浮點數傳送
9: FPUS 功能:浮點數壓棧
10: FPOP 功能:浮點數出棧
11: FCMP 功能:浮點數代數值比較不影響待比較操作數
12: FABS 功能:浮點絕對值函數
13: FSGN 功能:浮點符號函數
14: FINT 功能:浮點取整函數
15: FRCP 功能:浮點倒數函數
16: FSQU 功能:浮點數平方
17: FSQR 功能:浮點數開平方快速逼近演算法
18: FPLN 功能:浮點數多項式計算
19: FLOG 功能:以10為底的浮點對數函數
20: FLN 功能:以e為底的浮點對數函數
21: FE10 功能:以10為底的浮點指數函數
22: FEXP 功能:以e為底的浮點指數函數
23: FE2 功能:以2為底的浮點指數函數
24: DTOF 功能:雙位元組十六進制定點數轉換成格式化浮點數
25: FTOD 功能:格式化浮點數轉換成雙位元組定點數
26: BTOF 功能:浮點BCD碼轉換成格式化浮點數
27: FTOB 功能:格式化浮點數轉換成浮點BCD碼
28: FCOS 功能:浮點餘弦函數
29: FSIN 功能:浮點正弦函數
30: FATN 功能:浮點反正切函數
31: RTOD 功能:浮點弧度數轉換成浮點度數
32: DTOR 功能:浮點度數轉換成浮點弧度數
為便於讀者使用本程序庫,先將有關約定說明如下:
1.雙位元組定點操作數:用[R0]或[R1]來表示存放在由R0或R1指示的連續單元中的數據,地址小的單元存放高位元組?如果[R0]=1234H,若(R0)=30H,則(30H)=12H,(31H)=34H?
2.二進制浮點操作數:用三個位元組表示,第一個位元組的最高位為數符,其餘七位為階碼(補碼形式),第二位元組為尾數的高位元組,第三位元組為尾數的低位元組,尾數用雙位元組純小數(原碼)來表示?當尾數的最高位為1時,便稱為規格化浮點數,簡稱操作數?在程序說明中,也用[R0]或[R1]來表示R0或R1指示的浮點操作數,例如:當[R0]=-6.000時,則二進制浮點數表示為83C000H?若(R0)=30H,則(30H)=83H,(31H)=0C0H,(32H)=00H?
3.十進制浮點操作數:用三個位元組表示,第一個位元組的最高位為數符,其餘七位為階碼(二進制補碼形式),第二位元組為尾數的高位元組,第三位元組為尾數的低位元組,尾數用雙位元組BCD碼純小數(原碼)來表示?當十進制數的絕對值大於1時,階碼就等於整數部分的位數,如 876.5 的階碼是03H,-876.5 的階碼是 83H;當十進制數的絕對值小於1時,階碼就等於 80H 減去小數點後面零的個數,例如 0.00382 的階碼是 7EH,-0.00382的階碼是 0FEH?在程序說明中,用[R0]或[R1]來表示R0或R1指示的十進制浮點操作數?例如有一個十進制浮點操作數存放在30H?31H?32H中,數值是 -0.07315,即-0.7315乘以10的-1次方,則(30H)=0FFH,31H=73H,(32H)=15H?若用[R0]來指向它,則應使(R0)=30H?
4.運算精度:單次定點運算精度為結果最低位的當量值;單次二進制浮點算術運算的精度優於十萬分之三;單次二進制浮點超越函數運算的精度優於萬分之一;BCD碼浮點數本身的精度比較低(萬分之一到千分之一),不宜作為運算的操作數,僅用於輸入或輸出時的數制轉換?不管那種數據格式,隨著連續運算的次數增加,精度都會下降?
5.工作區:數據工作區固定在A?B?R2~R7,數符或標志工作區固定在PSW和23H單元(位1CH~1FH)?在浮點系統中,R2?R3?R4和位1FH為第一工作區,R5?R6?R7和位1EH為第二工作區?用戶只要不在工作區中存放無關的或非消耗性的信息,程序就具有較好的透明性?
6.子程序調用範例:由於本程序庫特別注意了各子程序介面的相容性,很容易採用積木方式(或流水線方式)完成一個公式的計算?以浮點運算為例:
計算 y = Ln √ | Sin (ab/c+d) |
已知:a=-123.4;b=0.7577;c=56.34;d=1.276; 它們分別存放在30H?33H?36H?39H開始的連續三個單元中?用BCD碼浮點數表示時,分別為a=831234H;b=007577H;c=025634H;d=011276H?
求解過程:通過調用BTOF子程序,將各變數轉換成二進制浮點操作數,再進行各
種運算,最後調用FTOB子程序,還原成十進制形式,供輸出使用?程序如下:
TEST: MOV R0,#39H ;指向BCD碼浮點操作數d
LCALL BTOF ;將其轉換成二進制浮點操作數
MOV R0,#36H ;指向BCD碼浮點操作數c
LCALL BTOF ;將其轉換成二進制浮點操作數
MOV R0,#33H ;指向BCD碼浮點操作數b
LCALL BTOF ;將其轉換成二進制浮點操作數
MOV R0,#30H ;指向BCD碼浮點操作數a
LCALL BTOF ;將其轉換成二進制浮點操作數
MOV R1,#33H ;指向二進制浮點操作數b
LCALL FMUL ;進行浮點乘法運算
MOV R1,#36H ;指向二進制浮點操作數c
LCALL FDIV ;進行浮點除法運算
MOV R1,#39H ;指向二進制浮點操作數d
LCALL FADD ;進行浮點加法運算
LCALL FSIN ;進行浮點正弦運算
LCALL FABS ;進行浮點絕對值運算
LCALL FSQR ;進行浮點開平方運算
LCALL FLN ;進行浮點對數運算
LCALL FTOB ;將結果轉換成BCD碼浮點數
STOP: LJMP STOP
END
運行結果,[R0]=804915H,即y=-0.4915,比較精確的結果應該是-0.491437?
(1) 標號: FSDT 功能:浮點數格式化
入口條件:待格式化浮點操作數在[R0]中?
出口信息:已格式化浮點操作數仍在[R0]中?
影響資源:PSW?A?R2?R3?R4?位1FH 堆棧需求: 6位元組
FSDT: LCALL MVR0 ;將待格式化操作數傳送到第一工作區中
LCALL RLN ;通過左規完成格式化
LJMP MOV0 ;將已格式化浮點操作數傳回到[R0]中
(2) 標號: FADD 功能:浮點數加法
入口條件:被加數在[R0]中,加數在[R1]中?
出口信息:OV=0時,和仍在[R0]中,OV=1時,溢出?
影響資源:PSW?A?B?R2~R7?位1EH?1FH 堆棧需求: 6位元組
FADD: CLR F0 ;設立加法標志
SJMP AS ;計算代數和
(3) 標號: FSUB 功能:浮點數減法
入口條件:被減數在[R0]中,減數在[R1]中?
出口信息:OV=0時,差仍在[R0]中,OV=1時,溢出?
影響資源:PSW?A?B?R2~R7?位1EH?1FH 堆棧需求:6位元組
FSUB: SETB F0 ;設立減法標志
AS: LCALL MVR1 ;計算代數和?先將[R1]傳送到第二工作區
MOV C,F0 ;用加減標志來校正第二操作數的有效符號
RRC A
XRL A,@R1
MOV C,ACC.7
ASN: MOV 1EH,C ;將第二操作數的有效符號存入位1EH中
XRL A,@R0 ;與第一操作數的符號比較
RLC A
MOV F0,C ;保存比較結果
LCALL MVR0 ;將[R0]傳送到第一工作區中
LCALL AS1 ;在工作寄存器中完成代數運算
MOV0: INC R0 ;將結果傳回到[R0]中的子程序入口
INC R0
MOV A,R4 ;傳回尾數的低位元組
MOV @R0,A
DEC R0
MOV A,R3 ;傳回尾數的高位元組
MOV @R0,A
DEC R0
MOV A,R2 ;取結果的階碼
MOV C,1FH ;取結果的數符
MOV ACC.7,C ;拼入階碼中
MOV @R0,A
CLR ACC.7 ;不考慮數符
CLR OV ;清除溢出標志
CJNE A,#3FH,MV01;階碼是否上溢?
SETB OV ;設立溢出標志
MV01: MOV A,@R0 ;取出帶數符的階碼
RET
MVR0: MOV A,@R0 ;將[R0]傳送到第一工作區中的子程序
MOV C,ACC.7 ;將數符保存在位1FH中
MOV 1FH,C
MOV C,ACC.6 ;將階碼擴充為8bit補碼
MOV ACC.7,C
MOV R2,A ;存放在R2中
INC R0
MOV A,@R0 ;將尾數高位元組存放在R3中
MOV R3,A
INC R0
MOV A,@R0 ;將尾數低位元組存放在R4中
MOV R4,A
DEC R0 ;恢復數據指針
DEC R0
RET
MVR1: MOV A,@R1 ;將[R1]傳送到第二工作區中的子程序
MOV C,ACC.7 ;將數符保存在位1EH中
MOV 1EH,C
MOV C,ACC.6 ;將階碼擴充為8bit補碼
MOV ACC.7,C
MOV R5,A ;存放在R5中
INC R1
MOV A,@R1 ;將尾數高位元組存放在R6中
MOV R6,A
INC R1
MOV A,@R1 ;將尾數低位元組存放在R7中
MOV R7,A
DEC R1 ;恢復數據指針
DEC R1
RET
AS1: MOV A,R6 ;讀取第二操作數尾數高位元組
ORL A,R7
JZ AS2 ;第二操作數為零,不必運算
MOV A,R3 ;讀取第一操作數尾數高位元組
ORL A,R4
JNZ EQ1
MOV A,R6 ;第一操作數為零,結果以第二操作數為准
MOV R3,A
MOV A,R7
MOV R4,A
MOV A,R5
MOV R2,A
MOV C,1EH
MOV 1FH,C
AS2: RET
EQ1: MOV A,R2 ;對階,比較兩個操作數的階碼
XRL A,R5
JZ AS4 ;階碼相同,對階結束
JB ACC.7,EQ3;階符互異
MOV A,R2 ;階符相同,比較大小
CLR C
SUBB A,R5
JC EQ4
EQ2: CLR C ;第二操作數右規一次
MOV A,R6 ;尾數縮小一半
RRC A
MOV R6,A
MOV A,R7
RRC A
MOV R7,A
INC R5 ;階碼加一
ORL A,R6 ;尾數為零否?
JNZ EQ1 ;尾數不為零,繼續對階
MOV A,R2 ;尾數為零,提前結束對階
MOV R5,A
SJMP AS4
EQ3: MOV A,R2 ;判斷第一操作數階符
JNB ACC.7,EQ2;如為正,右規第二操作數
EQ4: CLR C
LCALL RR1 ;第一操作數右規一次
ORL A,R3 ;尾數為零否?
JNZ EQ1 ;不為零,繼續對階
MOV A,R5 ;尾數為零,提前結束對階
MOV R2,A
AS4: JB F0,AS5 ;尾數加減判斷
MOV A,R4 ;尾數相加
ADD A,R7
MOV R4,A
MOV A,R3
ADDC A,R6
MOV R3,A
JNC AS2
LJMP RR1 ;有進位,右規一次
AS5: CLR C ;比較絕對值大小
MOV A,R4
SUBB A,R7
MOV B,A
MOV A,R3
SUBB A,R6
JC AS6
MOV R4,B ;第一尾數減第二尾數
MOV R3,A
LJMP RLN ;結果規格化
AS6: CPL 1FH ;結果的符號與第一操作數相反
CLR C ;結果的絕對值為第二尾數減第一尾數
MOV A,R7
SUBB A,R4
MOV R4,A
MOV A,R6
SUBB A,R3
MOV R3,A
RLN: MOV A,R3 ;浮點數規格化
ORL A,R4 ;尾數為零否?
JNZ RLN1
MOV R2,#0C1H;階碼取最小值
RET
RLN1: MOV A,R3
JB ACC.7,RLN2;尾數最高位為一否?
CLR C ;不為一,左規一次
LCALL RL1
SJMP RLN ;繼續判斷
RLN2: CLR OV ;規格化結束
RET
RL1: MOV A,R4 ;第一操作數左規一次
RLC A ;尾數擴大一倍
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
DEC R2 ;階碼減一
CJNE R2,#0C0H,RL1E;階碼下溢否?
CLR A
MOV R3,A ;階碼下溢,操作數以零計
MOV R4,A
MOV R2,#0C1H
RL1E: CLR OV
RET
RR1: MOV A,R3 ;第一操作數右規一次
RRC A ;尾數縮小一半
MOV R3,A
MOV A,R4
RRC A
MOV R4,A
INC R2 ;階碼加一
CLR OV ;清溢出標志
CJNE R2,#40H,RR1E;階碼上溢否?
MOV R2,#3FH ;階碼溢出
SETB OV
RR1E: RET
(4) 標號:FMUL 功能:浮點數乘法
入口條件:被乘數在[R0]中,乘數在[R1]中?
出口信息:OV=0時,積仍在[R0]中,OV=1時,溢出?
影響資源:PSW?A?B?R2~R7?位1EH?1FH 堆棧需求:6位元組
FMUL: LCALL MVR0 ;將[R0]傳送到第一工作區中
MOV A,@R0
XRL A,@R1 ;比較兩個操作數的符號
RLC A
MOV 1FH,C ;保存積的符號
LCALL MUL0 ;計算積的絕對值
LJMP MOV0 ;將結果傳回到[R0]中
MUL0: LCALL MVR1 ;將[R1]傳送到第二工作區中
MUL1: MOV A,R3 ;第一尾數為零否?
ORL A,R4
JZ MUL6
MOV A,R6 ;第二尾數為零否?
ORL A,R7
JZ MUL5
MOV A,R7 ;計算R3R4×R6R7-→R3R4
MOV B,R4
MUL AB
MOV A,B
XCH A,R7
MOV B,R3
MUL AB
ADD A,R7
MOV R7,A
CLR A
ADDC A,B
XCH A,R4
MOV B,R6
MUL AB
ADD A,R7
MOV R7,A
MOV A,B
ADDC A,R4
MOV R4,A
CLR A
RLC A
XCH A,R3
MOV B,R6
MUL AB
ADD A,R4
MOV R4,A
MOV A,B
ADDC A,R3
MOV R3,A
JB ACC.7,MUL2;積為規格化數否?
MOV A,R7 ;左規一次
RLC A
MOV R7,A
LCALL RL1
MUL2: MOV A,R7
JNB ACC.7,MUL3
INC R4
MOV A,R4
JNZ MUL3
INC R3
MOV A,R3
JNZ MUL3
MOV R3,#80H
INC R2
MUL3: MOV A,R2 ;求積的階碼
ADD A,R5
MD: MOV R2,A ;階碼溢出判斷
JB ACC.7,MUL4
JNB ACC.6,MUL6
MOV R2,#3FH ;階碼上溢,設立標志
SETB OV
RET
MUL4: JB ACC.6,MUL6
MUL5: CLR A ;結果清零(因子為零或階碼下溢)
MOV R3,A
MOV R4,A
MOV R2,#41H
MUL6: CLR OV
RET
(5) 標號: FDIV 功能:浮點數除法
入口條件:被除數在[R0]中,除數在[R1]中?
出口信息:OV=0時,商仍在[R0]中,OV=1時,溢出?
影響資源:PSW?A?B?R2~R7?位1EH?1FH 堆棧需求: 5位元組
FDIV: INC R0
MOV A,@R0
INC R0
ORL A,@R0
DEC R0
DEC R0
JNZ DIV1
MOV @R0,#41H;被除數為零,不必運算
CLR OV
RET
DIV1: INC R1
MOV A,@R1
INC R1
ORL A,@R1
DEC R1
DEC R1
JNZ DIV2
SETB OV ;除數為零,溢出
RET
DIV2: LCALL MVR0 ;將[R0]傳送到第一工作區中
MOV A,@R0
XRL A,@R1 ;比較兩個操作數的符號
RLC A
MOV 1FH,C ;保存結果的符號
LCALL MVR1 ;將[R1]傳送到第二工作區中
LCALL DIV3 ;調用工作區浮點除法
LJMP MOV0 ;回傳結果
DIV3: CLR C ;比較尾數的大小
MOV A,R4
SUBB A,R7
MOV A,R3
SUBB A,R6
JC DIV4
LCALL RR1 ;被除數右規一次
SJMP DIV3
DIV4: CLR A ;借用R0R1R2作工作寄存器
XCH A,R0 ;清零並保護之
PUSH ACC
CLR A
XCH A,R1
PUSH ACC
MOV A,R2
PUSH ACC
MOV B,#10H ;除法運算,R3R4/R6R7-→R0R1
DIV5: CLR C
MOV A,R1
RLC A
MOV R1,A
MOV A,R0
RLC A
MOV R0,A
MOV A,R4
RLC A
MOV R4,A
XCH A,R3
RLC A
XCH A,R3
MOV F0,C
CLR C
SUBB A,R7
MOV R2,A
MOV A,R3
SUBB A,R6
ANL C,/F0
JC DIV6
MOV R3,A
MOV A,R2
MOV R4,A
INC R1
DIV6: DJNZ B,DIV5
MOV A,R6 ;四捨五入
CLR C
RRC A
SUBB A,R3
CLR A
ADDC A,R1 ;將結果存回R3R4
MOV R4,A
CLR A
ADDC A,R0
MOV R3,A
POP ACC ;恢復R0R1R2
MOV R2,A
POP ACC
MOV R1,A
POP ACC
MOV R0,A
MOV A,R2 ;計算商的階碼
CLR C
SUBB A,R5
LCALL MD ;階碼檢驗
LJMP RLN ;規格化
(6) 標號: FCLR 功能:浮點數清零
入口條件:操作數在[R0]中?
出口信息:操作數被清零?
影響資源:A 堆棧需求: 2位元組
FCLR: INC R0
INC R0
CLR A
MOV @R0,A
DEC R0
MOV @R0,A
DEC R0
MOV @R0,#41H
RET
(7) 標號: FZER 功能:浮點數判零
入口條件:操作數在[R0]中?
出口信息:若累加器A為零,則操作數[R0]為零,否則不為零?
影響資源:A 堆棧需求: 2位元組
FZER: INC R0
INC R0
MOV A,@R0
DEC R0
ORL A,@R0
DEC R0
JNZ ZERO
MOV @R0,#41H
ZERO: RET
(8) 標號: FMOV 功能:浮點數傳送
入口條件:源操作數在[R1]中,目標地址為[R0]?
出口信息:[R0]=[R1],[R1]不變?
影響資源:A 堆棧需求: 2位元組
FMOV: INC R0
INC R0
INC R1
INC R1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
RET
(9) 標號: FPUS 功能:浮點數壓棧
入口條件:操作數在[R0]中?
出口信息:操作數壓入棧頂?
影響資源:A?R2?R3 堆棧需求: 5位元組
FPUS: POP ACC ;將返回地址保存在R2R3中
MOV R2,A
POP ACC
MOV R3,A
MOV A,@R0 ;將操作數壓入堆棧
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
DEC R0
DEC R0
MOV A,R3 ;將返回地址壓入堆棧
PUSH ACC
MOV A,R2
PUSH ACC
RET ;返回主程序
(10) 標號: FPOP 功能:浮點數出棧
入口條件:操作數處於棧頂?
出口信息:操作數彈至[R0]中?
影響資源:A?R2?R3 堆棧需求: 2位元組
FPOP: POP ACC ;將返回地址保存在R2R3中
MOV R2,A
POP ACC
MOV R3,A
INC R0
INC R0
POP ACC ;將操作數彈出堆棧,傳送到[R0]中
MOV @R0,A
DEC R0
POP ACC
MOV @R0,A
DEC R0
POP ACC
MOV @R0,A
MOV A,R3 ;將返回地址壓入堆棧
PUSH ACC
MOV A,R2
PUSH ACC
RET ;返回主程序
(11) 標號: FCMP 功能:浮點數代數值比較(不影響待比較操作數)
入口條件:待比較操作數分別在[R0]和[R1]中?
出口信息:若CY=1,則[R0] < [R1],若CY=0且A=0則 [R0] = [R1],否則[R0] > [R1]?
影響資源:A?B?PSW 堆棧需求: 2位元組
FCMP: MOV A,@R0 ;數符比較
XRL A,@R1
JNB ACC.7,CMP2
MOV A,@R0 ;兩數異號,以[R0]數符為准
RLC A
MOV A,#0FFH
RET
CMP2: MOV A,@R1 ;兩數同號,准備比較階碼
MOV C,ACC.6
MOV ACC.7,C
MOV B,A
MOV A,@R0
MOV C,ACC.7
MOV F0,C ;保存[R0]的數符
MOV C,ACC.6
MOV ACC.7,C
CLR C ;比較階碼
SUBB A,B
JZ CMP6
RLC A ;取階碼之差的符號
JNB F0,CMP5
CPL C ;[R0]為負時,結果取反
CMP5: MOV A,#0FFH ;兩數不相等
RET
CMP6: INC R0 ;階碼相同時,准備比較尾數
INC R0
INC R1
INC R1
CLR C
MOV A,@R0
SUBB A,@R1
MOV B,A ;保存部分差
DEC R0
DEC R1
MOV A,@R0
SUBB A,@R1
DEC R0
DEC R1
ORL A,B ;生成是否相等信息
JZ CMP7
JNB F0,CMP7
CPL C ;[R0]為負時,結果取反
CMP7: RET
(12) 標號: FABS 功能:浮點絕對值函數
入口條件:操作數在[R0]中?
出口信息:結果仍在[R0]中?
影響資源:A 堆棧需求: 2位元組
FABS: MOV A,@R0 ;讀取操作數的階碼
CLR ACC.7 ;清除數符
MOV @R0,A ;回傳階碼
RET
(13) 標號: FSGN 功能:浮點符號函數
入口條件:操作數在[R0]中?
出口信息:累加器 A=1 時為正數,A=0FFH時為負數,A=0 時為零?
影響資源:PSW?A 堆棧需求: 2位元組
FSGN: INC R0 ;讀尾數
MOV A,@R0
INC R0
ORL A,@R0
DEC R0
DEC R0
JNZ SGN
RET ;尾數為零,結束
SGN: MOV A,@R0 ;讀取操作數的階碼
RLC A ;取數符
MOV A,#1 ;按正數初始化
JNC SGN1 ;是正數,結束
MOV A,#0FFH ;是負數,改變標志
SGN1: RET
(14) 標號: FINT 功能:浮點取整函數
入口條件:操作數在[R0]中?
出口信息:結果仍在[R0]中?
影響資源:PSW?A?R2?R3?R4?位1FH 堆棧需求: 6位元組
FINT: LCALL MVR0 ;將[R0]傳送到第一工作區中
LCALL INT ;在工作寄存器中完成取整運算
LJMP MOV0 ;將結果傳回到[R0]中
INT: MOV A,R3
ORL A,R4
JNZ INTA
CLR 1FH ;尾數為零,階碼也清零,結束取整
MOV R2,#41H
RET
INTA: MOV A,R2
JZ INTB ;階碼為零否?
JB ACC.7,INTB;階符為負否?
CLR C
SUBB A,#10H ;階碼小於16否?
JC INTD
RET ;階碼大於16,已經是整數
INTB: CLR A ;絕對值小於一,取整後正數為零,負數為負一
MOV R4,A
MOV C,1FH
RRC A
MOV R3,A
RL A
MOV R2,A
JNZ INTC
MOV R2,#41H
INTC: RET
INTD: CLR F0 ;舍尾標志初始化
INTE: CLR C
LCALL RR1 ;右規一次
ORL C,F0 ;記憶舍尾情況
MOV F0,C
CJNE R2,#10H,INTE;階碼達到16(尾數完全為整數)否?
JNB F0,INTF ;捨去部分為零否?
JNB 1FH,INTF;操作數為正數否?
INC R4 ;對於帶小數的負數,向下取整
MOV A,R4
JNZ INTF
INC R3
INTF: LJMP RLN ;將結果規格化
(15) 標號: FRCP 功能:浮點倒數函數
入口條件:操作數在[R0]中?
出口信息:OV=0時,結果仍在[R0]中,OV=1時,溢出?
影響資源:PSW?A?B?R2~R7?位1EH?1FH 堆棧需求: 5位元組
FRCP: MOV A,@R0
MOV C,ACC.7
MOV 1FH,C ;保存數符
MOV C,ACC.6 ;絕對值傳送到第二工作區
MOV ACC.7,C
MOV R5,A
INC R0
MOV A,@R0
MOV R6,A
INC R0
MOV A,@R0
MOV R7,A
DEC R0
DEC R0
ORL A,R6
JNZ RCP
SETB OV ;零不能求倒數,設立溢出標志
RET
RCP: MOV A,R6
JB ACC.7,RCP2;操作數格式化否?
CLR C ;格式化之
MOV A,R7
RLC A
MOV R7,A
MOV A,R6
RLC A
MOV R6,A
DEC R5
SJMP RCP
RCP2: MOV R2,#1 ;將數值1.00傳送到第一工作區
MOV R3,#80H
MOV R4,#0
LCALL DIV3 ;調用工作區浮點除法,求得倒數
LJMP MOV0 ;回傳結果
(16) 標號: FSQU 功能:浮點數平方
入口條件:操作數在[R0]中?
出口信息:OV=0時,平方值仍然在[R0]中,OV=1時溢出?
影響資源:PSW?A?B?R2~R7?位1EH?1FH 堆棧需求: 9位元組
FSQU: MOV A,R0 ;將操作數
XCH A,R1 ;同時作為乘數
PUSH ACC ;保存R1指針
LCALL FMUL ;進行乘法運算
POP ACC
MOV R1,A ;恢復R1指針
RET
(17) 標號: FSQR 功能:浮點數開平方(快速逼近演算法)
入口條件:操作數在[R0]中?
出口信息:OV=0時,平方根仍在[R0]中,OV=1時,負數開平方出錯?
影響資源:PSW?A?B?R2~R7 堆棧需求: 2位元組
FSQR: MOV A,@R0
JNB ACC.7,SQR
SETB OV ;負數開平方,出錯
RET
SQR: INC R0
INC R0
MOV A,@R0
DEC R0
ORL A,@R0
DEC R0
JNZ SQ
MOV @R0,#41H;尾數為零,不必運算
CLR OV
RET
SQ: MOV A,@R0
MOV C,ACC.6 ;將階碼擴展成8bit補碼
MOV ACC.7,C
INC A ;加一
CLR C
RRC A ;除二
MOV @R0,A ;得到平方根的階碼,回存之
INC R0 ;指向被開方數尾數的高位元組
JC SQR0 ;原被開方數的階碼是奇數嗎?
MOV A,@R0 ;是奇數,尾數右規一次
RRC A
MOV @R0,A
INC R0
MOV A,@R0
RRC A
MOV @R0,A
DEC R0
SQR0: MOV A,@R0
JZ SQR9 ;尾數為零,不必運算
MOV R2,A ;將尾數傳送到R2R3中
INC R0
MOV A,@R0
MOV R3,A
MOV A,R2 ;快速開方,參閱定點子程序說明
ADD A,#57H
JC SQR2
ADD A,#45H
JC SQR1
ADD A,#24H
MOV B,#0E3H
MOV R4,#80H
SJMP SQR3
SQR1: MOV B,#0B2H
MOV R4,#0A0H
SJMP SQR3
SQR2: MOV B,#8DH
MOV R4,#0D0H
SQR3: MUL AB
MOV A,B
ADD A,R4
MOV R4,A
MOV B,A
MUL AB
XCH A,R3
CLR C
SUBB A,R3
MOV R3,A
MOV A,B
XCH A,R2
SUBB A,R2
MOV R2,A
SQR4: SETB C
MOV A,R4
RLC A
MOV R6,A
CLR A
RLC A
MOV R5,A
MOV A,R3
SUBB A,R6
MOV B,A
MOV A,R2
SUBB A,R5
JC SQR5
INC R4
MOV R2,A
MOV R3,B
SJMP SQR4
SQR5: MOV A,R4
XCH A,R2
RRC A
MOV F0,C
MOV A,R3
MOV R5,A
MOV R4,#8
SQR6: CLR C
MOV A,R3
RLC A
MOV R3,A
CLR C
MOV A,R5
SUBB A,R2
JB F0,SQR7
JC SQR8
SQR7: MOV R5,A
INC R3
SQR8: CLR C
MOV A,R5
RLC A
MOV R5,A
MOV F0,C
DJNZ R4,SQR6
MOV A,R3 ;將平方根的尾數回傳到[R0]中
MOV @R0,A
DEC R0
MOV A,R2
MOV @R0,A
SQR9: DEC R0 ;數據指針回歸原位
CLR OV ;開方結果有效
RET
(18) 標號: FPLN 功能:浮點數多項式計算
入口條件:自變數在[R0]中,多項式系數在調用指令之後,以40H結束?
出口信息:OV=0時,結果仍在[R0]中,OV=1時,溢出?
影響資源:DPTR?PSW?A?B?R2~R7?位1EH?1FH 堆棧需求: 4位元組
FPLN: POP DPH ;取出多項式系數存放地址
POP DPL
XCH A,R0 ;R0?R1交換角色,自變數在[R1]中
XCH A,R1
XCH A,R0
CLR A ;清第一工作區
MOV R2,A
MOV R3,A
MOV R4,A
CLR 1FH
PLN1: CLR A ;讀取一個系數,並裝入第二工作區
MOVC A,@A+DPTR
MOV C,ACC.7
MOV 1EH,C
MOV C,ACC.6
MOV ACC.7,C
MOV R5,A
INC DPTR
CLR A
MOVC A,@A+DPTR
MOV R6,A
INC DPTR
CLR A
MOVC A,@A+DPTR
MOV R7,A
INC DPTR ;指向下一個系數
MOV C,1EH ;比較兩個數符
RRC A
XRL A,23H
RLC A
MOV F0,C ;保存比較結果
LCALL AS1 ;進行代數加法運算
CLR A ;讀取下一個系數的第一個位元組
MOVC A,@A+DPTR
CJNE A,#40H,PLN2;是結束標志嗎?
XCH A,R0 ;運算結束,恢復R0?R1原來的角色
XCH A,R1
XCH A,R0
LCALL MOV0 ;將結果回傳到[R0]中
CLR A
INC DPTR
JMP @A+DPTR ;返回主程序
PLN2: MOV A,@R1 ;比較自變數和中間結果的符號
XRL A,23H
RLC A
MOV 1FH,C ;保存比較結果
LCALL MUL0 ;進行乘法運算
SJMP PLN1 ;繼續下一項運算
(19) 標號: FLOG 功能:以10為底的浮點對數函數
入口條件:操作數在[R0]中?
出口信息:OV=0時,結果仍在[R0]中,OV=1時,負數或零求對數出錯?
影響資源:DPTR?PSW?A?B?R2~R7?位1EH?1FH 堆棧需求:9位元組
FLOG: LCALL FLN ;先以e為底求對數
JNB OV,LOG
RET ;如溢出則停止計算
LOG: MOV R5,#0FFH;系數0.43430(1/Ln10)
MOV R6,#0DEH
MOV R7,#5CH
LCALL MUL1 ;通過相乘來換底
LJMP MOV0 ;傳回結果
5. C51單片機C語言中斷問題
51單片機12M晶振時,定時/計數器的時鍾為1uS,所以單個16位的定時/計數器能達到的最大定時時間為:65536*1uS=65.536ms,所以12M晶振的情況下,用單個16位定時器得不到100ms的定時。這時可更換頻率較低的晶振或用以下兩種軟體的方法:
1、定時器累加。用一個計數值來記錄定時器的中斷次數。比如,設定定時器10ms中斷,用一個計數值來記錄定時器的中斷次數,每中斷一次計數加1,這樣計數值為10時候,定時器中斷10次,即為100ms,然後將計數值清0,重新計數。這個方法會有小小誤差,因為操作計數值的時候會佔用一點時間,這個時間比較短。
2、2個定時/計數器串聯。一個用作定時器,一個用作計數器。定時器中斷的時候輸出一個脈沖作為計數器的計數脈沖,設定一個計數值,計數滿的時候中斷。總的定時時間的原理同上。
至於定時/計數器的操作,樓上兩位說得很清楚了。
6. 51單片機溫度報警器原理圖和程序有嗎
這個是自動控制溫度的一個例子,溫度降低到一定程度就啟動加熱。
//溫度感測器:DS18B20
//顯示方式:LED
#include <reg51.h>
#define uchar unsigned char
sbit keyup=P1^0;
sbit keydn=P1^1;
sbit keymd=P1^2;
sbit out=P3^7;//接控制繼電器
sbit DQ = P3^4;//接溫度感測器18B20
uchar t[2],number=0,*pt;//溫度值
uchar TempBuffer1[4]={0,0,0,0};
uchar Tmax=18,Tmin=8;
uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xfe,0xf7};
uchar dismod=0,xiaodou1=0,xiaodou2=0,currtemp;
bit flag;
void t0isr() interrupt 1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
switch(number)
{
case 0:
P2=0x08;
P0=distab[TempBuffer1[0]];
break;
case 1:
P2=0x04;
P0=distab[TempBuffer1[1]];
break;
case 2:
P2=0x02;
P0=distab[TempBuffer1[2]]&0x7f;
break;
case 3:
P2=0x01;
P0=distab[TempBuffer1[3]];
break;
default:
break;
}
number++;
if(number>3)number=0;
}
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20初始化函數**********************/
void Init_DS18B20(void)
{
bit x=0;
do{
DQ=1;
delay_18B20(8);
DQ = 0; //單片機將DQ拉低
delay_18B20(90); //精確延時 大於 480us
DQ = 1; //拉高匯流排
delay_18B20(14);
x=DQ; //稍做延時後 如果x=0則初始化成功 x=1則初始化失敗,繼續初始化
}while(x);
delay_18B20(20);
}
/***********ds18b20讀一個位元組**************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號
dat>>=1;
DQ = 1; // 給脈沖信號
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b20寫一個位元組****************/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
/**************讀取ds18b20當前溫度************/
unsigned char *ReadTemperature(unsigned char rs)
{
unsigned char tt[2];
delay_18B20(80);
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0x44); //啟動溫度轉換
delay_18B20(80);
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器)前兩個就是溫度
tt[0]=ReadOneChar(); //讀取溫度值低位
tt[1]=ReadOneChar(); //讀取溫度值高位
return(tt);
}
void covert1(void)//將溫度轉換為LED顯示的數據
{
uchar x=0x00,y=0x00;
t[0]=*pt;
pt++;
t[1]=*pt;
if(t[1]&0x080) //判斷正負溫度
{
TempBuffer1[0]=0x0c; //c代表負
t[1]=~t[1]; /*下面幾句把負數的補碼*/
t[0]=~t[0]; /*換算成絕對值*********/
x=t[0]+1;
t[0]=x;
if(x==0x00)t[1]++;
}
else TempBuffer1[0]=0x0a;//A代表正
t[1]<<=4;//將高位元組左移4位
t[1]=t[1]&0xf0;
x=t[0];//將t[0]暫存到X,因為取小數部分還要用到它
x>>=4;//右移4位
x=x&0x0f;//和前面兩句就是取出t[0]的高四位
y=t[1]|x;//將高低位元組的有效值的整數部分拼成一個位元組
TempBuffer1[1]=(y%100)/10;
TempBuffer1[2]=(y%100)%10;
t[0]=t[0]&0x0f;//小數部分
TempBuffer1[3]=t[0]*10/16;
//以下程序段消去隨機誤檢查造成的誤判,只有連續12次檢測到溫度超出限制才切換加熱裝置
if(currtemp>Tmin)xiaodou1=0;
if(y<Tmin)
{
xiaodou1++;
currtemp=y;
xiaodou2=0;
}
if(xiaodou1>12)
{
out=0;
flag=1;
xiaodou1=0;
}
if(currtemp<Tmax)xiaodou2=0;
if(y>Tmax)
{
xiaodou2++;
currtemp=y;
xiaodou1=0;
}
if(xiaodou2>12)
{
out=1;
flag=0;
xiaodou2=0;
}
out=flag;
}
void convert(char tmp)
{
uchar a;
if(tmp<0)
{
TempBuffer1[0]=0x0c;
a=~tmp+1;
}
else
{
TempBuffer1[0]=0x0a;
a=tmp;
}
TempBuffer1[1]=(a%100)/10;
TempBuffer1[2]=(a%100)%10;
}
void keyscan( )
{
uchar keyin;
keyin=P1&0x07;
if(keyin==0x07)return;
else if(keymd==0)
{
dismod++;
dismod%=3;
while(keymd==0);
switch(dismod)
{
case 1:
convert(Tmax);
TempBuffer1[3]=0x11;
break;
case 2:
convert(Tmin);
TempBuffer1[3]=0x12;
break;
default:
break;
}
}
else if((keyup==0)&&(dismod==1))
{
Tmax++;
convert(Tmax);
while(keyup==0);
}
else if((keydn==0)&&(dismod==1))
{
Tmax--;
convert(Tmax);
while(keydn==0);
}
else if((keyup==0)&&(dismod==2))
{
Tmin++;
convert(Tmin);
while(keyup==0);
}
else if((keydn==0)&&(dismod==2))
{
Tmin--;
convert(Tmin);
while(keydn==0);
}
xiaodou1=0;
xiaodou2=0;
}
main()
{
TMOD=0x01;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
ET0=1;
EA=1;
out=1;
flag=0;
ReadTemperature(0x3f);
delay_18B20(50000);//延時等待18B20數據穩定
while(1)
{
pt=ReadTemperature(0x7f); //讀取溫度,溫度值存放在一個兩個位元組的數組中
if(dismod==0)covert1();
keyscan();
delay_18B20(30000);
}
}
7. 求一MCS-51系列單片機指令表
傳送指令是指令系統中最基本,使用最多的一類指令,主要用於數據的傳送、保存以及交換等場合。
1.以累加器A為目的操作數的指令(4條)
這組指令的功能是把源操作數指定的內容送入累加器A中。
有寄存器、直接、寄存器間接和立即4種定址方式。
MOV A, Rn MOV A, data
MOV A,@Rn MOV A,#data
2.以寄存器Rn為目的的操作數的指令(3條)
這組指令的功能是把源操作數指定的內容送到所選定的工作寄存器Rn中。
有寄存器、直接和立即3種定址方式。
MOV Rn, A MOV Rn,data
MOV Rn,#data
3.以直接地址為目的操作數的指令(5條)
這組指令的功能是把源操作數指定的內容送到由直接地址data所指定的片內RAM中。
有寄存器、直接、寄存器間接和立即4種定址方式。
MOV data,A MOV data,Rn
MOV data1,data2 MOV data,@Ri
MOV data,#data
4.以間接地址為目的操作數的指令(3條)
這組指令的功能是把源操作數指定的內容送到以Ri中的內容為地址的片內RAM中。
有寄存器、直接和立即3種定址方式。
MOV @Ri,A MOV @Ri,data
MOV @Ri,#data
5.查表指令(2條)
這組指令的功能是對存放於程序存儲器中的數據表格進行查找傳送。使用變址定址方式。
MOVC A,@A+DPTR MOVC A, @A+PC
6.累加器A與片外AM傳送指令(4條)
這組指令的功能為累加器A與片RAM間的相互傳送。由於MCS-51指令系統中沒有專門的輸入/輸出指令,且片外擴展的I/O口與片外RAM是統一編址的,故以下4條指令也可作為輸入/輸出指令。使用寄存器間接定址方式。
MOVX A,@DPAR MOVX @DPTR,A
MOVX A,@Ri MOVX @Ri,A
7.堆棧操作類指令(2條)
該類指令的功能是把直接定址單元的內容傳送到堆棧指針SP所指的單元中,以及把SP所指單元的內容送到直接定址單元中。
PUSH data POP data
前一條指令稱為入棧操作指令,後一條指令稱為出棧指令。由於開機復位後,(SP)=07H,故一般需重新設置SP的初值。由於壓入堆棧的第一個數必須存放在SP+1所指存儲單元,故實際的棧底為SP+1所指存儲單元。
8.交換指令(4條)
該類指令的功能是把累加器A中的內容與源操作數所指出的數據相互交換。
有寄存器、直接和寄存器間接3種定址方式。
XCH A,Rn XCH A,data
XCH A,@Ri XCHD A,@Ri
9.16位數據傳送類指令(1條)
MOV DPTR,#data
該指令的功能是把16位常數送入數據指針寄存器,使用立即定址方式。譯成機器碼時,是高位位元組在前,低位位元組在後。
MCS-51具有強大的加、減、乘、除四則算術運算指令。
1.程序狀態字PSW
MCS-51有一個程序狀態字寄存器PSW,用來保存指令執行結果的標志,供程序查訊和判別。PSW是特殊功能寄存器中的一個,其格式如下:
PSW7--既是布爾處理機的累加器C,又是進位標志CY,如果操作結果在最高位有進位輸出(加法時)或借位輸入(減法時),置位CY,否則清「0」CY。
AC--輔助進位(半進位)標志。如果操作結果的低4位有進位(加法時)或向高4位借位時(減法),置AC,否則清「0」AC,AC主要用於二-十進制數加法調整。
OV--溢出標志。如果操作結果有進位進入最高位,但最高位沒有產生進位,或者最高位產生進位而低位沒有向最高位進位,這時置位溢出標志位,否則OV清「0」。溢出標志位用於補碼運算,當有符號的數運算結果不能用8位二進制數表示時,OV將置位。
P--累加器A的奇偶標志位,如果累加器A的8位的模2和為1(奇),則P=1;否則P=0。由於P總是表示A的奇偶性,隨著A的內容變化的,所以一個值寫入PSW的P位的值不變。
RS1、RS0--指示當前使用的工作寄存器區。
F0--用戶標志位。可作為軟體標志,它的作用和內部RAM位定址區的各位相似。
PSW1--保留位,對它的操作無效。
2.加法指令
1、不帶進位加法指令
ADD A,#data ADD A,data
ADD A,@Ri ADD A,Rn
工作寄存器、內部RAM單元內容或立即數的8位無符號二進制數和累加器A中數相加,所得和存放於累加器A中,當和的第3、7位有進位時,分別將AC,CY標志位置1;否則為0。
上述指令的執行將影響標志位AC、CY、OV、P。
對於無符號數,進位標志位CY=1,表示溢出;CY=0表示無溢出。帶符號數運算的溢出取決於第6、7位中有一位產生進位,而另一位不產生進位,溢出標志位OV置「1」否則被清「0」。OV=1表示兩個正數相加,和變為負數,或兩個負數相加,和變為正數的錯誤結果。
源操作數有四種定址方式:寄存器、直接、間接和立即數。
2、帶進位加法指令:
ADDC A,#data ADDC A,data
ADDC A,@Ri ADDC A,Rn
這是四條帶進位的加法指令。將累加器A內容加當前CY標志位內容,再加無符號單位元組的數,和存於累加器A中。當運算結果第3、7位產生進位溢出時,則分別置位AC、CY和OV標志位。本指令執行將影響標志位AC、CY、OV、P。
本指令常用於多位元組加法。
3、加1指令:
INC A INC data
INC @Ri INC Rn
INC DPTR
INC指令將指定的內容加1,結果仍存放於原A或原單元中。如原值為0FFH,加1運算後將變成00H,運算結果不影響標志位。
本指令可對累加器A、工作寄存器RN、RI間址和直接定址的單元內容進行加1運算。可見MCS-51加1指令是較豐富的。
注意:當用本指令使輸出並行I/O內容加1時,用作輸出口原始值,將從輸出口的數據鎖存器中讀入,而不是從輸出口的引腳上讀入。
4、二-十進制調正指令:
DA A
若[(A0-3)>9]或[(AC)=1),則(A0-3)(A0-3)+06H
本指令是對A的BCD碼加法結果進行調正。兩個壓縮型BCD碼按二進制數相加之後,必須經本指令調正,才能得到壓縮型BCD碼的和數。
本指令的操作為:若累加器A的低4位數值大於9或者第3位向第4位產生進位,即AC輔助進位位為1,則需將A的低4位內容加6調正,以產生低4位正確的BCD碼值。如果加0調正後,低4位產生進位,且高4位均為1時,則內部加法將置位CY,反之,它並不清「0」CY標志位。
若累加器A的高4位值大於9或最高進位位CY=1,則高位4位需加6調正,以產生高4位的正確BCD碼值。同樣,在加6調正後產生最高進位,則置位CY,反之,不清「0」CY這時CY的置位,表示和數BCD碼值大於等於100。這對多位元組十進制加法有用。不影響OV標志。
由此可見,本指令是根據累加器A的原始數值和PSW的狀態,對累加器A進行加O6H、60H或66H的操作。
必須注意:本指令不能簡單地把累加器A中的16進制數交換成BCD碼,也不能用於十進制減法的調正。
3.減法指令
MCS-51在MCS-48的基礎上增加了帶借位減法指令,加強了計算機的運算功能。
1、帶借位減法指令:
SUBB A,#data SUBB A,data
SUBB A,@Ri SUBB A,Rn
帶借位減法指令SUBB,從累加器A中減去進位標志位CY和指定的變數,結果在累加器A中,若第七位有借位,則置位位CY,否則CY清0。若第3位有錯位,則置位輔助進位標志AC,否則清0 AC。若第7和第6位中有一位需借位,而另一位不借位,則置位溢出標志OV。溢出位OV用於帶符號的整數減法,它表示(OV=1)一個正數減負數結果為負數;或一個負數減正數結果為正數的錯誤結果。
源操作數允許有四種定址方式:寄存器RN,直接地址direct,間址Ri或立即數。
當在進行單位元組或多位元組減法前,不知道進位標志位CY的值,則應在減法指令前先將CY清「0」。
4.乘法指令
MUL AB
乘法指令是MCS-51新增加的,運算速度只需4個機器周期。它大大增加了MCS-51單片機的運算功能,克服了MCS-48系列單片機的不足。
本指令將累加器A和寄存器B中二個8位無符號整數進行相乘,16位乘積的低8位存於A中,高8位存於B中,如果乘積大於255(0FFH),即B的內容不為0時,則置位溢出標志位OV,否則清「0」OV。進位標志位CY總是清「0」。
5.除法指令
DIV AB
MCS-51系列單片機增加的除法指令,運算時間亦只需4個機器周期,同樣也增強了MCS-51的運算功能,使它能適用於復雜的且要求運算功能較強的控制系統。除法指令格式:
本指令將累加器A中8位無符號整數除以B寄存器中8位無符號整數,所得結果商的整數部分存於A中,整數作數部分存於寄存器B中。清「0」CY和OV標志位。當除數(B中內容)為00H時,則執行結果將為不定值,即執行結果送往A和B中的為不定值,且置位溢出標志位OV。在任何情況下,均清「0」CY。
6.減一指令
DEC A DEC data
DEC @Ri DEC Rn
DEC指令把所指的寄存器內容減1,結果仍送回原寄存器,若原來寄存器的內容為00H,則減1後將為FFH,運算結果不影響任何標志位,該組指令使用了直接、寄存器和寄存器間定址。同加1指令一樣,在第二條指令中,若直接地址是I/O口,則進行「讀-改-寫」操作。
邏輯操作類指令共有效25條,有與、或、異或、求反、左右移位、清0等邏輯操作,對應的定址方式有直接、寄存器和間接定址,該類指令的執行一般不影響PSW。
1.循環移位指令(4條)
RL A; RR A;
RLC A; RRC A;
前兩條指令的功能分別是將累加器A的內容循環左移一位,後兩條指令的功能分別是將累加器A的內容連同進位位CY一起循環左移或右移一位。
2.累加器半位元組交換指令(1條)
SWAP A;
這條指令的功能是將累加器A的高低兩半位元組交換。如(A)=56H,執行指令SWAP A 後,結果(A)=65H。
3.求反指令(1條)
CPL A;
4.清0指令(1條)
CLR A;
5.邏輯與指令(6條)
ANL A,#data; ANL data,#data
ANL A,Rn ANL A,data
ANL data,A ANL A,@Ri
這組指令的第二條和第五條指令中,若直接地址正好是I/O口,則也是「讀-改-寫」操作。
6.邏輯或指令(6條)
ORL A,#data ORL data,#data
ORL A,Rn ORL A,data
ORL data,A ORL A,@Ri
這組指令的第二條和第五條也具有「讀-改-寫」功能。
7.邏輯異或指令(6條)
XRL A,#data XRL data,#data
XRL A,Rn XRL A,data
XRL data,A XRL A,@Ri
同樣,這組指令的第二條和第五條也具有「讀-寫-改」功能。
控制轉移類指令用於控製程序的走向,故其作用區間是程序存儲器空間。利用具有16位地址的長調用、長轉移指令可對64K程序存儲器的任一地址單元進行訪問,也可用具有11位地址的絕對調用和絕對轉移指令,訪問2K位元組的空間。另外,還有在一頁范圍的短相對轉移以及許多條件轉移指令,這類指令一般不影響標志位,不面分別給予介紹。
1.無條件轉移語句(4條)
LJMP addr16 AJMP addr11 SJMP rel JMP @(A)+DPTR
上述指令的功能是當程序執行完該指令時,程序就無條件地轉移到指令所提供的地址上去。
第一條指令稱為長轉移指令,指令提供16位目標地址,將指令中第二位元組和第三位元組地址碼分別裝入PC的高8位中,所以無條件轉移的目標地址范圍是64K位元組空間。
第二條指令稱為絕對轉移指令,指令提供11位目標地址,所以,無條件轉移的目標地址范圍是從下條指令開始的2K位元組空間。
第三條指令稱為相對短轉移指令,指令控製程序無條件的轉向指定地址。該指令的rel是一個帶符號的相對偏移量,范圍為-128~+127。負數表示向後轉移,正數表示向前轉移。這條指令的優點是指令給出的是相對轉移地址,不具體指出地址值,這樣當程序地址發生變化時,只要相對地址不發生變化,該指令就不需作任何改動。在用匯編語言寫程序時,rel是一個標號,由匯編程序在匯編過程中自動計算偏移地址。在手工匯編時,可用下式計算偏移地址:
向後轉移時:rel=FEH-(源、目的地址的絕對值)
向前轉移時:rel=(源、目的地址差的絕對值)-2
第四條指令稱為散轉指令(又稱為間接轉移指令),該指令把累加器A中的8位無符號數與作為基址寄存器DPTR中的16位數據相加,所得的值送入PC作為轉移的目的地址。該指令執行後不影響累加器A和數據指針DPTR中的原內容,也不影響任何標志位。這條指令的特點是其轉移地址不是編程時確定的,而是在程序運行時動態決定的。因此,可以在DPTR中裝入多條轉移程序的首地址,而由累加器A中的內容來動態選擇該時刻應轉向那一條分支程序。
2.條件轉移指令(8條)
1.JZ rel 2.JNZ rel
3.CJNEA,data,rel 4.CJNE A,#data,rel
5. CJNE Rn,#data,rel
6.CJNE @Ri,data,rel
7.DJNZ Rn,rel
8.DJNZ data,rel
上述指令執行滿足某種特定條件的轉移,其目標在以下一條指令的起始地址為中心的256個位元組范圍內(-128~+127)。
第一條和第二條指令是判別累加器A中的內容是否為0來確定是順序執行還是轉移。
第三條至第六條是比較轉移指令,該指令通過比較前面兩個操作數的大小,如果它們的值不相等則轉移,相等則繼續執行。指令執行後要影響進位位CY,若操作數1小於操作數2,則CY=1;若操作數1大於操作數2,則CY=0。
3.調用指程序及返回指令(4條)
1.LCALL addr16 2.ACALL addr11 3.RET 4.RETI
在程序設計中,經常需要對某段程序反復執行,為了減少程序的編寫以及浪費不必要的地址空間,於是引入了主程序和子程序的概念,通常把某一段需要反復調用的程序稱為子程序,子程序的最後一條指令為返回主程序指令(RET),而對具有調用子程序功能的指令稱為調用指令。
第一條指令稱為長調用指令,其與LJMP一樣提供16位地址,可調用64K位元組范圍內的子程序。由於其為三位元組指令,所以執行時首先(PC)+3,以獲得下一條指令地址,並把此時的PC內容壓入堆棧,作為返回地址,然後把地址addr16裝入PC,轉去執行子程序。
第二條指令稱為絕對調用指令,該指令提供11位目標地址,限制在2K位元組范圍內調用,由於是雙位元組指令,所以執行時(PC)+2以獲得下一條指令的地址,然後把該地址壓入堆棧作為返回地址。其操作碼的形成與AJMP指令相同。
第三條指令稱為子程序返回指令,表示子程序結束需返回主程序,所以執行該指令時,分別從堆棧中彈出調用子程序時壓入的返回地址。
第四條指令稱為中斷返回指令,該指令的執行過程類似指令RET,但其還能恢復中斷邏輯,RETI和RET決不能互換使用。
4.空操作指令(1條)
NOP;
空操作指令除了PC加1外,CPC不作任何操作,而轉向下一條指令去執行。這條指令常用於產生一個機器周期的延時。
位操作類指令共有17條,均以位為操作對象,分別完成位傳送、位狀態控制、位邏輯運算、位條件轉移等功能,在匯編語言中,位地址的表示方式有以下4種:
直接用位地址表示:如91H。
位元組地址位數方式:如P1.0(90H)。
位名稱方式:如RS0。
用戶使用偽指令事先定義過的符號地址。
1.位數據傳送指令(2條)
MOV C,bit MOV bit,C
上述指令把源操作數指定的變數傳送到目的操作數指定的單元中。第二條指令若是對I/O口的位進行操作,則也是「讀-改-寫」操作。
2.位狀態控制指令(6條)
CLR C CLR bit CPL C
CPL bit SETB C SETB bit
上述指令的功能是分別對進位標志和直接定址進行清0、求反以及直接位地址是I/O口的某一位時,也具有「讀-改-寫」功能。
3.位邏輯運算指令(4條)
ANL C,bit ANL C,/bit
ORL C,bit ORL C/bit
上述指令的功能是將位累加器C的內容與直接位地址的內容或直接位地址內容的反進行邏輯與、邏輯或,結果仍送回C中。
4.位條件轉移指令(5)
JC rel JNC rel
JB bit,rel JNB bit,rel
JBC bit,rel
上述指令的功能分別是判別進位位C和直接位地址的內容是「1」還是「0」,以此來決定程序的走向。最後一條指令的功能是:若直接位址的內容為「1」則轉移,並且同時將該位清0,否則順序執行。這條指令若是對I/O口某一位操作,也具有「讀-改-寫」功能。
8. 51單片機中的求絕對值函數abs怎麼不管用
標准c中:
int abs(int x); 計算整數x的絕對值
double fabs(double x); 求x的絕對值
abs(1.2)會先取整再求絕對值。
9. 51單片機實現按鍵數值加減,並顯示在LCD上,有負數處理功能。
很簡單,加一個判斷語氣,當數值大於0時,不用處理,小於0時,加絕對值語氣,在lcd上面顯示一個-(負數),數據上自己處理一下就可以了