?? leqn.asm
?? 在定時器中斷中做LED的PWM輸出
AT89C2051實現A/D轉換的C51程序
單片機開發系統 指令系統 程序設計 定時與中斷 系統擴展 接口技術 串行口
?? ASM
?? 第 1 頁 / 共 2 頁
字號:
??
;解線性方程組的主元消去法(無回代過程)。
;入口條件:
; 方程組系數增廣矩陣存放在片外RAM中指定的頁面內,
; 數據格式為三字節二進制浮點數,方程組最大階數為八階。
;出口信息:
; 方程組的解X1,X2,...Xn依次在首址為WORK的內存中(二進制浮點數形式)。
ANNB EQU 20H ;方程組系數增廣矩陣存放的片外RAM頁面。
WORK EQU 30H ;工作區及方程根存放區首址。
WORK1 EQU 4BH ;輔助工作區。
N EQU 5 ;未知數個數(最多八個,以便存放在同一頁面內)。
I DATA 29H ;行指針變量。
J DATA 2AH ;列指針變量。
K DATA 2BH ;輔助指針變量。
CON DATA 2CH ;計數器。
TEMP EQU 2DH ;臨時浮點變量存放首址。
FLAG DATA 23H ;浮點運算標志
PFA BIT FLAG.7
PFB BIT FLAG.6
PFC BIT FLAG.5
PFD BIT FLAG.4
ORG 0000H
LJMP TEST
ORG 100H
TEST: MOV DPTR,#DATS;把測試數據復制到片外RAM指定的頁面。
MOV P2,#ANNB;系數增廣矩陣存放首址。
MOV R1,#0
MOV A,#N ;計算系數個數。
MOV B,A
INC A
MUL AB
MOV CON,A
TRA0: MOV R5,#3 ;每個系數有三個字節。
MOV R0,#TEMP;先讀到片內RAM。
TRA2: CLR A
MOVC A,@A+DPTR
MOV @R0,A
INC DPTR
INC R0
DJNZ R5,TRA2
MOV A,R1
PUSH ACC
MOV R0,#TEMP
PUSH DPH
PUSH DPL
LCALL BTOF ;把方程各系數由十進制浮點數轉換成二進制浮點數。
POP DPL
POP DPH
POP ACC
MOV R1,A
MOV R5,#3 ;再存放到片外RAM指定頁面。
TRA3: MOV A,@R0
MOVX @R1,A
INC R0
INC R1
DJNZ R5,TRA3
DJNZ CON,TRA0;將所有系數均存放好。
LCALL LEQN ;調用無回代主元消去法求解方程組的根。
MOV CON,#N ;將全部根
MOV R0,#WORK
TRA4: LCALL FTOB ;轉換成十進制浮點數。
INC R0
INC R0
INC R0
DJNZ CON,TRA4
STOP: LJMP STOP
;測試結果X1=1.000 ( 01H 10H 00H )
;測試結果X2=-0.9999 ( 80H 99H 99H )(準確值為-1.000)
;測試結果X3=2.000 ( 01H 20H 00H )
;測試結果X4=-2.000 ( 81H 20H 00H )
;測試結果X5=1.000 ( 01H 10H 00H )
DATS: DB 01H,30H,0H ;系數增廣矩陣A11=3.0
DB 01H,20H,0H ;A12=2.0
DB 41H,00H,0H ;A13=0.0
DB 01H,10H,0H ;A14=1.0
DB 81H,20H,0H ;A15=-2.0
DB 81H,30H,0H ;B1 =-3.0
DB 01H,10H,0H ;A21=1.0
DB 81H,10H,0H ;A22=-1.0
DB 01H,20H,0H ;A23=2.0
DB 01H,30H,0H ;A24=3.0
DB 01H,50H,0H ;A25=5.0
DB 01H,50H,0H ;B2 =5.0
DB 41H,00H,0H ;A31=0.0
DB 01H,30H,0H ;A32=3.0
DB 41H,00H,0H ;A33=0.0
DB 01H,20H,0H ;A34=2.0
DB 01H,10H,0H ;A35=1.0
DB 81H,60H,0H ;B3 =-6.0
DB 81H,10H,0H ;A41=-1.0
DB 41H,00H,0H ;A42=0.0
DB 01H,10H,0H ;A43=1.0
DB 01H,10H,0H ;A44=1.0
DB 41H,00H,0H ;A45=0.0
DB 81H,10H,0H ;B4 =-1.0
DB 01H,40H,0H ;A51=4.0
DB 01H,10H,0H ;A52=1.0
DB 01H,20H,0H ;A53=2.0
DB 81H,10H,0H ;A54=-1.0
DB 81H,10H,0H ;A55=-1.0
DB 01H,80H,0H ;B5 =8.0
LEQN: MOV DPH,#ANNB;指向系數存放頁面。
MOV P2,#ANNB;指向系數存放頁面。
MOV I,#0 ;從第一行(行號為0)開始處理。
LEQ: MOV A,I ;取將要處理的行號。
INC A
XRL A,#N
JZ LEQ1 ;如果是最后一行,不必尋找主元。
LCALL FINDMIN ;尋找主元,并將其所在行交換到當前處理行位置上。
LEQ1: LCALL DIVMIN ;將當前處理行的各個系數除以主元,使主元為1。
MOV K,#0 ;從第一行開始,進行消元處理。
LEQ2: MOV A,K ;取待消元行號。
XRL A,I
JZ LEQ3 ;如果是主元所在行號,則跳過。
LCALL DEL ;進行消元處理。
LEQ3: INC K ;調整到下一行。
MOV A,K
XRL A,#N
JNZ LEQ2 ;直到各行均進行過消元處理。
INC I ;調整尋找主元的行號。
MOV A,I
XRL A,#N
JNZ LEQ ;直到整個系數矩陣成為單位矩陣。
MOV I,#0 ;增廣矩陣的最后一列,就是方程組的解。
MOV J,#N
LCALL LOADH ;將其調入片內RAM中。
RET ;求解方程組的任務完成。
FINDMIN:MOV J,I ;尋找主元,定位主對角線系數。
LCALL LOADH ;將主對角線系數及其以下同一列的系數讀入片內。
MOV R0,#WORK;先設第一個系數為最大值。
MOV R1,#WORK+3;從第二個系數開始進行比較。
MOV A,#N ;計算比較的次數。
SETB C
SUBB A,I
MOV CON,A
MOV A,@R0 ;取絕對值。
CLR ACC.7
MOV @R0,A
MAX: MOV A,@R1 ;取絕對值。
CLR ACC.7
MOV @R1,A
LCALL FCMP ;比較。
JNC MAX1
MOV A,R1 ;以比較對象為新的最大值。
MOV R0,A
MAX1: INC R1 ;準備比較下一個系數。
INC R1
INC R1
DJNZ CON,MAX ;完成所有比較。
MOV A,R0 ;取最大值的地址。
CLR C
SUBB A,#WORK ;和主對角線系數的距離(字節數)。
JZ FINDE ;為零,主對角線系數就是最大值系數,不必交換。
MOV B,#3 ;將距離轉換為系數個數。
DIV AB
ADD A,I ;加上當前行號,
MOV K,A ;得到最大值所在行號。
MOV J,I ;主對角線系數的列號和行號相同。
LCALL ADDR ;計算主對角線系數的地址。
MOV R0,DPL ;保存地址在R0中。
PUSH I ;保存主對角線系數的行號。
MOV I,K ;將行號改為最大值的行號(列號不變)。
LCALL ADDR ;計算地址。
MOV R1,DPL ;保存地址在R1中。
POP I ;恢復主對角線系數的行號。
MOV A,#N+1 ;計算待交換系數的字節數。
CLR C
SUBB A,J
MOV B,#3
MUL AB
MOV R7,A
XCHG: MOVX A,@R0 ;交換兩行,使最大值系數處于主對角線上。
MOV R6,A
MOVX A,@R1
XCH A,R6
MOVX @R1,A
MOV A,R6
MOVX @R0,A
INC R1
INC R0
DJNZ R7,XCHG
FINDE: RET ;完成主元尋找和交換任務。
DEL: MOV J,I ;待消元的系數的列號等于主元的行號。
PUSH I ;保存主元的行號。
MOV I,K ;指向待消元的行號。
MOV A,#WORK ;指向片內工作區。
LCALL LOADL ;將待消元的一行系數調入片內工作區。
POP I ;恢復主元行號。
MOV A,#N ;計算需要調整數值的系數個數。
CLR C
SUBB A,J
MOV CON,A
MOV R0,#WORK+3;指向第一個待調整數值的系數A k , j。
MOV R1,#WORK1+3;指向主元數值行的第一個參照系數A i , j。
DEL1: MOV TEMP,WORK;將待消元的系數值A k , i復制到臨時變量中。
MOV TEMP+1,WORK+1
MOV TEMP+2,WORK+2
MOV A,R0
PUSH ACC
MOV R0,#TEMP
LCALL FMUL ;計算A k , i×A i , j→TEMP。
POP ACC
MOV R0,A
MOV A,R1
PUSH ACC
MOV R1,#TEMP
LCALL FSUB ;計算A k , j=A k , j-A k , i×A i , j
POP ACC
MOV R1,A
INC R0
INC R0
INC R0
INC R1
INC R1
INC R1
DJNZ CON,DEL1;將待消元行有關系數全部調整好。
MOV J,I ;主元所在的列號等于行號。
INC J ;加一,得到已調整系數的最小列號。
PUSH I
MOV I,K ;取已調整系數的行號。
MOV A,#WORK+3;取已調整系數在片內的首址。
LCALL SAVE ;將全部已調整系數存回到片外RAM原來位置上。
POP I ;恢復主元行號。
RET ;一行消元處理結束。
DIVMIN: MOV J,I ;主元所在行系數處理。
MOV A,#WORK1;指向輔助工作區。
LCALL LOADL ;將主元所在行的系數調入片內RAM中。
MOV R1,#WORK1;以主元作除數。
MOV R0,#WORK1+3;其右的系數作為第一個被除數。
MOV A,#N ;計算需要處理的系數個數。
CLR C
SUBB A,I
MOV CON,A
DMIN: LCALL FDIV ;進行除法運算A i , j=A i , j/A i , i。
INC R0
INC R0
INC R0
DJNZ CON,DMIN
MOV A,#WORK1+3;指向片內第一個已經處理的系數。
MOV J,I
INC J ;列號j=i+1。
SAVE: MOV R0,A ;片內首址。
LCALL ADDR ;計算片外首址。
MOV A,#N+1 ;計算回存字節數。
CLR C
SUBB A,J
MOV B,#3
MUL AB
MOV R7,A
SAVE1: MOV A,@R0 ;回存到片外。
MOVX @DPTR,A
INC DPTR
INC R0
DJNZ R7,SAVE1
RET
LOADL: MOV R0,A ;片內首址。
LCALL ADDR ;計算片外首址。
MOV A,#N+1 ;計算回存字節數。
CLR C
SUBB A,J
MOV B,#3
MUL AB
MOV R7,A
LOAD1: MOVX A,@DPTR ;調入到片內。
MOV @R0,A
INC DPTR
INC R0
DJNZ R7,LOAD1
RET
LOADH: MOV R0,#WORK;將一列系數調入WORK為首址片內RAM中。
MOV A,#N ;計算同一列相鄰系數中間間隔的字節數。
MOV B,#3
MUL AB
MOV R6,A
LCALL ADDR ;計算片外首址。
MOV A,#N ;計算調入系數個數。
CLR C
SUBB A,I
MOV R7,A
LOAD2: MOV R2,#3 ;每個系數為三個字節。
LOAD3: MOVX A,@DPTR ;調入一個系數。
MOV @R0,A
INC DPTR
INC R0
DJNZ R2,LOAD3
MOV A,DPL ;調整到同一列下一個相鄰系數的首址。
ADD A,R6
MOV DPL,A
DJNZ R7,LOAD2;將所需系數全部調入片內RAM中。
RET
ADDR: MOV B,#N+1 ;計算A i , j的片外地址(低八位)。
MOV A,I
MUL AB
ADD A,J
MOV B,#3
MUL AB
MOV DPL,A
RET
;以下是浮點運算子程序庫。
FADD: CLR F0
SJMP AS
FSUB: SETB F0
AS: LCALL MVR1
MOV C,F0
RRC A
XRL A,@R1
MOV C,ACC.7
ASN: MOV PFB,C
XRL A,@R0
RLC A
MOV F0,C
LCALL MVR0
LCALL AS1
MOV0: INC R0
INC R0
MOV A,R4
MOV @R0,A
DEC R0
MOV A,R3
MOV @R0,A
DEC R0
MOV A,R2
MOV C,PFA
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
MOV C,ACC.7
MOV PFA,C
MOV C,ACC.6
MOV ACC.7,C
MOV R2,A
INC R0
MOV A,@R0
MOV R3,A
INC R0
MOV A,@R0
MOV R4,A
DEC R0
DEC R0
RET
MVR1: MOV A,@R1
MOV C,ACC.7
MOV PFB,C
MOV C,ACC.6
MOV ACC.7,C
MOV R5,A
INC R1
MOV A,@R1
MOV R6,A
INC R1
MOV A,@R1
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,PFB
MOV PFA,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 PFA
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
FMUL: LCALL MVR0
MOV A,@R0
XRL A,@R1
RLC A
MOV PFA,C
LCALL MUL0
LJMP MOV0
MUL0: LCALL MVR1
MUL1: MOV A,R3
ORL A,R4
JZ MUL6
MOV A,R6
ORL A,R7
JZ MUL5
MOV A,R7
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
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
MOV A,@R0
XRL A,@R1
RLC A
MOV PFA,C
LCALL MVR1
LCALL DIV3
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -