|
PinBEEP EQU P2.3
IrPin EQU P3.2
SCL EQU P2.1
SDA EQU P2.0
AddressH EQU 0AH
AddressL EQU 0BH
Address EQU 0EH
I2CData EQU 0FH
IrDataA EQU 10H
IrDataB EQU 11H
IrDataC EQU 12H
IrDataD EQU 13H
LED1 EQU 18H
LED2 EQU 19H
LED3 EQU 1AH
LED4 EQU 1BH
LedT0 EQU 1CH
Flag EQU 20H
FlagKeyRP EQU 20H.0 ;禁止按键重复执行
OutBuf EQU 40H
ComBuf EQU 50H
;=====================================================================================
ORG 0000H
JMP START
;=====================================================================================
ORG 000BH ;定时器0中断入口
;定时中断主要作显示用
INT_TO:
PUSH ACC
PUSH PSW
CLR TF0 ;清定时0中断标?
MOV TH0,#0F6H ;2.5MS
MOV TL0,#03DH ;
MOV A,#11110000B ;关数码管
ORL P2,A
MOV DPTR,#TABLE
MOV A,LedT0
CJNE A,#0,INT_T0_1
MOV A,LED1
MOVC A,@A+DPTR
MOV P0,A
CLR P2.4
MOV LedT0,#1
LJMP INT_T0_END
INT_T0_1:
MOV A,LedT0
CJNE A,#1,INT_T0_2
MOV A,LED2
MOVC A,@A+DPTR
MOV P0,A
CLR P2.5
MOV LedT0,#2
LJMP INT_T0_END
INT_T0_2:
MOV A,LedT0
CJNE A,#2,INT_T0_3
MOV A,LED3
MOVC A,@A+DPTR
MOV P0,A
CLR P2.6
MOV LedT0,#3
LJMP INT_T0_END
INT_T0_3:
MOV A,LED4
MOVC A,@A+DPTR
MOV P0,A
CLR P2.7
MOV LedT0,#0
LJMP INT_T0_END
INT_T0_END:
POP PSW
POP ACC
RETI
TABLE:
DB 00101000B ;0
DB 11101011B ;1
DB 00110010B ;2
DB 10100010B ;3
DB 11100001B ;4
DB 10100100B ;5
DB 00100100B ;6
DB 11101010B ;7
DB 00100000B ;8
DB 10100000B ;9
DB 01100000B ;A
DB 00100101B ;b
DB 00111100B ;C
DB 00100011B ;d
DB 00110100B ;E
DB 01110100B ;F
DB 11110111B ;-
DB 11111111B ;
;=====================================================================================
START:
CLR Flag
mov sp,#60h
;===================================================
;串口初始化
MOV SCON,#00H
MOV TCON,#00H
MOV IE,#00H
;TMOD: GATE|C/!T|M1|M0|GATE|C/!T|M1|M0
; 0 0 1 0 0 0 0 1
MOV TMOD,#00100001b ;T1八位重载,T0十六位定时模式
MOV TH1,#0FFH
MOV TL1,#0FFH ;波特率28800
;SCON: SM0|SM1|SM2|REN|TB8|RB8|TI|RI
; 0 1 0 1 0 0 0 0
MOV SCON,#01010000b
SETB TR1
CLR RI
;===================================================
;定时器中断初始化
; MOV TMOD,#01H ;设定T0为十六位定时模式。
MOV TH0,#0F6H ;2MS
MOV TL0,#03DH ;
SETB TR0 ;开定时器0
SETB ET0 ;致能定时0中断
CLR TF0 ;清定时0中断标志
SETB EA ;开总中断
MOV LedT0,#00H
MOV LED1,#0
MOV LED2,#0
MOV LED3,#0
MOV LED4,#0
;=====================================================================================
MAIN:
;=====================================================================================
;遥控扫描
MAIN_IR:
JB IrPin,MAIN_IR_NEXT
JMP IR
MAIN_IR_NEXT:
;=====================================================================================
;按键扫描
MAIN_KEY:
MOV A,P3
ORL A,#00000111B
CPL A
JZ MAIN_KEY_NO
CALL DELAY2400 ;延时去抖
MOV A,P3
ORL A,#00000111B
CPL A
JZ MAIN_KEY_NO
;
JMP KEY_GOTO
MAIN_KEY_NO:
CLR FlagKeyRP
MAIN_KEY_NEXT:
;=====================================================================================
;串口接收
MAIN_RS232_RX:
JNB RI,MAIN_RS232_RX_NEXT
CALL RS232_Receive
JNZ MAIN_RS232_RX_NEXT
JMP RS232_GOTO
MAIN_RS232_RX_NEXT:
JMP MAIN
;=====================================================================================
;遥控处理
IR_GOTO:
MOV R0,#OutBuf
MOV A,#85 ;开始位
MOV @R0,A
MOV R0,#OutBuf+1
MOV A,#2 ;遥控信息
MOV @R0,A
MOV R0,#OutBuf+2
MOV A,IrDataA
MOV @R0,A ;用户码1
MOV R0,#OutBuf+3
MOV A,IrDataB
MOV @R0,A ;用户码2
MOV R0,#OutBuf+4
MOV A,IrDataC
MOV @R0,A ;数据码1
MOV R0,#OutBuf+5
MOV A,IrDataD
MOV @R0,A ;数据码2
CALL RS232_SendData ;发送
JMP MAIN_IR_NEXT
;=====================================================================================
;遥控处理
KEY_GOTO:
JB FlagKeyRP,KEY_GOTO_END
SETB FlagKeyRP
MOV B,A
MOV R0,#OutBuf
MOV A,#85 ;开始位
MOV @R0,A
MOV R0,#OutBuf+1
MOV A,#1 ;按键信息
MOV @R0,A
MOV R0,#OutBuf+2
MOV @R0,B ;按键值
CALL RS232_SendData ;发送
KEY_GOTO_END:
JMP MAIN_KEY_NEXT
;=====================================================================================
RS232_GOTO:
MOV R0,#ComBuf
MOV A,@R0
XRL A,#85
JNZ RS232_GOTO_END ;开始码不等于85,则退出
MOV R0,#ComBuf+1
MOV A,@R0
CJNE A,#1,$+6
LJMP RS232_GOTO_LED
CJNE A,#2,$+6
LJMP RS232_GOTO_DIGIT
CJNE A,#3,$+6
LJMP RS232_GOTO_READ_2402
CJNE A,#4,$+6
LJMP RS232_GOTO_WRITE_2402
RS232_GOTO_END:
JMP MAIN
;================================================================
RS232_GOTO_LED:
MOV R0,#ComBuf+2
MOV A,@R0
CPL A
MOV P1,A
CALL BEEP ;响一下
JMP MAIN
;================================================================
RS232_GOTO_DIGIT:
MOV R0,#ComBuf+2
MOV A,@R0
ANL A,#00001111B
MOV LED1,A
MOV R0,#ComBuf+3
MOV A,@R0
ANL A,#00001111B
MOV LED2,A
MOV R0,#ComBuf+4
MOV A,@R0
ANL A,#00001111B
MOV LED3,A
MOV R0,#ComBuf+5
MOV A,@R0
ANL A,#00001111B
MOV LED4,A
CALL BEEP ;响一下
JMP MAIN
;================================================================
RS232_GOTO_READ_2402:
MOV R0,#ComBuf+2
MOV A,@R0
MOV Address,A
CALL I2C_READ ;读出数据
JC RS232_GOTO_READ_2402_END ;读数数失败
;发送数据
MOV B,A
MOV R0,#OutBuf
MOV A,#85 ;开始位
MOV @R0,A
MOV R0,#OutBuf+1
MOV A,#3 ;24C02数据信息
MOV @R0,A
MOV R0,#OutBuf+2
MOV A,Address
MOV @R0,A ;地址
MOV R0,#OutBuf+3
MOV A,I2CData
MOV @R0,A ;数据
CALL RS232_SendData ;发送
JMP MAIN
RS232_GOTO_READ_2402_END:
JMP MAIN
;================================================================
RS232_GOTO_WRITE_2402:
MOV R0,#ComBuf+2
MOV A,@R0
MOV Address,A
MOV R0,#ComBuf+3
MOV A,@R0
MOV I2CData,A
CALL I2C_WRITE ;读出数据
JC RS232_GOTO_WRITE_2402_END ;读数数失败
CALL BEEP ;响一下
RS232_GOTO_WRITE_2402_END:
JMP MAIN
;=====================================================================================
; RS232 通讯子程序
;=====================================================================================
;=====================================================================================
;接收数据,6字节
;=====================================================================================
RS232_Receive:
CLR RI
MOV R0,#ComBuf
MOV @R0,SBUF
MOV R7,#6
RS232_Receive_LOOP:
;超时检测
MOV R3,#250
RS232_Receive_DELAY_R3:
MOV R4,#250
RS232_Receive_DELAY_R4:
JB RI,RS232_Receive_GO
DJNZ R4,RS232_Receive_DELAY_R4
DJNZ R3,RS232_Receive_DELAY_R3
JMP RS232_Receive_ERROR
RS232_Receive_GO:
INC R0
MOV @R0,SBUF
CLR RI
DJNZ R7,RS232_Receive_LOOP
RS232_Receive_RIGHT:
SETB C
RET
RS232_Receive_ERROR:
CLR C
RET
;=====================================================================================
;发送数据,6字节
;=====================================================================================
RS232_SendData:
MOV R0,#OutBuf
MOV R7,#6
RS232_SendData_18BYTE:
CLR TI
MOV SBUF,@R0
JNB TI,$ ;等待发送完成
CLR TI
INC R0
DJNZ R7,RS232_SendData_18BYTE
RET
;=====================================================================================
; AT24C01 处理子程序
;=====================================================================================
/*------------------------------------------------------
写一个字节 Address地址 I2CDatata写入的数据
------------------------------------------------------*/
I2C_WRITE:
MOV R6,#30 ;等待30MS
I2C_WRITE_A:
call I2C_START
MOV A,#10100000B
call I2C_SEND8BIT
call I2C_ACK
JNC I2C_WRITE_A_GO ;=1,表示无确认,再次发送
CALL DELAY1000
DJNZ R6,I2C_WRITE_A
JMP I2C_WRITE_ERROR
I2C_WRITE_A_GO:
MOV A,Address
call I2C_SEND8BIT
call I2C_ACK
MOV A,I2CData
call I2C_SEND8BIT
call I2C_ACK
call I2C_STOP
CLR C
RET
I2C_WRITE_ERROR:
SETB C
RET
/*------------------------------------------------------
读一个字节 Address地址 Data读出的数据
------------------------------------------------------*/
I2C_READ:
MOV R6,#30 ;等待30MS
I2C_READ_A:
call I2C_START
MOV A,#10100000B
call I2C_SEND8BIT
call I2C_ACK
JNC I2C_READ_A_GO ;=1,表示无确认,再次发送
CALL DELAY1000
DJNZ R6,I2C_READ_A
JMP I2C_READ_ERROR
I2C_READ_A_GO:
MOV A,Address
call I2C_SEND8BIT
call I2C_ACK
MOV R6,#30 ;等待30MS
I2C_READ_B:
call I2C_START
MOV A,#10100001B
call I2C_SEND8BIT
call I2C_ACK
JNC I2C_READ_B_GO ;=1,表示无确认,再次发送
CALL DELAY1000
DJNZ R6,I2C_READ_B
JMP I2C_READ_ERROR
I2C_READ_B_GO:
call I2C_RECEIVE8BIT
MOV I2CData,A
call I2C_ACK
call I2C_STOP
CLR C
RET
I2C_READ_ERROR:
SETB C
RET
;发送开始信号
I2C_START:
SETB SCL
SETB SDA
NOP
NOP
CLR SDA
NOP
NOP
CLR SCL
RET
;发送结束信号
I2C_STOP:
CLR SDA
NOP
NOP
SETB SCL
NOP
NOP
SETB SDA
RET
;发送接收确认信号
I2C_ACk:
SETB SDA
SETB SCL
NOP
NOP
JB SDA,I2C_ACK0
CLR C
SJMP I2C_ACK_END
I2C_ACK0:
SETB C
I2C_ACK_END:
CLR SCL
RET
;送八位数据
I2C_SEND8BIT:
MOV B,#08H
I2C_SEND8BIT_A:
RLC A
MOV SDA,C
SETB SCL
NOP
NOP
CLR SCL
DJNZ B,I2C_SEND8BIT_A
RET
;接收八位数据
I2C_RECEIVE8BIT:
MOV B,#08H
CLR A
SETB SDA
I2C_RECEIVE8IT_A:
SETB SCL
NOP
NOP
MOV C,SDA
RLC A
CLR SCL
DJNZ B,I2C_RECEIVE8IT_A
RET
;=====================================================================================
; 遥控接收子程序
;=====================================================================================
IR:
;以下对遥控信号的9000微秒的初始低电平信号的识别,波形见图5。
MOV R6,#9
IR_SB:
ACALL DELAY882 ;调用882微秒延时子程序
JB IrPin,IR_ERROR ;延时882微秒后判断P3.2脚是否出现高电平如果有就退出解 ;码程序
DJNZ R6,IR_SB ;重复10次,目的是检测在8820微秒内如果出现高电平就退 ;出解码程序
;识别连发码,和跳过4.5ma的高电平。
JNB IrPin, $ ;等待高电平避开9毫秒低电平引导脉冲
ACALL DELAY2400
JNB IrPin,IR_Rp ;这里为低电平,认为是连发码信号,见图6。
ACALL DELAY2400 ;延时4.74毫秒避开4.5毫秒的结果码
;以下32数据码的读取 ,0和1的识别 请看图2
MOV R1,#IrDataA ;设定IrDataA为起始RAM区
MOV R2,#4
IR_4BYTE:
MOV R3,#8
IR_8BIT:
JNB IrPin,$ ;等待地址码第一位的高电平信号
LCALL DELAY882 ;高电平开始后用882微秒的时间尺去判断信号此时的高低电 ;平状态
MOV C,IrPin ;将P3.2引脚此时的电平状态0或1存入C中
JNC IR_8BIT_0 ;如果为0就跳转到IR_8BIT_0
LCALL DELAY1000
IR_8BIT_0:
MOV A,@R1 ;将R1中地址的给A
RRC A ;将C中的值0或1移入A中的最低位
MOV @R1,A ;将A中的数暂时存放在R1中
DJNZ R3,IR_8BIT ;接收地址码的高8位
INC R1 ;对R1中的值加1,换下一个RAM
DJNZ R2,IR_4BYTE ;接收完16位地址码和8位数据码和8位数据,
;存放在1AH/1BH/1CH/1DH的RAM中
;解码成功
JMP IR_GOTO
IR_Rp:
;这里为重复码执行处
;按住遥控按键时,每过108ms就到这里来
LJMP MAIN ;退出解码子程序
IR_ERROR:
;错语退出
LJMP MAIN ;退出解码子程序
;=============================882
DELAY882: ;1.085x ((202x4)+5)=882
MOV R7,#202
DELAY882_A:
NOP
NOP
DJNZ R7,DELAY882_A
RET
;=============================1000
DELAY1000: ;1.085x ((229x4)+5)=999.285
MOV R7,#229
DELAY1000_A:
NOP
NOP
DJNZ R7,DELAY1000_A
RET
;=============================2400
DELAY2400: ;1.085x ((245x9)+5)=2397.85
MOV R7,#245
DELAY2400_A:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R7,DELAY2400_A
RET
;=========================================
;接收正确 响一下
BEEP:
CLR PinBEEP
CALL DELAY2400
CALL DELAY2400
CALL DELAY2400
CALL DELAY2400
CALL DELAY2400
CALL DELAY2400
CALL DELAY2400
CALL DELAY2400
CALL DELAY2400
CALL DELAY2400
SETB PinBEEP
RET
END
|
|