本帖最后由 lfjwfm 于 2015-10-22 18:55 编辑
;从第一个下降沿开始,启动计时计数器和监视计数器。
;在以后的每一个下降沿里 清监视计数器/脉冲数累加/检测退出条件
;测量第一脉冲组n个脉冲的总周期,减少误差。
;单周期计算公式
;红外码学习程序.LiFangsJun
;t = (T1 - MAXCYCT-7) / ( PSCOUNT - 1)这7个周期是指令执行的延时
;第一阶段,测量载波周期
STEP1TH: JNB IE1, $ ;[2] ;等待第一个下降沿
SETB TR1 ;[1] ;T1记录n个周期的时长
SETB TR0 ;[1] ;启动监视计数器
CLR IE1 ;[1] ;清中断标志
STEP4TH: JNB IE1, OVERERROR ;[2] ;是否新的脉冲
MOV TL0, #MAXCYCT ;[1] ;重装监视计数器
; INC PSCOUNT ;[2]
INC DPTR ;[2]
CLR IE1 ;[1]
OVERERROR: JNB TF0, STEP4TH ;[2] ;是否监视溢出
CLR TR1 ;[1]
MOV MODh, TH1 ;[2] ;保存第一个脉冲组的载波周期总和
MOV MODl, TL1 ;[2]
MOV TH1, #00H ;[1]
MOV TL1, #03CH
ENDSTEPC: SETB TR1 ;[1] ;开始测量长电平周期
;计算也可插入,但影响最小可测量的长电平长度
LONGLOOP: CLR TR0 ;[1] ;停止监视计数器
CLR TF0 ;[1]
jb ramover,longstp1 ;[2]
mov @r0,dpl ;[2] ;本脉冲组的脉冲个数
inc r0 ;[1]
cjne r0,#maxplusrec,plusover ;[2] ;内存用完
setb ramover ;[1]
plusover: mov a,dph ;脉冲组溢出处理
jz longstp1
push 01h
mov r1,OVERCODE
mov @r1,llcount ;特别注意,这是未加前就已经保存
inc r1
setb acc.7
mov @r1,acc
inc r1
mov OVERCODE,r1
pop 01h
mov dph,#00h
longstp1: MOV TH0, #0FFH ;[1] ;重装监视计数器
MOV TL0, #MAXCYCT ;[2] ;
; MOV PSCOUNT,#0001H ;[2] ;第一个脉冲来不及累加
MOV DPTR,#0001H ;[2] ;第一个脉冲来不及累加
;开中断告诉T1中断,已经开始了一个新的脉冲周期
SETB HLEVEL ;[1]
SETB EA ;[1]
INC LLCOUNT ;[1] ;长电平计数
;此时可插入计算模块
;等待脉冲组
NEXTPCW: JBC IE1,NEXTPLUSC ;[2]
JNB IRRQUITF,NEXTPCW ;[2]
clr tr1
AJMP ENDIRSD ;检测到T1设置的退出标志
NEXTPLUSC: CLR TR1 ;[1] ;长电平停止计数
SETB TR0 ;[1] ;开始监视计数
CLR EA ;[1] ;关中断
PCLOOP: JNB IE1, OVERER ;[2] ;是否新的脉冲
MOV TL0, #MAXCYCT ;[2] ;重装监视计数器
; INC PSCOUNT ;[1]
INC DPTR ;[1]
CLR IE1 ;[1]
OVERER: JNB TF0, PCLOOP ;[2] ;是否监视溢出
;再进入长电平期
jb ramover,overerstp1 ;[2]内存用完后不再保存
mov @r1,th1 ;[2] ;先保存上个长周期的值
inc r1 ;[1]
mov @r1,tl1 ;[2]
inc r1 ;[1]
overerstp1: MOV TH1, #00H ;[1];补尝后的初值
MOV TL1, #03DH ;[1] {**T0溢出补偿50 + 11**}
SETB TR1 ;[1] ;开始测量新的长电平周期
AJMP LONGLOOP ;[2] ;开始下一轮等待 =20
ENDIRSD: ;红外码学习结束
jb ramover,irclrset;[2]内存用完后不再保存
mov @r1,th1 ;[2] ;先保存溢出后的值
inc r1 ;[1]
mov @r1,tl1 ;[2]
inc r1 ;[1]
irclrset: CLR A ;终止红外学习 清除各种设置
MOV TMOD,A
MOV TCON,A
MOV IE,A
MOV IP,A
; CLR RedLed
; CLR GreenLed
RET |