存儲器讀寫實驗:
對RAM的30H、31H單元分别指派BCD碼75H、35H,試将兩個數相加,其BCD的差送32H單元。
(說明):
因為MCS-51的十進制調整指令不适合減法,是以可以把減法變成加法:将被減數-減數變成被減數+減數的補數,其中,減數的補數=BCD碼的模-減數。最後再用十進制加法指令,将被減數+減數的補數,所得值送往存儲器A,再存儲到32H單元即可。
(流程圖):
ORG 0000H
LJMP START
ORG 0020H
START: MOV R0,#30H
MOV R1,#31H
MOV 30H,#72H
MOV 31H,#35H
MOV A,#9AH
SUBB A,@R1
ADD A,@R0
DA A
MOV 32H,A
SJMP $
END
并行端口實驗:
利用單片機的兩個接口驅動四位一體LED數位管電路,要求在數位管上自右向左直接顯示RAM20H—23H中的“0,4,1,9”。
(說明):
待顯示的資料變量存儲在RAM的20H-23H中,對應的字形碼存儲在RAM的24H-27H中。與變量對應的字形碼通過查表擷取。根據電路特點,位驅動電平為低電平有效。子程式DELAY得延時決定每位數位管的點亮時間,可以通過修改DELAY中的延時參數來增加延時時間,進而觀察動态顯示的效果。
(流程圖):
ORG 0000H
LJMP START
ORG 0030H
START: MOV SP,#60H
MOV A,#00H
MOV R0,#20H
MOV @R0,A
MOV A,#4
INC R0
MOV @R0,A
INC R0
MOV A,#1
MOV @R0,A
INC R0
MOV A,#9
MOV @R0,A
MOV R0,#20H
MOV R1,#24H
MOV R2,#4
MOV DPTR,#LEDGY
LOOP1: MOV A,@R0
MOVC A,@A+DPTR
MOV @R1,A
INC R0
INC R1
DJNZ R2,LOOP1
LOOP2: MOV P1,#0FFH
MOV P0,24H
MOV P1,#0EFH
LCALL DELAY
MOV P1,#0FFH
MOV P0,25H
MOV P1,#0DFH
LCALL DELAY
MOV P1,#0FFH
MOV P0,26H
MOV P1,#0BFH
LCALL DELAY
MOV P1,#0FFH
MOV P0,27H
MOV P1,#07FH
LCALL DELAY
SJMP LOOP2
LEDGY: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H
DB 80H,90H,88H,83H,0C6H,0A1H,86H,8EH
DELAY PUSH 00H
PUSH 01H
MOV R1,#00H
LOOP3: MOV R0,#06H
DJNZ R0,$
DJNZ R1,LOOP3
POP 01H
POP 00H
RET
END
外部中斷實驗:
設計一個計數器,利用中斷程式完成對其每按五次便加一并顯示的功能,計數器原始清零。利用“邏輯筆”電路顯示P0.7的狀态:如果P0.7的電平不斷轉換,則表明系統在執行主程式,無中斷;如果P0.7變成固定的高電平,則表明系統進入中斷。
(說明):
設定/INT0中斷入口,在中斷服務程式中将P0.7置位為1。中斷程式中,每接受一次中斷,便對R3加一,将R3中的資料傳送到A中,對A除以5用來檢測是否接受中斷次數達到五次,達到後,将計數器加一并顯示。在每次讀取中斷時均加入延時程式用于軟體防抖。
(電路圖):
(流程圖):
ORG 0000H
LJMP START
ORG 0003H
LJMP INT_0
ORG 0030H
START: MOV SP,#60H
MOV TCON,#00H
MOV R3,#00H
MOV A,R3
SETB EX0 ;
SETB EA ;允許中斷
LOOP1: MOV P1,A
CPL P0.7
LCALL DELAY
SJMP LOOP1
INT_0: PUSH PSW
SETB P0.7
INC R3
MOV A,R3
MOV B,#5
DIV A B
MOV P1,A
LCALL DELAY
JNB P3.2,$
LCALL DELAY
POP PSW
RETI
DELAY: PUSH 01H
PUSH 02H
MOV R4,#12H
LOOP2: NOP
DJNZ R4,LOOP2
MOV R1,#00H
DELAY1: MOV R2,#00H
DJNZ R2,$
DJNZ R1,DELAY1
POP 02H
POP 01H
RET
END
定時計數器實驗:
分别利用T0,T1實作蜂鳴器以1Khz頻率鳴笛2s,并停1s,循環發聲的程式。
(說明):
利用定時/計數器T1,采用查詢法,設定初值0FE33H,,控制1KHZ的發聲頻率;利用定時/計數器T0,采用中斷法,設定初值4BFCH,每50MS中斷一次,采用循環來達到定時2s,停止1s的秒定時效果。
(電路圖):
(流程圖):
ORG 0000H
LJMP START
ORG 000BH
LJMP INT_0
ORG 0030H
START:
MOV SP,#60H
MOV TMOD,#11H ;T0、T1都工作在模式一
MOV TL0,#0FCH
MOV TH0,#4BH ;T0設定初值4BFCH,每50MS中斷一次
MOV TL1,#033H
MOV TH1,#0FEH ;T1設定初值0FE33H,,控制1KHZ的發聲頻率
SETB TR1
SETB TR0
SETB EA
SETB ET0
MOV A,#00H
MOV R0,#40 ;循環40次
LOOP:
CJNE A,#00H,DOWN
JNB TF1,$ ;使用查詢法
CLR TF1
MOV TL1,#033H
MOV TH1,#0FEH
JB F0,DOWN
CPL P1.1
DOWN: SJMP LOOP
INT_0: PUSH PSW ;使用中斷法
MOV TL0,#0FCH
MOV TH0,#4BH
DJNZ R0,EXIT
MOV R0,#20 ;循環20次
CJNE A,#00H,TURN
MOV A,#01H
SJMP EXIT
TURN: MOV A,#00H
MOV R0,#40
EXIT: POP PSW
RETI
END
TLC549串行AD轉換實驗、串行口實驗
将LED發光二極管LED1~LED8按順序與P1口連接配接,顯示從串行口接收的資料。當序列槽接受資料為FF0FH時,燈全亮;當序列槽接收資料為FF00H時,燈全滅;當序列槽接受資料為其他資料時,維持上一資料狀态。
(說明):
定時器T1工作在模式2,設定波特率初值為9600HZ,接收到資料後清除标志,首先判斷資料是否為0FH,若是,則向A指派0FFH并輸出,使燈全亮;若不是,則判斷是否為00H,若是,則向A指派00H并輸出,使燈全滅,若不是,則輸出上一次儲存的R1值,使燈保持原樣。
(電路圖):
(流程圖):
ORG 0030H
START:
MOV TMOD,#20H
MOV TL1,#0FDH ;送定時初值
MOV TH1,#0FDH
MOV PCON,#00H
SETB TR1
CLR RI
MOV SCON,#50H ;串行接口模式1(允許接受)
LOOP1:
JNB RI,LOOP1 ;判斷是否接受到資料
CLR RI ;接受資料後清空接受标志
MOV A,SBUF ;資料送累加器A
CJNE A,#0FH,ZERO ;判斷是否為最大值
MAX: MOV A,#0FFH ;向A賦0FFH
MOV R1,A
MOV P1,A ;從P1口輸出
SJMP LLL
ZERO:
CJNE A,#00H,DOWN ;判斷是否為0
MOV A,#00H ;向A賦#00H
MOV R1,A
MOV P1,A
SJMP LLL
DOWN: MOV A,R1 ;若輸入資料為其他值,将保持上一資料
MOV P1,A
SJMP LLL
LLL: SJMP LOOP1
END
ZLG7290B動态顯示實驗:
将LED發光二極管LED1~LED8按順序與P1口連接配接,顯示從串行口接收的資料。當序列槽接受資料為FF0FH時,燈全亮;當序列槽接收資料為FF00H時,燈全滅;當序列槽接受資料為其他資料時,維持上一資料狀态。
(說明):
将原從變量緩沖區得到的待顯示二進制數用序列槽方式接受資料得到。将從序列槽得到的兩位十六進制數除以10H,商送往31H,作高位;餘數送往30H,作低位,進而能讓資料能正确顯示在數位管上.
(流程圖):
SDA BIT P1.0
SCL BIT P1.1
WSLA EQU 070H
RSLA EQU 071H
ORG 0000H
LJMP START
;主程式
ORG 0030H
START: MOV SP,#60H
CLR P1.7 ;ZLG7290B複位
MOV TMOD,#20H
MOV TH1,#0fdh
MOV TH1,#0fdh ;送定時初值
MOV PCON,#00h
SETB TR1
CLR RI
MOV SCON,#50H ;串行接口模式1(允許接受)
LOOP1:
JNB RI,LOOP1 ;判斷是否接受到資料
CLR RI ;接受資料後清空接受标志
MOV A,SBUF ;資料送累加器A
SETB P1.7
MOV B,#10H
DIV AB
MOV R4,A
MOV A,B
MOV R3,A ;除以10H,得到商和餘數
MOV 30H,R3
MOV 31H,R4 ;商送往高位,餘數送往低位
LCALL DELAY
MOV DPTR,#LEDSEG ;開始對變量查表
CLR A
MOV R7,#02H
MOV R0,#20H
MOV R1,#30H
LOOP1:
MOV A,@R1
MOVC A,@A+DPTR ;查表得對應字形碼
MOV @R0,A ;送緩沖區
INC R1
INC R0
DJNZ R7,LOOP1
MOV R7,#02H
MOV R0,#20H
MOV R2,#10H
MOV R3,#WSLA
LCALL WRNBYT
SJMP LOOP
LEDSEG: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E4H;60H-61H
DB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EH
DELAY: PUSH 00H
PUSH 01H
MOV R0,#00H
DELAY1: MOV R1,#00H
DJNZ R1,$
DJNZ R0,DELAY1
POP 01H
POP 00H
RET
;以下為子程式
;*******************************************************************
;【提 示】下列程式是在系統時鐘為12MHZ(或11.0592MHZ),即NOP指令為1微秒左右。
;(1)帶有内部單元位址的多位元組寫操作子程式 WRNBYT
;*******************************************************************
;通用的I2C通訊子程式(多位元組寫操作)
;入口參數R7位元組數,R0源資料塊首位址
; R2從器件内部子位址;R3外圍器件位址(寫)
;相關子程式WRBYT、STOP、CACK、STA
;*******************************************************************
WRNBYT: PUSH PSW
PUSH ACC
WRADD: MOV A,R3 ;取外圍器件地位址(包含r/w=0)
LCALL STA ;發送起始信号S
LCALL WRBYT ;發送外圍位址
LCALL CACK ;檢測外圍器件的應答信号
JB F0,WRADD ;如果應答不正确傳回重來
MOV A,R2
LCALL WRBYT ;發送内部寄存器首位址
LCALL CACK ;檢測外圍器件的應答信号
JB F0,WRADD ;如果應答不正确傳回重來
WRDA: MOV A,@R0
LCALL WRBYT ;發送外圍位址
LCALL CACK ;檢測外圍器件的應答信号
JB F0,WRADD ;如果應答不正确傳回重來
INC R0
DJNZ R7,WRDA
LCALL STOP
POP ACC
POP PSW
RET
;*******************************************************************
;(2)帶有内部單元位址的多位元組讀操作子程式RDNBYT
;*******************************************************************
;通用的I2C通訊子程式(多位元組讀操作)
;入口參數R7位元組數;
;R0目标資料塊首位址;R2從器件内部子位址;
;R3器件位址(寫);R4器件位址(讀)
;相關子程式WRBYT、STOP、CACK、STA、MNACK
;*******************************************************************
RDNBYT: PUSH PSW
PUSH ACC
RDADD1:LCALL STA
MOV A,R3 ;取器件位址(寫)
LCALL WRBYT ;發送外圍位址
LCALL CACK ;檢測外圍器件的應答信号
JB F0,RDADD1 ;如果應答不正确傳回重來
MOV A,R2 ;取内部位址
LCALL WRBYT ;發送外圍位址
LCALL CACK ;檢測外圍器件的應答信号
JB F0,RDADD1 ;如果應答不正确傳回重來
LCALL STA
MOV A,R4 ;取器件位址(讀)
LCALL WRBYT ;發送外圍位址
LCALL CACK ;檢測外圍器件的應答信号
JB F0,RDADD1 ;如果應答不正确傳回重來
RDN: LCALL RDBYT
MOV @R0,A
DJNZ R7,ACK
LCALL MNACK
LCALL STOP
POP ACC
POP PSW
RET
ACK: LCALL MACK
INC R0
SJMP RDN
;**********************************************************************
;(3)I2C各個信号子程式
;**********************************************************************
; 啟動信号子程式S
;**********************************************************************
STA: SETB SDA ;啟動信号S
SETB SCL
NOP ;産生4.7US延時
NOP
NOP
NOP
NOP
CLR SDA
NOP ;産生4.7US延時
NOP
NOP
NOP
NOP
CLR SCL
RET
;**********************************************************************
; 停止信号子程式P
;**********************************************************************
STOP: CLR SDA ;停止信号P
SETB SCL
NOP ;産生4.7US延時
NOP
NOP
NOP
NOP
SETB SDA
NOP ;産生4.7US延時
NOP
NOP
NOP
NOP
SETB SCL ;釋放總線
SETB SDA
RET
;**********************************************************************
; 應答信号子程式 MACK
;**********************************************************************
MACK: CLR SDA ;發送應答信号ACK
SETB SCL
NOP ;産生4.7US延時
NOP
NOP
NOP
NOP
CLR SCL
SETB SDA
RET
;**********************************************************************
; 非應答法信号子程式MNACK
;**********************************************************************
MNACK: SETB SDA ;發送非應答信号NACK
SETB SCL
NOP ;産生4.7US延時
NOP
NOP
NOP
NOP
CLR SCL
CLR SDA
RET
;**********************************************************************
; 應答檢測子程式CACK
;**********************************************************************
CACK: SETB SDA ;應答位檢測子程式
SETB SCL
CLR F0
MOV C,SDA ;采樣SDA
JNC CEND ;應答正确時轉CEND
SETB F0 ;應答錯誤時F0置一
CEND: CLR SCL
RET
;**********************************************************************
; 發送一個位元組子程式WRBYT
;**********************************************************************
WRBYT: PUSH 06H
MOV R6,#08H ;發送一個位元組子程式
WLP: RLC A ;入口參數A
MOV SDA,C
SETB SCL
NOP ;産生4.7US延時
NOP
NOP
NOP
NOP
JNB SCL,$
CLR SCL
DJNZ R6,WLP
POP 06H
RET
;**********************************************************************
; 接收一個位元組子程式RDBYT
;**********************************************************************
RDBYT: PUSH 06H
MOV R6,#08H ;接收一個位元組子程式,出口參數R2
RLP: SETB SDA
SETB SCL
JNB SCL,$
MOV C,SDA
MOV A,R2
RLC A
MOV R2,A
CLR SCL
DJNZ R6,RLP
POP 06H
RET
;**********************************************************************
END
;**********************************************************************