
;************渐亮渐灭程序*************************
HIGHH EQU 41H ;定义高电平高8位数据存放的地址
HIGHL EQU 40H ;定义高电平低8位数据存放的地址
LOWH EQU 43H ;定义低电平高8位数据存放的地址
LOWL EQU 42H ;定义低电平低8位数据存放的地址
SUM2 EQU 46H ;定义高低电平的和值:设高电平持续时间为55536+X,则低电平持续时间为55536+(10000-X)
SUM1 EQU 45H ;所以高低电平的总时间就是55536+X+55536+(10000-X)=121072
SUM0 EQU 44H ;将121072转换为十六进制为1D8F0H
LED EQU P2 ;定义LED接口
ORG 0000H
LJMP START
ORG 001BH
LJMP T1
ORG 0030H
;*************************************************
;******************主程序*************************
START:
SETB EA ;开启总中断允许开关
SETB ET1 ;开启定时计数器T1中断允许开关
MOV TMOD,#00010000B ;将T1设置为内部定时,方式1
SETB LED.7 ;关闭LED
CLR F1 ;清零用户自定义标志位
MOV HIGHH,#0FFH ;赋值高电平时间的初值55536+100*99=FF9C
MOV HIGHL,#9CH
MOV SUM2,#01H ;赋值高低电平的总时间1D8F0H
MOV SUM1,#0D8H
MOV SUM0,#0F0H
MAIN:
LCALL DIZENG ;调用PWM波占空比递增子程序(每次计数初值递增100,即100/10000=1%的占空比)
LCALL DIJIAN ;调用PWM波占空比递减子程序(每次计数初值递减100,即100/10000=1%的占空比)
LJMP MAIN
;*************************************************
;******************占空比递增子程序***************
DIZENG:
SETB TR1 ;开启定时计数器T1
LCALL JISUAN ;调用计算子程序,通过总时间1D8F0减高电平所占的时间计算出低电平的时间
LCALL DELAY ;调用延时子程序
MOV A,HIGHL
CLR C
SUBB A,#100 ;将高电平定时初值的低8位减100
MOV HIGHL,A
MOV A,HIGHH
SUBB A,#0
MOV HIGHH,A ;检验低8位减100后是否有借位,如果有借位则高8位自动减1
MOV A,HIGHH
CJNE A,#0D8H,DIZENG ;检验高8位是否等于0D8H,如果不等于则子程序返回
MOV A,HIGHL
CJNE A,#0F0H,DIZENG ;检验低8位是否等于0F0H,如果不等于则子程序返回
MOV HIGHH,#0D9H ;在返回之前先给递减子程序初始值,在这个值基础上加100,实现递减
MOV HIGHL,#54H
RET
;*************************************************
;******************占空比递减子程序***************
DIJIAN: ;占空比递减子程序
SETB TR1 ;开启定时计数器T1
LCALL JISU
AN ;调用计算子程序,通过总时间1D8F0减高电平所占的时间计算出低电平的时间
LCALL DELAY ;调用延时子程序
MOV A,HIGHL
CLR C
ADD A,#100 ;将高电平定时初值的低8位加100
MOV HIGHL,A
MOV A,HIGHH
ADDC A,#0
MOV HIGHH,A ;检验低8位加100后是否有进位,如果有进位则高8位自动加1
MOV A,HIGHH
CJNE A,#0FFH,DIJIAN ;检验高8位是否等于0FFH,如果不等于则子程序返回
MOV A,HIGHL
CJNE A,#9CH,DIJIAN ;检验低8位是否等于9CH,如果不等于则子程序返回
RET
;*************************************************
;******************计算子程序*********************
JISUAN:
CLR C ;在低8位减低8位时不需要考虑进位标志位,所以将其清零
MOV A,SUM0
SUBB A,HIGHL ;低8位减低8位
MOV LOWL,A ;将减得的数值存入低电平低8位存储器
MOV A,SUM1
SUBB A,HIGHH ;高8位减高8位
MOV LOWH,A ;将减得的数值存入低电平高8位存储器
MOV A,SUM2
SUBB A,#0 ;最高8位的数值无用所以可以舍去(即1D8F0中的“1”)
RET
;*************************************************
;***********PWM波占空比递增的延时时间*************
DELAY:
MOV 30H,#1
D1:
MOV 31H,#100
D2:
MOV 32H,#200
DJNZ 32H,$
DJNZ 31H,D2
DJNZ 30H,D1
RET
;*************************************************
;******************中断服务子程序*****************
T1:
CLR TR1 ;关闭定时计数器,避免运行中断程序照成的误差
CPL F1 ;对用户自定义标志位取反,以实现高低电平的初值交替赋给TH1:TL1
JNB F1,DI ;检验F1=0?如果F1=0则将低电平的计数初值赋值给TH1:TL1
GAO: ;如果F1=1则将高电平的计数初值赋值给TH1:TL1
MOV TH1,HIGHH
MOV TL1,HIGHL
CLR LED.7 ;因为下一个定时周期定时的是高电平的时间,所以应点亮LED
SETB TR1 ;重新开启定时计数器1
LJMP FANHUI2
DI: ;如果F1=0则将低电平的计数初值赋值给TH1:TL1
MOV TH1,LOWH
MOV TL1,LOWL
SETB LED.7 ;因为下一个定时周期定时的是低电平的时间,所以应关闭LED
SETB TR1 ;重新开启定时计数器1
FANHUI2:
RETI
;**************************************************
;**************************************************
