欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: STC8G單片機MDU16位乘除法器C語言改匯編程序 [打印本頁]

作者: dalaoshi    時間: 2021-4-10 01:02
標題: STC8G單片機MDU16位乘除法器C語言改匯編程序
最近需要用到16位乘16位,記得STC有硬件的16位乘除法器,看了說明書,找到了例程,卻只有C語言的,看來匯編已經快被拋棄了,只好自己改寫,C語言就是一堆難懂的符號,像這句“ARCON = 4 << 5;    //16位*16位,乘法模式"就看不懂,但只要看原理說明就知道,這乘除法器就設在傳統(tǒng)51單片結構外,利用一個P_SW2的寄存器做開關,開關打開后,就可以用DPTR指針往外面的寄存器(MD0-MD5)賦值,再打開一個外面的開關OPCON,就會開始運算,等若干時鐘后把運算結果讀進來,再把P_SW2關閉就可以了。明白了原理后寫匯編就很簡單了。為了驗證寄存器沒有搞錯,將結果通過UART1顯示出來,網上有不少HEX的運算器,我把數(shù)字放上去計算,出來的結果都看不懂,最后是把16位的乘數(shù)和被乘數(shù)都轉換成是進制,再用五元的家用計算器算出結果,再把結果轉為HEX,0107HX0208H=00021638H,答案正確吧?

;C語言:

;============================================
;16位乘以16位乘法:被乘數(shù):{MD1,MD0} 乘數(shù):{MD5,MD4} 積:{MD3,MD2,MD1,MD0}

;define MD3 (*(unsigned char volatile xdata *)0xfcf0)
;#define MD2 (*(unsigned char volatile xdata *)0xfcf1)
;#define MD1 (*(unsigned char volatile xdata *)0xfcf2)
;#define MD0 (*(unsigned char volatile xdata *)0xfcf3)
;#define MD5 (*(unsigned char volatile xdata *)0xfcf4)
;#define MD4 (*(unsigned char volatile xdata *)0xfcf5)
;#define ARCON (*(unsigned      char volatile xdata *)0xfcf6)
;#define OPCON (*(unsigned      char volatile xdata *)0xfcf7)
;sfr              P_SW2                =              0xBA;            
;////////////////////////////////////////////////////////////////////////////////
;//16位乘16位//////////////////////////////////////////////////////////////////////////////
;// unsigned long res; unsigned int dat1, dat2;
;P_SW2 |= 0x80;     //訪問擴展寄存器xsfr
;MD1U16 = dat1;     //dat1用戶給定MD5U16 = dat2; //dat2用戶給定
;ARCON = 4 << 5;    //16位*16位,乘法模式
;OPCON = 1;         //啟動計算
;while((OPCON & 1) != 0); //等待計算完成
;res = MD3U32; //32位結

;匯編:
HEADBUFFER1 EQU 0A0H
LASTBUFFER1 EQU 0FFH   ;第一組緩沖區(qū)
AUXR EQU 8EH
AUXR2 EQU 0A2H
WAKE_CLKO EQU 08FH   

MD0 EQU 0FCF3H
MD1 EQU 0FCF2H
MD2 EQU 0FCF1H
MD3 EQU 0FCF0H
MD4 EQU 0FCF5H
MD5 EQU 0FCF4H
ARCON EQU 0FCF6H
OPCON EQU 0FCF7H
P_SW2 EQU 0BAH            ;當需要訪問 XFR 時,必須先將 EAXFR 置 1,才能對 XFR 進行正常的讀寫

ORG 0000H
LJMP MAIN
ORG 0023H
LJMP UART1    ;UART1 RECEIVED INTERRUPT
ORG 0100H

MAIN:
LCALL DELAY1  ;用STC-ISP的串口助手,必須給點時間切換,否則上載后來不及接收結果(00 02 16 38)接收口波特率為115200 晶振:11.0592 STC8G2K32S4
LCALL DELAY1
LCALL DELAY1

