本帖最后由 xiaodezhou 于 2013-7-28 10:44 编辑
/*
采码模块处理。
通过外部INT0下降沿中断,启动TIMER0定时采码。
*/
INT0ISR:
PUSH ACC
PUSH PSW
CLR TR0
CPL P10
MOV PSW,#__INT0_BANK
MOV R6,TL0
MOV R7,TH0
MOV TL0,#00H
MOV TH0,#00H
SETB TR0
JB 标志寄存器_IRStart_En,INT0ISR_1
////////////////////////////////////////
;第一次下降沿触发启动采码
////////////////////////////////////////
SETB 标志寄存器_IRStart_En
MOV RESCOUNT,#00H
;下次设置成上升沿触发INT0中断
MOV EINTCS0,#54H ;INT0异步上升沿触发方式
SETB IT0 ;边沿触发方式
LJMP INT0ISR_ONE_END
////////////////////////////////////////
;保存定时器0的数据
////////////////////////////////////////
INT0ISR_1:
////////////////////////////////////////
;判断是第几个数据段电平,
;再确定触发方式(上升沿或下降沿)
////////////////////////////////////////
MOV A,RESCOUNT
RRC A
JC INT0ISR_2
;保存数据至R4、R5中.
MOV A,R6
MOV R4,A
MOV A,R7
MOV R5,A
MOV EINTCS0,#50H ;INT0异步下降沿触发方式
SETB IT0 ;边沿触发方式
MOV A,RESCOUNT
CJNE A,#22,INT0ISR_3
;一帧数据接收完成,保存最后一位数据,采取半个周期
CLR 标志寄存器_IRStart_En
SETB 标志寄存器_IRResEnd_En
JB 标志寄存器_IRRes_En,INT0ISR_31
SETB 标志寄存器_IRRes_En
SETB 标志寄存器_IRValid_En
INT0ISR_31:
CLR TR0
MOV TH0,#0D8H ;定时10ms,溢出说明按键已释放。
MOV TL0,#0F0H
SETB TR0
LJMP INT0ISR_05
INT0ISR_3:
LJMP INT0ISR_END
////////////////////////////////////////
;状态数据位解码,判断是否满足
;数据位周期和占空比
////////////////////////////////////////
INT0ISR_2:
MOV EINTCS0,#54H ;INT0异步上升沿触发方式
SETB IT0 ;边沿触发方式
//高电平和低电平相加组成1个状态周期T
CLR C
MOV A,R6
ADD A,R4
MOV R2,A
MOV A,R7
ADDC A,R5
MOV R3,A
JC INT0ISR_ERRO ;数据超出周期T
INT0ISR_05:
//判断周期时间
CLR C
MOV A,#__DATAT0_TL ;判断是否有超出上限值
SUBB A,R2
MOV A,#__DATAT0_TH
SUBB A,R3
JC INT0ISR_ERRO
MOV A,#__DATAT1_TL ;判断是否有超出下限值
SUBB A,R2
MOV A,#__DATAT1_TH
SUBB A,R3
JNC INT0ISR_ERRO
//判断状态数据,是否为“0”
CLR C
MOV A,#__DATA00_L ;判断是否有超出上限值
SUBB A,R4
MOV A,#__DATA00_H
SUBB A,R5
JC INT0ISR_04
MOV A,#__DATA01_L ;判断是否有超出下限值
SUBB A,R4
MOV A,#__DATA01_H
SUBB A,R5
JNC INT0ISR_ERRO
CLR 标志寄存器_IRData_En ;得到状态“0”
LJMP INT0ISR_D0
//判断状态数据,是否为“1”
INT0ISR_04:
CLR C
MOV A,#__DATA10_L ;判断是否有超出上限值
SUBB A,R4
MOV A,#__DATA10_H
SUBB A,R5
JC INT0ISR_ERRO
MOV A,#__DATA11_L ;判断是否有超出下限值
SUBB A,R4
MOV A,#__DATA11_H
SUBB A,R5
JNC INT0ISR_ERRO
SETB 标志寄存器_IRData_En ;得到状态“1”
INT0ISR_D0:
MOV A,RESCOUNT
CJNE A,#01,INT0ISR_Code0
JNB 标志寄存器_IRData_En,INT0ISR_ERRO
LJMP INT0ISR_SAVE
INT0ISR_Code0:
CJNE A,#03,INT0ISR_Code1
JNB 标志寄存器_IRData_En,INT0ISR_ERRO
LJMP INT0ISR_SAVE
INT0ISR_Code1:
CJNE A,#05,INT0ISR_Code2
JB 标志寄存器_IRData_En,INT0ISR_ERRO1
LJMP INT0ISR_SAVE
INT0ISR_Code2:
CJNE A,#22,INT0ISR_Code3 ;保存最后一个数据位(只判断高电平)
LJMP INT0ISR_SAVE
INT0ISR_Code3:
MOV A,RESCOUNT ;判断完速的周期
RRC A
JNC INT0ISR_END
INT0ISR_SAVE:
CLR C
MOV A,RESCOUNT
SUBB A,#10
JNC INT0ISR_D_SAVE
MOV A,IRCode
MOV C,标志寄存器_IRData_En
RLC A
MOV IRCode,A
LJMP INT0ISR_END
INT0ISR_D_SAVE:
MOV A,IRData
MOV C,标志寄存器_IRData_En
RLC A
MOV IRData,A
LJMP INT0ISR_END
;解码错误,重新开始接收数据,计数值清“0”
INT0ISR_ERRO:
MOV RESCOUNT,#00H
MOV IRData,#00H
MOV IRCode,#00H
SETB 标志寄存器_IRStart_En
CLR 标志寄存器_IRResEnd_En
LJMP INT0ISR_ONE_END
;检测到引导码为“111”是,保留最后一个“1”
INT0ISR_ERRO1:
MOV RESCOUNT,#01H
MOV IRCode,#01H
;1个电平采集完成
INT0ISR_END:
INC RESCOUNT
INT0ISR_ONE_END:
MOV A,EINTCS0
ANL EINTCS0,#0FCH ;EINTF0清零
MOV A,EINTCS0
ANL EINTCS0,#0FCH ;EINTF0清零
CPL P10
POP PSW
POP ACC
RETI
/*
关闭定时器0,准备下一次接收。
*/
TIMER0ISR:
PUSH PSW
CLR 标志寄存器_IRStart_En
CLR 标志寄存器_IRResEnd_En
CLR 标志寄存器_IRRes_En
CLR TR0
CLR TF0
POP PSW
RETI |