LED单灯PWM调光
申明:本程序绝对原创,请转载本博文注明出处:http://blog.csdn.net/fly928sky/article/details/7668663
1.本程序电路图,请参考http://blog.csdn.net/fly928sky/article/details/7645591
2.程序中PWM调光的LED灯为DS9
3.本程序相同流程对应A51程序,请参考http://blog.csdn.net/fly928sky/article/details/7668673
代码如下:
DelayNH EQU 1000H
DelayNL EQU 1001H
PwmLowH EQU 1002H
PwmLowL EQU 1003H
PwmCylH EQU 1004H
PwmCylL EQU 1005H
ORG 0000H
LJMP Start
;程序开始
Start: ACALL Init
;主程序段
Main: ACALL PwmM
LJMP Main
;初始化函数
Init: SETB P1.1 ;关闭数码管
MOV P0,#0FFH
CLR P1.1
SETB P1.3 ;关闭点阵
MOV P0,#00H
CLR P1.3
RET
;PWM函数
PwmM: SETB P1.2 ;LED使能
MOV DelayNH,#00H ;延时函数参数DelayN的H位
MOV DelayNL,#00H ;延时函数参数DelayN的L位
MOV PwmLowH,#00H ;PwmLow参数H位
MOV PwmLowL,#00H ;PwmLow参数L位
MOV PwmCylH,#02H ;PwmCyl参数H位
MOV PwmCylL,#58H ;PwmCyl参数L位
PwmS: MOV P0,#0FFH
ACALL Delay60000
ACALL PwmToBright //逐渐变亮
MOV P0,#07FH
ACALL PwmToDark //逐渐变暗
LJMP PwmS
RET
;带参数的延时函数
DelayUS:MOV R0,DelayNH
MOV R1,DelayNL
ULoop: SETB C
MOV A,R1
SUBB A,#00H
MOV A,R0
SUBB A,#00H
JC DUEnd
MOV A,R1
DEC R1
JNZ ULoop
DEC R0
SJMP ULoop
DUEnd: RET
Delay60000: ;0xEA60十进制数为60000
MOV DelayNH,#0EAH
MOV DelayNL,#060H
ACALL DelayUS
RET
DelayPL: ;参数为PwmLow
MOV DelayNH,R2
MOV DelayNL,R3
ACALL DelayUS
RET
DelayPCL: ;参数为PwmCyl-PwmLow
CLR C ;减法运算
MOV A,R5
SUBB A,R3
MOV DelayNL,A
MOV A,R4
SUBB A,R2
MOV DelayNH,A
ACALL DelayUS
RET
;逐渐变亮函数
PwmToBright:
ACALL PwmInit
MOV R3,#01H
PTBS: MOV P0,#07FH
ACALL DelayPL
MOV P0,#0FFH
ACALL DelayPCL
;加1
CLR C
MOV A,R3
ADD A,#01H
MOV R3,A
MOV A,R2
ADDC A,#00H
MOV R2,A
;PwmLow与PwmCyl的比较,PwmLow是否小于PwmCyl
ACALL CylCLow
JC PTBEnd ;判断CY是否有借位,有借位直接结束函数,否则继续下一条指令
JNZ PTBS ;判断差值的H位和L位相或值是否等于零,不等于零跳转到PTBS,否则继续下一条指令
PTBEnd: RET
;逐渐变暗函数
PwmToDark:
ACALL PwmInit
CLR C ;将PwmCyl-1赋给PwmLow
MOV A,R5
SUBB A,#01H
MOV R3,A ;PwmCyl减1后将L位赋值给PwmLowL
MOV A,R4
SUBB A,#00H
MOV R2,A ;PwmCyl减1后将H位赋值给PwmLowH
PTDS: MOV P0,#07FH
ACALL DelayPL
MOV P0,#0FFH
ACALL DelayPCL
;减1
CLR C ;PwmLow-1
MOV A,R3
SUBB A,#01H
MOV R3,A ;减1后PwmLowL
MOV A,R2
SUBB A,#00H
MOV R2,A ;减1后PwmLowH
;判断PwmLow是否大于1
JC PTDEnd ;判断CY是否有借位,有借位直接结束函数,否则继续下一条指令
MOV A,R2
JNZ PTDS ;PwmLow的H位不为零跳转到PTDS,否则继续下一条指令
MOV A,R3
CJNE A,#01H,LowCOne ;PwmLow的L位不等于1跳转到LowCOne,否则继续下一条指令
LJMP PTDEnd ;PwmLow的L位等于1跳转到PTDEnd结束函数
LowCOne:JNC PTDS ;判断CY是否有为零,为零(PwmLow大于1)跳转到PTDS,否则继续下一条指令
PTDEnd: RET
PwmInit:
MOV R2,PwmLowH
MOV R3,PwmLowL
MOV R4,PwmCylH
MOV R5,PwmCylL
RET
;PwmLow与PwmCyl的比较
CylCLow:
CLR C ;减法运算
MOV A,R5
SUBB A,R3
MOV 1010H,A ;减法低位结果暂存1010H中
MOV A,R4
SUBB A,R2
ORL A,1010H ;将低位与高位相或存入累加器A
RET
;程序结束
END