LCALL IOSET

CLR P1.0

MOV WAKE_CLKO,#00000001B     ;ENABLE BRT(=4),T1(=2) T0(=1) HAVE CLOCK OUTPUT BRT@P1.0 T1@P3.5 T0@P3.4
MOV AUXR,#11111100B          ;T0X12,T1X12,UART_M0X6,BRTRUN,S2SMOD,BRTX12,EXTRAM,S1BRS
MOV AUXR2, #00000000B        ;#00010000B=SHIFT UART2
MOV TMOD, #00100010B         ;TIMER0, TIMER1 AS MOD2(8 BYTE AUTO RELOAD TIMER)
                             ;GATE, C/T,M1,M0(T1) GATE, C/T,M1,MO(T0)
MOV PCON, #00000000B         ;THIS DOUBLE THE BRT AND T0 T1 RATE; SMOD IS AT PCON.7 249(3.64=32US) 219(18M= 2USX16=32US MIDI VIEW AT P3.5)

LCALL INITIAL_UART1        ;USE T1 AS SERIAL BAUD GENERATE FOR UART1
CLR RI
CLR TI
SETB  EA                  ;ENABLE ALL INTERRUPT

MOV P_SW2,#80H            ;訪問X寄存器打開

MOV DPTR,#MD1             ;
MOV A, #01H               ;必須通過A才能送到
MOVX @DPTR,A

MOV DPTR,#MD0             ;
MOV A, #07H               ;必須通過A才能送到
MOVX @DPTR,A

MOV DPTR,#MD5             ;
MOV A, #02H               ;必須通過A才能送到
MOVX @DPTR,A

MOV DPTR,#MD4             ;
MOV A, #08H               ;必須通過A才能送到
MOVX @DPTR,A

MOV DPTR,#ARCON           ;
MOV A, #10000000B         ;b7,b6,b5 4=16X16 5=16/16
MOVX @DPTR,A

MOV DPTR,#OPCON           ;啟動運算
MOV A, #00000001B            
MOVX @DPTR,A

WAIT:
MOVX A, @DPTR
ANL A, #00000001B
JNZ  WAIT

MOV DPTR, #MD3            
MOVX A, @DPTR

LCALL SENTONEBYTE1

MOV DPTR,#MD2           
MOVX A, @DPTR

LCALL SENTONEBYTE1

MOV DPTR, #MD1            
MOVX A, @DPTR

LCALL SENTONEBYTE1

MOV DPTR,#MD0         
MOVX A, @DPTR

LCALL SENTONEBYTE1

MOV P_SW2,#00H            ;訪問完畢要關閉

LED:                      ;停機

JMP LED

NEXTBUFFER:
CJNE R0, #LASTBUFFER1, NEXTBUFFER2
MOV R0, #HEADBUFFER1
JMP NEXTBUFFEREXIT
NEXTBUFFER2:
INC R0  ;POINT TO NEXT BYTE
NEXTBUFFEREXIT:
RET

SENTONEBYTE1:                ;SENT OUT A
CHECKBUSY1:
JB 40H, CHECKBUSY1
SETB 40H
MOV SBUF, A
RET

UART1:      ;RECEIVED DATA FROM AIR
PUSH ACC
PUSH PSW
JNB RI, UART1CHECKTI
MOV A, SBUF ;READ THE CHARACTER FROM THE SERIAL PORT
CLR RI      ;CLEAR RECEICED FLAG
MOV @R1, A  ;SAVE TO BUFFER
CJNE R1, #LASTBUFFER1, NEXTREADBUFFER
MOV R1, #HEADBUFFER1
JMP UART1EXIT
NEXTREADBUFFER:
INC R1  ;POINT TO NEXT BUFFER
JMP UART1EXIT
UART1CHECKTI:
CLR TI
CLR 40H      
UART1EXIT:
POP PSW
POP ACC
RETI

INITIAL_UART1:           ;115200
MOV SCON, #01010000B     ;SET AS BAUD VERIABLE, NO ODD/EVEN CHECK
MOV TH1, #253            ;247(11.0592, 38400BPS) FOR TIMER_1 251=115200(18.4320M 115200BPS) 253(11.0592M 115200BPS) IF PCON.7=0   
MOV TL1, #253
SETB PS                  ;SERIAL PORT PRORITY HIGH
SETB TR1                 ;RUN TIMER_1
SETB ES                  ;ENABLE UART1 INTERRUPT
RET

IOSET:
;-----------I/O CONFIGUE
MOV 93H, #00000000B      ;SET P0 0,0=I/0, 0,1=HIGH CURRENT OUTPUT, 1,0=HIGH IMPEDENY INPUT 1,1=OPEN COLLECTIVE OUTPUT
MOV 94H, #00000000B      ;SET P0 (CONMAIN WITH 93H THIS IS SENCOND BIT)
MOV 91H, #00000000B      ;SET P1
MOV 92H, #00000000B      ;SET P1
MOV 95H, #00000000B      ;SET P2
MOV 96H, #00000000B      ;SET P2
MOV 0B1H, #00000000B     ;SET P3
MOV 0B2H, #00000000B     ;SET P3
MOV 0B3H, #00000000B     ;SET P4
MOV 0B4H, #00000000B     ;SET P4
MOV 0C9H, #00000000B     ;SET P5
MOV 0CAH, #00000000B     ;SET P5
;MOV 0CBH, #00000000B     ;SET P6
;MOV 0CCH, #00000000B     ;SET P6
;MOV 0E1H, #00000000B     ;SET P7
;MOV 0E2H, #00000000B     ;SET P7
RET

DELAY1:
LCALL DELAY2
LCALL DELAY2
SETB P1.0
LCALL DELAY2
LCALL DELAY2
CLR P1.0
RET

DELAY2:
MOV 35H, #255
SLOWDOWN0:
MOV 34H, #170
SLOWDOWN:
MOV 36H, #2
SLOWDOWN2:
DJNZ 36H, SLOWDOWN2
DJNZ 34H, SLOWDOWN
DJNZ 35H, SLOWDOWN0
RET

END



作者: youlinys    時間: 2022-3-9 21:59
感謝朋友的代碼
作者: haokanma77    時間: 2022-4-26 09:53
感謝朋友的乘除法代碼
作者: dalaoshi    時間: 2022-5-28 00:46
用“逼”作匯編位運算的思考:

ANL:
11001100   原值
11010000   逼值
11000000   結果   

ANL是用來逼0的,逼值放0的位結果全變?yōu)?,放1的結果保留原值,用來保留你要的有效位。

ORL:
11001100   原值
11010000   逼值
11011100   結果
   
ORL是用來逼1的,逼值放1的位結果全變?yōu)?,放0的結果保留原值,用來打開你要的某個位,而而其他位維持不變。

XOL:
11001100   原值
11010000   逼值
00011100   結果   

XOL是用來比較每個位的,相等的位就變0,不等的位就變1


作者: hhh402    時間: 2022-6-3 01:16
這么復雜誰用?直接計算就好,慢不了多少,單片機主要是控制IO,復雜計算留給上位機。
作者: lijn    時間: 2022-6-6 11:27
感謝樓主的解析,請教  UART1是常用的串口軟件嗎?
作者: dalaoshi    時間: 2022-6-6 16:06
lijn 發(fā)表于 2022-6-6 11:27
感謝樓主的解析,請教  UART1是常用的串口軟件嗎?

UART不是常用,而是必不可少(除非只是想點亮一個LED而已),開發(fā)過程中可以用來輸出結果,在PC上查看,STC的燒錄軟件可以在燒錄后即可打開UART接收來自單片機UART1的數(shù)值,非常方便。
作者: lijn    時間: 2022-6-30 17:04
請教樓主,目前STC已經有32位單片機,用匯編程序也行嗎?

作者: dalaoshi    時間: 2022-6-30 17:28
lijn 發(fā)表于 2022-6-30 17:04
請教樓主,目前STC已經有32位單片機,用匯編程序也行嗎?

我還沒有玩STC32,因為還沒有必要用到32位,估計也不算難,學會匯編底子好,你先玩玩看。
作者: zhxzhx    時間: 2022-6-30 18:09
說C看不懂的,就是給自己找理由,C有的概念,匯編都有,
你要愿意,完全可以把C寫成匯編
作者: dalaoshi    時間: 2022-7-29 03:12
近日有所發(fā)現(xiàn),KEIL4在編譯匯編語言的時候,無法發(fā)現(xiàn)偽指令ORG所指定的位置會覆蓋生成的代碼部分,比如:

ORG 0000H ;開頭部分
LJMP MAIN
ORG 0003H
LJMP EXT_INT0 ;EXTERNAL INTERRUPT0
ORG 000BH
LJMP TIMER_0  ;TIMER0 INTERRUPT
ORG 0013H
LJMP EXT_INT1 ;EXTERNAL INTERRUPT1
ORG 001BH
LJMP TIMER_1  ;TIMER1 INTERRUPT
ORG 0023H
LJMP UART1    ;UART1 RECEIVED INTERRUPT
ORG 002BH
LJMP ADC      ;T2
ORG 0033H
LJMP LVD
ORG 003BH
LJMP PCA
ORG 0043H
LJMP UART2    ;UART2 RECEIVED INTERRUPT
ORG 004BH
LJMP SPI
ORG 0100H     

------------程序部分-----------

ORG 1700H ;數(shù)據(jù)部分(共256字節(jié))
DB 00H,40H,41H,3EH,41H,40H,41H,3CH,41H,40H,41H,3EH,41H,40H,00H,3BH ;0 16 0F
DB 41H,40H,41H,3EH,41H,40H,41H,3CH,41H,40H,41H,3EH,41H,40H,41H,39H ;0 16 1F
DB 41H,40H,41H,3EH,41H,40H,41H,3CH,41H,40H,41H,3EH,41H,40H,41H,3BH ;0 16 2F
DB 41H,40H,41H,3EH,41H,40H,41H,3CH,41H,40H,41H,3EH,41H,40H,41H,37H ;0 16 3F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 4F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 5F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 6F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 7F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 8F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 9F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 AF
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 BF
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 CF
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 DF
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 EF
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 FF

編譯之后,顯示CODE=6144 (1800H) ,如果將數(shù)值部分(ORG 1700H)部分COMMENT, 編譯后
CODE=5926 (1726H),  顯然如果包含ORG 1700H 的數(shù)值,CODE的后面26H字節(jié)會被覆蓋, 上載到單片機后會出現(xiàn)意想不到的錯誤,如果不能警覺這個問題,會DEBUG到暈倒,把 ORG 改為1800H后,一切就正常了,但為什么編譯器不會發(fā)現(xiàn)問題,沒有任何警告呢?
作者: 188610329    時間: 2022-7-29 03:59
dalaoshi 發(fā)表于 2022-7-29 03:12
近日有所發(fā)現(xiàn),KEIL4在編譯匯編語言的時候,無法發(fā)現(xiàn)偽指令ORG所指定的位置會覆蓋生成的代碼部分,比如:
...

所以, 如果需要絕對定位的盡量用 CSEG AT 1700H  這樣的格式, 盡量不要用 ORG 1700H 這樣的格式。
假如不需要絕對定位,就盡量用 RSEG 讓KEIL來自動 分配。就不會出現(xiàn)你遇到的問題了。
作者: Y_G_G    時間: 2022-7-29 06:44
dalaoshi 發(fā)表于 2022-7-29 03:12
近日有所發(fā)現(xiàn),KEIL4在編譯匯編語言的時候,無法發(fā)現(xiàn)偽指令ORG所指定的位置會覆蓋生成的代碼部分,比如:
...

STM32搞了個代碼生成軟件,引腳選好了,就生成代碼給你,復制就行,為什么呢?因為ST覺得直接用C語言去寫代碼太麻煩了,給你點幾下鼠標就有代碼了
你倒好,覺得C看不明白,倒退回去用匯編
在單片機片上資源越來越豐富的今天,匯編只能不斷的放棄自己的江山
玩單片機,會匯編是好事,但并不是說什么都是匯編
而且,不是我說你,你就算是用匯編,但也對匯編并不了解,竟然去懷疑編譯器
在你使用了ORG 1700H之后,1700H以前空間都會被使用,不管有沒有代碼,代碼長度都是以ORG 1700H+后面占用的空間為總長度,那么你這個代碼總長度就是1700H+所有的DB=1800H
如果你不用ORG 1700H,代碼總長度就是你其它代碼+DB占用的空間
可以計算出來,你匯編的代碼如果沒有DB這一部分,長度就是:5670
這么多的代碼,估計問題就出在別的地方,要么是這DB部分放在代碼中間了,查表的時候也許是指針指過頭了,程序就到處跑
作者: dalaoshi    時間: 2022-7-29 17:53
Y_G_G 發(fā)表于 2022-7-29 06:44
STM32搞了個代碼生成軟件,引腳選好了,就生成代碼給你,復制就行,為什么呢?因為ST覺得直接用C語言去寫代碼 ...

開始寫的時候,把表放在1700H就覺得很夠了,后來程序越寫也大,終于超過1700H的范圍,而編譯器編譯時沒有任何警告,上載后運作就發(fā)生異常了,我之所以能比較快意識到這個問題是因為我貼了一段新代碼在最末尾,運作時發(fā)現(xiàn)該代碼沒有運作,將該段代碼轉到中間部分,再運行時該代碼就有運作了,這才發(fā)現(xiàn)問題所在,為了讓其他用匯編的網友警覺,就貼上來分享了。

C語言的確強大和省事,但只會用C語言永遠不可能玩出D,F(xiàn),G。。語言的。
作者: Hephaestus    時間: 2022-7-29 18:50
dalaoshi 發(fā)表于 2022-7-29 17:53
開始寫的時候,把表放在1700H就覺得很夠了,后來程序越寫也大,終于超過1700H的范圍,而編譯器編譯時沒有 ...

編譯的時候絕對不可能報錯或者警告的,如果你了解編譯連接過程的話。如果要警告,那也是BL51.exe連接器給出警告。
作者: Y_G_G    時間: 2022-7-29 19:16
dalaoshi 發(fā)表于 2022-7-29 17:53
開始寫的時候,把表放在1700H就覺得很夠了,后來程序越寫也大,終于超過1700H的范圍,而編譯器編譯時沒有 ...

這本身就是你的問題呀
編譯器只會執(zhí)行你的代碼,它只會識別語法和硬件上的錯誤,比如RAM使用過頭了,或者是少了個逗號沒寫
至于代碼本身的邏輯問題,它是不會有什么警告的
匯編只有在個別極限要求下,比如時序嚴格到一個時鐘,或者是內存實在太小的情況下,還有優(yōu)勢
其它的,什么所謂效率,了解硬件的.......一點優(yōu)勢都沒有
玩單片機的,只會C不會匯編的人,大有人在,你敢說他們的技術都是在你之下?
嚴格遵循C語言規(guī)范寫出來的程序,不見得比匯編差
不知道你玩不玩王者
匯編只作為一個BUFF,有BUFF你就打得過人家?
我之前就是用匯編的,現(xiàn)在基本就是只要能用C的,絕對不用匯編,連都不想看一眼
作者: 622323wjl    時間: 2025-7-1 10:05
用“逼”作匯編位運算的思考:  ANL: 11001100   原值 11010000   逼值 11000000   結果     ANL是用來逼0的,逼值放0的位結果全變?yōu)?,放1的結果保留原值,用來保留你要的有效位。  ORL: 11001100   原值 11010000   逼值 11011100   結果     ORL是用來逼1的,逼值放1的位結果全變?yōu)?,放0的結果保留原值,用來打開你要的某個位,而而其他位維持不變。  XOL: 11001100   原值 11010000   逼值 00011100   結果     XOL是用來比較每個位的,相等的位就變0,不等的位就變1
作者: dalaoshi    時間: 2025-11-4 02:05
這是STC官方說明書的內容:

7.2.1 內部 RAM
內部 RAM 共 256 字節(jié),可分為 2 個部分:低 128 字節(jié) RAM 和高 128 字節(jié) RAM。低 128 字節(jié)的數(shù)據(jù)存儲
器與傳統(tǒng) 8051 兼容,既可直接尋址也可間接尋址。高 128 字節(jié) RAM(在 8052 中擴展了高 128 字節(jié) RAM)
與特殊功能寄存器區(qū)共用相同的邏輯地址,都使用 80H~FFH,但在物理上是分別獨立的,使用時通過不同的
尋址方式加以區(qū)分。高 128 字節(jié) RAM 只能間接尋址,特殊功能寄存器區(qū)只可直接尋址。


讀了很多遍了,但有時還會混淆:

1. 建議把堆棧SP從07H移動到80H:因為隨著堆棧增多會用到08H,09H,0AH,0BH,這是另外三組R0-R7的位置,這些存取都是能直接尋址的,如果程序需要用到這三組R0-R7,就得移到80H,這時堆棧增長是81H,82H,83H,84H,而這部分的RAM是必須用間接尋址才能存取的,而堆棧無論是在07H或80H都能自己推入或拉出,是超能力的,而程序員就必須記住這兩個區(qū)得用不同的尋址,很容易搞昏,我早期都把BUFFER放在80H開始的位置,一直要注意SP是指向那里,擔心SP會破環(huán)BUFFER,今晚讀了說明書,做了這個筆記,避免以后又搞混了。最后納悶的是,功能存儲器都在80H以后的位置,都是直接尋址的,而00H-7FH的直接尋址為何不是另外128個特殊功能存儲器?而是RAM,而這部分的RAM也可以間接尋址,更加亂了。這應該是早期8031留下的胎記,沒得怨,記下就好了。
作者: 188610329    時間: 2025-11-4 13:15
dalaoshi 發(fā)表于 2025-11-4 02:05
這是STC官方說明書的內容:

7.2.1 內部 RAM

說起來,你用 KEIL 匯編編程 也用了那么久了, 就沒有好好學習一下 KEIL A51 的各種功能么?
但凡,你打開 STARTUP.A51 文件 認真看一下,但凡 KEIL A51 的幫助 稍微 瀏覽一下,你這些問題都不會存在了。
雖然,本質上  51 單片機 的 堆棧 是 由 SP 來決定的。但是, SP 的設定,一般不需要手動介入。
首先用  SEGMENT DATA  和 SEGMENT IDATA  定義你需要用的變量。
定義完所有的變量之后,直接定義 STACK 然后 SP 指向 STACK 就不可能存在覆蓋問題。
而且,SEGMENT 來定義IDATA 的好處是,你不會和寄存器搞錯。當你定義了 IDATA 然后 直接尋址訪問的話,KEIL 會 出警告。
你可以喜歡用匯編,我也喜歡用匯編。但是,既然用 KEIL 來編程,而不是用 寫字板 來寫代碼,那么,該用的偽指令就要用起來,對你編程是有好處的。
作者: lwylwy1    時間: 2025-11-5 11:34
建議你寫個CMDU16位乘除法函數(shù),再反匯編就OK了

