;***************************
;PCA.ASM
;功能:实现捕获
;******************************
;数据RAM单元定义
BIT_CNT DATA 21H ;发送、接收子程序的位计数器
REC_BUF DATA 22H ;接收缓冲器
SEND_BUF DATA 23H ;发送缓冲器
PCA_CNT DATA 24H ;个数计数器
DELAY1 DATA 25H ;延时计数器
;以下是P89C51相对标准80C51新增的SFR定义
CCON DATA 0xD8 ;PCA控制寄存器
CMOD DATA 0xD9 ;PCA模式寄存器
CCAPM0 DATA 0xDA ;模式位
CCAPM1 DATA 0xDB
CCAPM2 DATA 0xDC
CCAPM3 DATA 0xDD
CL DATA 0xE9 ;PCA计数器低字节
CCAP0L DATA 0xEA ;模块N捕获低字节
CCAP1L DATA 0xEB
CCAP2L DATA 0xEC
CCAP3L DATA 0xED
CH DATA 0xF9 ;PCA计数器高字节
CCAP0H DATA 0xFA ;模块N捕获高字节
CCAP1H DATA 0xFB
CCAP2H DATA 0xFA
CCAP3H DATA 0xFB
CCF0 BIT CCON.0 ;中断标志位
CCF1 BIT CCON.1
CCF2 BIT CCON.2
CCF3 BIT CCON.3
CR BIT CCON.6 ;启动PCA
CF BIT CCON.7 ;PCA溢出位
AUXR1 DATA 0xA2 ;
;标志位定义
FLAG1 BIT 20H.0
;I/O口定义
CS BIT P2.4
CLK BIT P2.3
DIO BIT P2.2
KEY BIT P2.1
;======================================
ORG 0000H
AJMP MAIN
ORG 0080H
;======================================
MAIN:
MOV SP,#10H ;堆栈初始化
MOV P1,#11111111B ;P1口作为输入口
MOV IE,#0 ;关中断
SETB CS
SETB KEY
SETB DIO
LCALL INI_ALL ;启动CMP2的16位高速输出功能
CLR P1.4
MAIN_LP:
JB KEY,MAIN_LP
MOV SEND_BUF,#00010101B
LCALL SEND
LCALL RECEIVE
SETB CS
CLR FLAG1
LCALL KEY_DJG
MAIN_LP1:
JNB KEY,MAIN_LP1
LJMP MAIN_LP
;========================================
; KEY_DJG
;========================================
KEY_DJG:
MOV A,REC_BUF
CJNE A,#36,SF
MOV CMOD,#80H ;初始化把PCA设置为捕获模式
MOV IE,#0H
MOV PCA_CNT,#104 ;接收次数设置为适合某种遥控器
MOV R0,#2EH
MOV CCAPM0,#30H
CLR CCF0
REMOTE1:
MOV 26H,#200 ;延时20MS使接收从第一个方波开始
REMOTE2:
MOV 27H,#25
REMOTE3:
JB P1.3,REMOTE1
DJNZ 27H,REMOTE3
DJNZ 26H,REMOTE2
CLR CCF0
SETB CR
WAIT:
JBC CCF0,WW ;有捕捉则保存方波信息
SJMP WAIT
WW:
MOV CH,#0
MOV CL,#0
MOV @R0,CCAP0L
INC R0
MOV @R0,CCAP0H
INC R0
WAIT1:
JBC CCF0,WW1 ;有捕捉则判断看是否继续
SJMP WAIT1
WW1:
DJNZ PCA_CNT,WW
CLR CR ;不接收则关PCA
MOV SEND_BUF,#10100100B ;发复位指令
LCALL SEND
SETB CS
MOV SEND_BUF,#10000000B ;显示1表示接收完毕
LCALL SEND
MOV SEND_BUF,#10000001B
LCALL SEND
SETB CS
RET
SF:
MOV A,REC_BUF ;把接收缓冲器的值给A
CJNE A,#28,SE
MOV IE,#0H
MOV AUXR1,#20H ;AUXR1的位ENBOOT=1
MOV R0,#12 ;假定fosc=12
MOV R1,#01H ;字节编程功能?
MOV DPTR,#20000 ;欲编程地址
LCALL 0FFF0H ;调用BOOT ROM固化程序
MOV SEND_BUF,#10100100B;发复位指令
LCALL SEND
SETB CS
MOV SEND_BUF,#10000001B;显示'2'表示擦除FLASH完毕
LCALL SEND
MOV SEND_BUF,#10000010B
LCALL SEND
SETB CS
RET
SE:
MOV A,REC_BUF
CJNE A,#20,SC
MOV IE,#0H
CLR RS1
CLR RS0
MOV 08H,#30H ;把(30H+PCA CNT)RAM区内容写入FLASH
MOV PCA_CNT,#206
MOV DPTR,#2000H
WWR:
MOV AUXR1,#20H
MOV R0,#12 ;fsoc=12
MOV R1,#02H ;字节编程功能
SETB RS0
MOV ACC,@R0 ;欲编程内容
INC R0
CLR RS0
PUSH DPH
PUSH DPL
LCALL 0FFF0H ;
POP DPL
POP DPH
INC DPTR
DJNZ PCA_CNT,WWR
MOV SEND_BUF,#10100100B ;发复位指令
LCALL SEND
SETB CS
MOV SEND_BUF,#10000010B ;显示'3'表示写FLASH完毕
LCALL SEND
SETB CS
RET
SC:
MOV A,REC_BUF ;
CJNE A,#4,PCOUT
MOV CCAPM1,#4CH ;PCA设置为高速输出模式
SETB P1.4
PIN:
MOV DPTR,#2000H ;取FLASH中存储的信息
MOV PCA_CNT,#101
JNB FLAG1,QIN ;按键未松开则送第二个信息
INC DPTR
INC DPTR
DEC PCA_CNT ;少发第一个脉冲
QIN:
CLR CCF1
SETB CR
QQ:
MOV CH,#0
MOV CL,#0
MOV CCAPM1,#4CH ;循环发送
CLR A
MOVC A,@A+DPTR
MOV CCAP1L,A
INC DPTR
CLR A
MOVC A,@A+DPTR
MOV CCAP1H,A
INC DPTR
WAIT5:
JBC CCF1,QQ1
SJMP WAIT5
QQ1:
DJNZ PCA_CNT,QQ
SETB FLAG1
MAIN_LP3:
JNB KEY,PIN ;判断按键松开否
MOV CCAPM1,#0H
CLR CR
CLR P1.4
MOV SEND_BUF,#10100100B ;发复位指令
LCALL SEND
SETB CS
MOV SEND_BUF,#10000011B ;显示'4'表示已发送一列信号
LCALL SEND
MOV SEND_BUF,#00000100B
LCALL SEND
SETB CS
RET
PCOUT:
MOV SEND_BUF,#10000010B ;显示'5'表示按下无效
LCALL SEND
MOV SEND_BUF,#10000101B
LCALL SEND
SETB CS
RET
;*************************************************
; SEND
;*************************************************
SEND:
MOV BIT_CNT,#8 ;设发送位数为8位
CLR CS
LCALL LONG_DELAY ;
SEND_LP1:
MOV A,SEND_BUF ;
RLC A
MOV SEND_BUF,A
MOV DIO,C
NOP
NOP
SETB CLK
LCALL SHORT_DELAY ;延时为10微秒
CLR CLK
LCALL SHORT_DELAY
DJNZ BIT_CNT,SEND_LP1 ;发送完8位返回
CLR DIO
RET
;*************************************************
; RECEIVE
;*************************************************
RECEIVE:
MOV BIT_CNT,#8
SETB