NAME my_51
;51汇编 红外遥控解码,8位数据管显示,
;作者--操作系统
3.2红外接收头,P3.3 蜂鸣器,P0 并口数据,P2 数码管位选择,全部低电平有效
;使用有自动重装功能的定时器2,为时钟节拍 ,周期为 2 毫秒
;定时器0,模式1,为红外头 接收脉宽计数
;晶振 12 M。
;单片机型号 STC89C52
;时间 2013.01.01
;
$include (reg52.inc)
TTH EQU ((65536-2000)/256 )
TTL EQU ((65536-2000) MOD 256)
BAT EQU P3.3
DIS_EN BIT 20H.0
INT_IF BIT 20H.1
VAR1 SEGMENT DATA
PROG SEGMENT CODE ;定义 PROG 在CODE段
RSEG VAR1
ORG 23H
BUF: DS 8
TM: DS 1
WEI: DS 1
BUF1: DS 1
BUF2: DS 1
BEEP_TIME: DS 1
IR_WEI: DS 1
YW: DS 1
BUFF: DS 6
RSEG PROG ROG 段 开始
ORG 0H ; RESET
JMP MAIN_INIT
ORG 03H ;INT0
JMP INTINT0
ORG 0BH ; TIMER0
RETI
ORG 13H ; INT1
RETI
ORG 1BH ; TIMER1
RETI
ORG 23H ; UART TI/RI
RETI
ORG 2BH ;TIMER2
CLR TF2
SETB DIS_EN
RETI
; // 定时器0 中断服务子程序
INTINT0:
MOV BUF2,TH0
MOV TH0,#0
MOV TL0,#0
SETB INT_IF
RETI
;主程序开始
MAIN_INIT:
MOV SP, #60H ; sp=60H, 向上生长的堆栈指针。
SETB EX0 ; 使能外部中断 0
SETB ET2 ; 使能定时器中断 2
SETB ET1 ;使能定时器1中断
SETB IT0 ;外部中断0 下降沿有效
MOV TMOD ,#11H ;定时器模式为 11
MOV RCAP2H,#TTH ;初始化定时2 自动重装值
MOV RCAP2L,#TTL ;初始化定时2 自动重装值
MOV TH2,#TTH ;初始化定时器2初始值
MOV TL2,#TTL ;初始化定时器2初始值
SETB TR2 ;启动定时2
SETB TR0 ;启动定时器 0
SETB TR1 ;启动定时器1
MOV P0,#00H ;初始化P0
MOV R0,#BUF ; R0 为数组基地址指针
CLR A ; 清A
CLRBUF:
MOV @R0,A ;显存清0
INC R0
CJNE R0,#BUF+8,CLRBUF
MOV WEI,A ; WEI=0
CLR BAT ; 叫一声
SETB EA ;开全局中断
;; JMP MAIN ;到大循环
MAIN:
JBC DIS_EN,DISP ; 如果可以显示就到显示 ,因为JBC 跳不远,只能先跳到近处。换个指令跳到远处。
JBC INT_IF,PRESS_INT_IF ; 如果有外部中断数据,就处理数据
JMP MAIN ;回到大循环
DISP:
JMP DISPLAY;跳到远的显示程序 ,因为只有一个地方用这个程序块,所以不用CALL
PRESS_INT_IF:
MOV BUF1,BUF2 ;BUF2,是一个与中断共享的变量,尽量使用原子操作来操作此变量
MOV A,BUF1
SUBB A,#28H
JC NN1 ;如何 buf1 < 0x28
;else
MOV A,BUF1
SUBB A,#3CH
JNC NN1 ;IF(BUF1>0X31)
;IF(BUF1>=0X28 && BUF1<= 0X32)
CLR A
MOV IR_WEI,A ;IR_WEI=0;
JMP RETT ;退出处理
NN1:
MOV A,BUF1
SUBB A,#3
JC RETT ;IF(BUF1<3)退出处理
MOV A,BUF1
SUBB A,#7
JNC NN2
;IF(BUF1 < 7 && BUF1>=3
MOV A,YW
CLR C
RRC A
MOV YW,A ;YW>>=1;IR_WEI++;
INC IR_WEI
JMP NN3
NN2:
MOV A,BUF1
SUBB A,#8
JC RETT
MOV A,BUF1
SUBB A,#12
JNC RETT
;IF(BUF1>=8 && BUF1<12 )
MOV A,YW
CLR C
RRC A
MOV YW,A
ORL YW,#80H ; YW>>=1;YW |=0X80;IR_WEI++;
INC IR_WEI
NN3:
MOV A,IR_WEI
ANL A,#07H
JNZ RETT
MOV A,IR_WEI
RR A
RR A
RR A
ANL A,#1FH
ADD A,#BUFF
MOV R0,A
MOV @R0,YW
MOV A,IR_WEI
CJNE A,#32,RETT
CLR A
MOV IR_WEI,A
MOV A,#1 ;加载数据到显示缓冲区(显存)
ADD A,#BUFF
MOV R0,A
MOV A,#7
ADD A,#BUF
MOV R1,A
LOP1:
MOV A,@R0
SWAP A
ANL A,#0X0F
MOV @R1,A
DEC R1
MOV A,@R0
ANL A,#0X0F
MOV @R1,A
DEC R1
INC R0
MOV A,R0
CJNE A,#BUFF+5,LOP1
;校验数据正常不正常
MOV A,#3
ADD A,#BUFF
MOV R0,A
MOV A,@R0
MOV R7,A
INC R0
MOV A,@R0
ORL A,R7
CJNE A,#0XFF ,RETT ;不正常的
CLR BAT ;正常数据,鸣叫一下
RETT: JMP MAIN
SHUADD:
MOV R7,#0
LOOP:
MOV A,#BUF
ADD A,R7
MOV R0,A
MOV A,@R0
INC A
MOV @R0,A
CJNE A,#0AH,RN
MOV @R0,#0
INC R7
MOV A,R7
CJNE A,#4,LOOP
RN:
RET
DISPLAY:
MOV P0,#0FFH ;//关闭显示内容
MOV DPTR,#TWEI
MOV A,WEI
MOVC A,@A+DPTR
MOV P2,A ; // 切换显示位置
MOV DPTR,#TAB
MOV A,#BUF
ADD A,WEI
MOV R0,A
MOV A,@R0
MOVC A,@A+DPTR
MOV P0,A
INC WEI
MOV A,WEI
CJNE A,#8H,RETURNMAIN
MOV WEI,#0H
CALL PROCESS_BEEP
INC TM
MOV A,TM
CJNE A,#1000/16, RETURNMAIN
; CALL SHUADD
MOV TM,#0H
RETURNMAIN: JMP MAIN
PROCESS_BEEP:
JB BAT,RETN1
INC BEEP_TIME
MOV A,BEEP_TIME
CJNE A,#100/16,RETN
SETB BAT
RETN1: MOV BEEP_TIME,#0
RETN: RET
TAB:
DB 0XC0,0F9H,0A4H,0B0H,099H,092H,082H, 0F8H,080H,090H,0x88,0x83,0xc6,0xa1,0x86,0x8e
TWEI:
DB ~0X80,~0X40,~0X20,~0X10,~8,~4,~2,~1
END
|