作者: dalaoshi    時間: 2025-11-5 15:39
188610329 發(fā)表于 2025-11-4 13:15
說起來,你用 KEIL 匯編編程 也用了那么久了, 就沒有好好學習一下 KEIL A51 的各種功能么?
但凡,你打 ...

原來KEIL還有這么多偽指令,我卻只懂ORG和EQU,上一次的那個程序碼超過了ORG的定位卻沒有接到警告也是因為沒有使用偽指令的緣故。不過折騰了這么久也就摸清了8051的結構,應用起來也就靈活了。

SP移到80H后,預留32字節(jié)應該夠用,后面0AH到FFH用作串口的接收緩存,用MOV, @R0來存取,這都是用到所謂“內部RAM”,后來才知道用MOVX,@R0就可以把緩存放在“外部RAM”,這時整個00H-FFH都可以用了,但因為沒有修改緩存范圍:FIRSTBUFFER EQU 80H LASTBUFFER EQU 0FFH, 每當看見MOV SP, 80H, 就會懷疑是否沖突了,但程序明明會跑,是自己沒有確定的觀念。


作者: 188610329    時間: 2025-11-5 22:08
dalaoshi 發(fā)表于 2025-11-5 15:39
原來KEIL還有這么多偽指令,我卻只懂ORG和EQU,上一次的那個程序碼超過了ORG的定位卻沒有接到警告也是因 ...

建議 了解一下 匯編中 "段(Segment)" 的概念. STC單片機原理及應用(第1到第6章)-2015-4-9.part1.rar (20 MB, 下載次數(shù): 0) STC單片機原理及應用(第1到第6章)-2015-4-9.part2.rar (20 MB, 下載次數(shù): 0) STC單片機原理及應用(第1到第6章)-2015-4-9.part3.rar (20 MB, 下載次數(shù): 0) STC單片機原理及應用(第1到第6章)-2015-4-9.part4.rar (1.96 MB, 下載次數(shù): 0)

STC單片機原理及應用目錄-2015-4-9.pdf (4.78 MB, 下載次數(shù): 0)


建議你看看此書 第五章 你寫出來的代碼會大不一樣。

作者: lxh0508    時間: 2025-11-6 09:40
純好奇,不懂C語言的話,如果需要用網絡比如以太網、canopen等,都是自己用匯編重新寫一遍嗎?如果需要經常換單片機,每次都重寫,老板能理解嗎?
作者: dalaoshi    時間: 2025-11-6 15:12
188610329 發(fā)表于 2025-11-5 22:08
建議 了解一下 匯編中 "段(Segment)" 的概念.

謝謝,會認真研讀。
作者: dalaoshi    時間: 2025-11-6 15:27
lxh0508 發(fā)表于 2025-11-6 09:40
純好奇,不懂C語言的話,如果需要用網絡比如以太網、canopen等,都是自己用匯編重新寫一遍嗎?如果需要經常 ...

C語言用來吃飯用,A語言用來鉆研用,像51這樣的單片機,用A語言就很夠了,而且沒有任何煩惱,所有問題都是自己學藝不精造成的,與中間語言(C語言)無關。
作者: 188610329    時間: 2025-11-6 18:17
lxh0508 發(fā)表于 2025-11-6 09:40
純好奇,不懂C語言的話,如果需要用網絡比如以太網、canopen等,都是自己用匯編重新寫一遍嗎?如果需要經常 ...

有一種編程方式,叫混編,即C語言,A語言混合編寫。可以自己用匯編,然后調用別人的 C 語言 函數(shù)。也可以自己用C 調用別人的A語言函數(shù)。甚至可以把 C 語言的函數(shù),或者 A語言的函數(shù) 封裝成庫,那么也不存在 是 C 語言 還是 匯編的壁壘了。調用庫就完了。
比如,當你用 printf  的時候,你知道他是用匯編寫的么?

最后,純個人習慣,一個外設剛拿到手的時候,是直接調用。等到研究深了,我還是喜歡自己用匯編重新寫一遍。




歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1