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