感謝大大的鼓勵 ,對阿...有這個就方便多了,不需要去借很大隻的示波器,我個人覺得蠻方便的@Q@
現在不知道為什麼不能貼檔案.圖片也限制檔案類型與大小,程式只好貼在下面:
CH1 REG P2.0
CH2 REG P2.1
COUNT EQU 37H
CUT EQU 39H
PWM0 EQU 40H ;
PWM1 EQU 41H ;
PWM2 EQU 42H ;
PWM3 EQU 43H ;
PWM4 EQU 44H ;
PWM5 EQU 45H ;
PWM6 EQU 46H ;
PWM7 EQU 47H ;
F EQU 50H
PIN EQU 51H
PWM EQU 52H ;目前被我拿來解決LOW的部分
PIN1 EQU 53H
;------------------------------------------------------
ORG 00H
AJMP START
;ORG 0BH
;LJMP T0_INT ;timer0中斷
;ORG 1BH
;LJMP T1_INT ;timer1中斷
ORG 30H
START:
MOV SP,#5FH ;設定堆疊區60H-7FH(固定用法)
MOV DPTR,#TABLE ;查表法,將TABLE的位址傳入DPTR的暫存器
MOV TMOD,#00010001B ;設定 TIMER1 作業於模式 1,TIMER0 作業於模式 1
;---------------------------------------------------------
;MOV TH0,#>(65536-40) ;設定TIMER0在每40us中斷一次,if use12Mhz crystal
;MOV TL0,#<(65536-40)
;MOV TH1,#>(65536-10000);設定TIMER1在每10ms計時一次,if use12Mhz crystal(以12MHZ基礎週期為1us)
;MOV TL1,#<(65536-10000)
;--------------------------------------------------------
SETB EA
;SETB ET0 ;啟用TIMER0中斷
;SETB ET1 ;啟用TIMER1中斷
MOV CUT,#0 ;賦予解譯旗標CUT歸零(沒用到)
MOV COUNT,#0 ;暫存R0位址的值
;--------------------------------------------------------------------------------
;通道判斷
;--------------------------------------------------------------------------------
MAIN:
MOV R1,#0H
MOV R2,#5H
LOOP:
MOV A,R1
MOVC A,@A+DPTR ;將TABLE裡第一個定義的值存入A
MOV PWM0,A ;將A的值推入PWM0
INC R1
MOV A,R1
MOVC A,@A+DPTR
MOV PWM1,A
INC R1
MOV A,R1
MOVC A,@A+DPTR
MOV PWM2,A
INC R1
MOV A,R1
MOVC A,@A+DPTR
MOV PWM3,A
INC R1
MOV A,R1
MOVC A,@A+DPTR
MOV PWM4,A
INC R1
MOV A,R1
MOVC A,@A+DPTR
MOV PWM5,A
INC R1
MOV A,R1
MOVC A,@A+DPTR
MOV PWM6,A
INC R1
MOV A,R1
MOVC A,@A+DPTR
MOV PWM7,A
INC R1
ACALL OUT ;短距離呼叫
DJNZ R2,LOOP ;R2不=0則跳回LOOP,=0則回到MAIN
LJMP MAIN ;遠程跳躍
;--------------------------------------------------------------------------------
TABLE:
DB 0CH,0CH,0CH,0CH,0CH,0CH,0CH,0CH ;先置中(1.5ms的high訊號)
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 06H,06H,06H,06H,06H,06H,06H,06H
DB 12H,12H,12H,12H,12H,12H,12H,12H
DB 19H,19H,19H,19H,19H,19H,19H,19H
;---------------------------------------------------
;輪序迴圈
;---------------------------------------------------
OUT:
MOV R0,#40H
C0: SETB P1.0
MOV R7,#13 ;每一格"H"的時間,視需要微調
ACALL DEL_H ;1ms
ACALL PWM_WIDTH
CLR P1.0
ACALL DEL_L
C1: SETB P1.1 ;R0=41H
MOV R7,#13 ;每一格"H"的時間,視需要微調
ACALL DEL_H ;1ms
ACALL PWM_WIDTH
CLR P1.1
ACALL DEL_L
C2: SETB P1.2 ;R0=42H
MOV R7,#13 ;每一格"H"的時間,視需要微調賦,目前改成延時0.1ms
ACALL DEL_H ;1ms
ACALL PWM_WIDTH
CLR P1.2
ACALL DEL_L
C3: SETB P1.3 ;R0=43H
MOV R7,#13 ;每一格"H"的時間,視需要微調
ACALL DEL_H ;1ms
ACALL PWM_WIDTH
CLR P1.3
ACALL DEL_L
C4: SETB P1.4 ;R0=44H
MOV R7,#13 ;每一格"H"的時間,視需要微調
ACALL DEL_H ;1ms
ACALL PWM_WIDTH
CLR P1.4
ACALL DEL_L
C5: SETB P1.5 ;R0=45H
MOV R7,#13 ;每一格"H"的時間,視需要微調
ACALL DEL_H ;1ms
ACALL PWM_WIDTH
CLR P1.5
ACALL DEL_L
C6: SETB P1.6 ;R0=46H
MOV R7,#13 ;每一格"H"的時間,視需要微調
ACALL DEL_H ;1ms
ACALL PWM_WIDTH
CLR P1.6
ACALL DEL_L
C7: SETB P1.7 ;R0=47H
MOV R7,#13 ;每一格"H"的時間,視需要微調
ACALL DEL_H ;1ms
ACALL PWM_WIDTH
CLR P1.7
ACALL DEL_L
;DJNZ R3,OUT ;因為輪序迴圈執行共20ms x 250次 = 5秒(顯示五秒)
RET
;--------------------------------------------------------------------------------
PWM_WIDTH:
MOV COUNT,@R0
LOOP1:
;SETB TR0 ;開啟T0計數器
;CLR TR0 ;關閉T0計數器
MOV R4,#0AH ;10次
LOOP4:
NOP ;每個 nop 延時 1us
NOP
DJNZ R4,LOOP4 ;R4=0時跳下一行=>(1us+1us+2us)X10 = 40us,此行本身要2us
DJNZ COUNT,LOOP1 ;將PWM的值乘以40us
MOV CUT,#0 ;因為T0中斷給兩個副程式使用,所以CUT累加在此須清除
MOV PWM,@R0 ;將R0的值交給DEL_L去取LOW的時間
INC R0 ;找下一個PWM的位置
RET
;--------------------------------------------------------------------------------
DEL_H:
;延時R7*0.1毫秒,晶振在11.0592MHZ
L7:
MOV R6,#2 ;令 R6=0
L6:
MOV R5,#17 ;令 R5=0
DJNZ R5,$ ;R5=R5-1, 若 R5 <> 0, 則繼續本指令
DJNZ R6,L6 ;R6=R6-1, 若 R6 <> 0, 則跳至 L6
DJNZ R7,L7 ;R7=R7-1, 若 R7 <> 0, 則跳至 L7
RET
;--------------------------------------------------------------------------------
DEL_L:
;延時R7*0.1毫秒,晶振在11.0592MHZ
;MOV R7,#1 ;因為執行DEL_H時已經變成0(暫時想不到當初為什麼要+這個)
MOV A,#27H ;27H X 40us 約 = 1.56ms ,先前已經有1ms了
CPL PWM
ADD A,PWM
MOV COUNT,A
LOOP2:
;SETB TR0 ;開啟T0計數器
;CLR TR0 ;關閉T0計數器
MOV R4,#0AH ;10次
LOOP3:
NOP ;每個 nop 延時 1us
NOP
DJNZ R4,LOOP3 ;R4=0時跳下一行=>(1us+1us+2us)X10 = 40us
DJNZ COUNT,LOOP2 ;將PWM LOW的值乘以40us
MOV CUT,#0 ;因為T0中斷給兩個副程式使用,所以CUT累加在此須清除
RET
;--------------------------------------------------------------------------------
;DEL:
;延時R7*0.1毫秒,晶振在11.0592MHZ
;D5:
; MOV R6,#20 ;令 R6=0
;D4:
; MOV R5,#20 ;令 R5=0
; DJNZ R5,$ ;R5=R5-1, 若 R5 <> 0, 則繼續本指令($代表跳回本行)
; DJNZ R6,D4 ;R6=R6-1, 若 R6 <> 0, 則跳至 L4
; DJNZ R7,D5 ;R7=R7-1, 若 R7 <> 0, 則跳至 L5
; RET
;--------------------------------------------------------------------------------
;T0_INT: ;只用到一個計時中斷
; PUSH A
; PUSH PSW
; CLR TR0
; MOV TH0,#>(65536-40) ;設定TIMER0在每40us中斷一次,if use12Mhz crystal
; MOV TL0,#<(65536-40)
; ;INC CUT ;CUT還搞不懂
; POP PSW
; POP A
; RETI
;--------------------------------------------------------------------------------
;T1_INT:
; PUSH A
; PUSH PSW
; CLR TR1
; MOV TH1,#>(65536-10000);設定TIMER1在每10ms中斷一次,if use 12Mhz crystal
; MOV TL1,#<(65536-10000)
; POP PSW
; POP A
; RETI
;---------------------------------------------------------------------
END |