📄 pt2272.asm
字号:
; =========================================================================================
; =========================================================================================
; PT2272 模拟解码器(接收来自射频解码模块的2262格式串行数据流)
; 管理三位数码管显示器
; 利用AT24C32实现堆栈式掉电缓存保护,通过特殊的清除发射器清除堆栈
; 显示器具有两级亮度变化
; 具有蜂鸣器,新的编码收到后,蜂鸣器鸣响2/3次,显示器高亮,三秒后正常
;
; CPU: AT89C2051@12MHz
;
; COPYRIGHT yanggt@163.net SEP 9, 2004
; =========================================================================================
; =========================================================================================
EESIZE EQU 32768 ;EEPROM容量(32768/16384/8192/4096/2048/1024/512)
PWDF EQU 50H ;EEPROM中用于标识历史记录有效
MYA0_3 EQU 00010101B ;有效识别码,不匹配则不响应
MYCLRL EQU 00H ;主控手机编码值(目前为 0000H)
MYCLRH EQU 00H ;根据A4-A11计算得到(00 D7 D6 D5 D4 D3 D2 D1)(D0)
BELONT EQU 40 ;声音鸣响时间
BELOFT EQU 20 ;静音时间
SCL BIT P3.0 ;AT24C32(4K字节)
SDA BIT P3.1
SIGPIN BIT P3.2 ;接收信号入口
BELL BIT P3.3 ;蜂鸣器控制
VSEL BIT P1.0 ;LED亮度选择,H=高亮度
U0E BIT P3.5 ;个位LED位选
U1E BIT P3.4 ;十位LED位选
U2E BIT P3.7 ;百位LED位选
BELLSW BIT 78H ;蜂鸣器运行期间=1
EEEMPTY BIT 79H ;EEPROM空标志
BELLON BIT 7AH ;通知蜂鸣器鸣响
CODEOK BIT 7BH ;收到的编码正确
TMK250 BIT 7CH ;250us标志,每250us置位一次
SIGING BIT 7DH ;手机发射信号正在持续=1,无信号=0
LEDHIGH BIT 7EH ;显示器亮度标志=0:正常;=1:高亮
TOUTMK BIT 7FH ;显示器降低亮度时间已到=1
RBUF81 DATA 20H ;后8位第一次采样结果A4-A11
RBUF82 DATA 21H ;后8位第二次采样结果A4-A11
RBUF44 DATA 22H ;前4位第12次采样结果A0-A3
SIGPOT DATA 23H ;接收引脚上次电平,直接保存P3口全部内容
SIGMSK EQU 04H ;SIG----P3.2
TCNTL DATA 24H ;定时计数器(4ms时基)
TCNTH DATA 25H
TMX16 DATA 26H ;16*250=4000us=4ms
BELLTM DATA 27H ;鸣响时间
DBUF0 DATA 28H ;个位显示缓冲区
DBUF1 DATA 29H ;十位
DBUF2 DATA 2AH ;百位
EEPTRL DATA 2BH ;EEPROM当前位置指针
EEPTRH DATA 2CH
EEPOL DATA 2DH ;保存清除指针
EEPOH DATA 2EH ;
RES2F DATA 2FH ;使用其中的标志位
EEBUF DATA 30H ;30-37H, I2C缓冲区
BELLCNT DATA 38H ;鸣响次数计数器(3/2/1)
BELLTMK DATA 39H
CODEL DATA 40H ;接收到编码低位
CODEH DATA 41H ; 高位
CODELK DATA 42H ;保存上一个编码
CODEHK DATA 43H ;
CODE1L DATA 44H
CODE1H DATA 45H
; =========================================================================================
; =========================================================================================
ORG 0000H
LJMP START
; =========================================================================================
; 250us进入一次,每16次(4ms)切换一次显示位
; =========================================================================================
ORG 000BH ;定时器0中断入口,独占 R7
TM0SUB: SETB TMK250
TM0_4MS:DJNZ TMX16, TM0_E
MOV TMX16, #10H
JNB BELLSW, TM0_CLY
DJNZ BELLTM, TM0_CLY
SETB BELLON
TM0_CLY:JB TOUTMK, TM0_0 ;每4ms执行一次
DJNZ TCNTL, TM0_0
DJNZ TCNTH, TM0_0
SETB TOUTMK
TM0_0: CJNE R7, #0, TM0_1 ;当前显示位
CLR U2E
MOV P1, DBUF0
INC R7
SETB U0E
RETI
TM0_1: CJNE R7, #1, TM0_2
CLR U0E
MOV P1, DBUF1
INC R7
SETB U1E
RETI
TM0_2: CLR U1E
MOV P1, DBUF2
MOV R7, #0
SETB U2E
RETI
TM0_E: RETI
; =========================================================================================
; =========================================================================================
START: MOV P1, #00H ;关闭显示器,正常亮度
CLR BELLON
CLR BELL
ACALL EECHK ;检查EEPROM,确定指针,提取其中最后一个历史记录号码
ACALL TOBUF
MOV TMX16, #10H ;中断计数寄存器置初始值16
SETB TOUTMK ;延迟定时器处于停止状态
CLR U0E
CLR U1E
CLR U2E
MOV R7, #00H ;从第一位开始显示
MOV TMOD, #12H ;TIMER0, MODE 2, TIMER1, MODE 1
MOV TL0, #06H
MOV TH0, #06H ;时间=250us
SETB TR0
SETB ET0
SETB EA
MOV A, #6-1 ;开机时蜂鸣器自动鸣响
ACALL BELL_S
MOV BELLTM, #BELONT-20
ACALL LEDOFF
CLR LEDHIGH ;关闭高亮度
MOV SIGPOT, #00H ;假设开始时接收引脚=0
CLR SIGING
SETB F0
;=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
MAIN: JNB BELLSW, MAIN_S0
ACALL BELL_M
MAIN_S0:JNB LEDHIGH, MAIN_00 ;显示器普通亮度,不检查标志
JNB TOUTMK, MAIN_0
ACALL LEDOFF ;显示器回到正常亮度
CLR LEDHIGH
JB EEEMPTY, MAIN_0 ;没有尚未确认的编码
AJMP MAIN_01
MAIN_00:JB EEEMPTY, MAIN_0 ;没有尚未确认的编码
JNB TOUTMK, MAIN_0
MOV A, #2-1
ACALL BELL_S ;鸣响
MAIN_01:MOV TCNTL, #LOW(5000/4) ;高亮度持续3000ms=3s后恢复
MOV TCNTH, #HIGH(5000/4)
CLR TOUTMK
MOV BELLTM, #30
MAIN_0: MOV A, P3 ;监视SIG引脚电平变化
XCH A, SIGPOT
XRL A, SIGPOT
ANL A, #SIGMSK
JZ MAIN ;A=0表示引脚电平无变化
SETB F0
ACALL GETCOD ;开始接收,出错后直接返回
JC MAIN ;接收代码无效,舍弃。
ACALL FIND
JC MAIN ;C=1,表示代码无效,什么也不发生
MOV CODE1L, CODEL
MOV CODE1H, CODEH
CLR F0
ACALL GETCOD ;开始接收,出错后直接返回
SETB F0
JC MAIN ;接收代码无效,舍弃。
ACALL FIND
JC MAIN ;C=1,表示代码无效,什么也不发生
MOV B, A
MOV A, CODE1L
XRL A, CODEL
JNZ MAIN_0D
MOV A, CODE1H
XRL A, CODEH
JZ MAIN_0C
MAIN_0D:MOV CODE1L, CODEL
MOV CODE1H, CODEH
CLR F0
ACALL GETCOD ;开始接收,出错后直接返回
SETB F0
JC MAIN ;接收代码无效,舍弃。
ACALL FIND
JC MAIN ;C=1,表示代码无效,什么也不发生
MOV B, A
MOV A, CODE1L
XRL A, CODEL
JNZ MAIN_E
MOV A, CODE1H
XRL A, CODEH
JNZ MAIN_E
MAIN_0C:MOV A, B
JNZ MAIN_1 ;A=1:主控手机,转去退栈
MOV BELLCNT, #4-1
MOV A, CODEL
XRL A, CODELK
JNZ MAIN_0A
MOV A, CODEH
XRL A, CODEHK
JZ MAIN_0B
;这里可以进行编码过滤=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
MAIN_0A:MOV BELLCNT, #6-1
ACALL EEPUSH ;其他手机,转去保存、显示
ACALL TOBUF
MAIN_0B:SETB TOUTMK
MOV TCNTL, #LOW(3000/4) ;高亮度持续3000ms=3s后恢复
MOV TCNTH, #HIGH(3000/4)
CLR TOUTMK
SETB LEDHIGH ;显示器进入高亮状态
MOV A, BELLCNT
ACALL BELL_S ;鸣响
MOV BELLTM, #BELONT
AJMP MAIN
MAIN_1: MOV A, CODEL ;核对手机号码
XRL A, #MYCLRL
JNZ MAIN_E
MOV A, CODEH
XRL A, #MYCLRH
JNZ MAIN_E
ACALL EEPOP ;执行退栈操作
MAIN_E: AJMP MAIN
; =========================================================================================
; 主程序结束
; =========================================================================================
BELL_S: MOV BELLCNT, A
SETB BELLSW
SETB BELL
RET
; =========================================================================================
BELL_M: JBC BELLON, BELLM
RET
BELLM: MOV A, BELLCNT
BELLM0: JNB ACC.0, BELLM1
MOV BELLTM, #BELOFT ;A.0=1,正在鸣响,应该关闭
CLR BELL
AJMP BELLM9
BELLM1: MOV BELLTM, #BELONT ;静音状态,应该打开
SETB BELL
BELLM9: DJNZ BELLCNT, BELLME
CLR BELLSW
CLR BELL
BELLME: RET
; =========================================================================================
LEDOFF: ANL DBUF0, #0FEH
ANL DBUF1, #0FEH
ANL DBUF2, #0FEH
RET
; =========================================================================================
; =========================================================================================
TM1SET: CLR TR1 ;1,ACALL=2
CLR TF1 ;1
MOV TL1, DPL ;2
MOV TH1, DPH ;2
SETB TR1 ;1
RET ;2, TOTAL=2+1+1+2+2+1+2=11us
; =========================================================================================
; 接收代码,收到两个相同的编码即认可。
; 发射结束后接收下一个。
; =========================================================================================
GETCOD: NOP
GETC_S: MOV DPTR, #65535-50000 ;在50ms内搜索至少持续4ms的低电平 [***]
ACALL TM1SET
GETC_S0:MOV R6, #16 ;16*250us=4000us=4ms
GETC_S1:CLR TMK250
GETC_S2:JB TF1, GETC_E ;这里超时认为目前无发射器工作,或上次发射已结束。
JB SIGPIN, GETC_S0
JNB TMK250, GETC_S2
DJNZ R6, GETC_S1
MOV R5, #4*2 ;首先接收A0-A3,共4位,8个采样点
MOV DPTR, #65535-8000 ;在接下来的8ms内必须出现上升沿 [***]
ACALL TM1SET
GETC_0: JB TF1, GETC_E ;这里超时认为目前无发射器工作,或上次发射已结束。
JNB SIGPIN, GETC_0
; JB SIGING, GETC_F ;上次发射尚未结束,直接返回,不接收编码。
; AJMP GETC_20
JNB SIGING, GETC_20 ;上次发射尚未结束,直接返回,不接收编码。
JNB F0, GETC_20
AJMP GETC_F
GETC_1P:MOV DPTR, #65535-1250+11+2 ;在接下来的1250us内必须出现低电平 [***]
ACALL TM1SET
GETC_1: JB TF1, GETC_F ;超时
JB SIGPIN, GETC_1
MOV DPTR, #65535-1250+11+2 ;在接下来的1250us内必须出现上升沿 [***]
ACALL TM1SET
GETC_2: JB TF1, GETC_F ;超时
JNB SIGPIN, GETC_2
GETC_20:MOV DPTR, #65535-500+11+2 ;固定延迟500us后采样
ACALL TM1SET
JNB TF1, $
MOV C, SIGPIN ;采样接收信号
MOV A, RBUF44
RLC A
MOV RBUF44, A
DJNZ R5, GETC_1P ;循环接收4个数据位,进行8次采样
MOV R5, #8*2 ;接收A4-A11,共8个数据位,16个采样点
MOV R0, #RBUF81 ;RBUF81存放第一次采样值
GETC_3P:MOV DPTR, #65535-1250+11+2 ;在接下来的1250us内必须出现低电平 [***]
ACALL TM1SET
GETC_3: JB TF1, GETC_F ;超时
JB SIGPIN, GETC_3
MOV DPTR, #65535-1250+11+2 ;在接下来的1250us内必须出现上升沿 [***]
ACALL TM1SET
GETC_4: JB TF1, GETC_F ;超时
JNB SIGPIN, GETC_4
GETC_40:MOV DPTR, #65535-500+11+2 ;固定延迟500us后采样
ACALL TM1SET
JNB TF1, $
MOV C, SIGPIN ;采样接收信号
MOV A, @R0
RLC A
MOV @R0, A
XRL 00H, #RBUF81 ;在RBUF81和RBUF82之间切换
XRL 00H, #RBUF82
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -