📄 ir_uart.asm
字号:
LED_WINK_LOOP: CPL f_LED2 ;
CALL INT_DELAY20MS ;
DJNZ g_SOFT_DOG,LED_WINK_LOOP ;
RET ;
;****************************************************
IROUT_DATA: CALL IROUT_DA_HEAD ; 发射红外导引头
MOV A,g_IR_HEAD1 ;
CALL IROUT_BYTE ;
MOV A,g_IR_HEAD2 ;
CALL IROUT_BYTE ;
MOV A,g_IR_HEAD3 ;
CALL IROUT_BYTE ;
MOV A,g_IR_HEAD3 ;
CPL A ;
CALL IROUT_BYTE ;
MOV R6,#17H ;
IROUT_DA_END: CALL IROUT_LOW ;
DJNZ R6,IROUT_DA_END ;
RET ;
;****************************************************
IROUT_BYTE: MOV R2,#8 ;
CLR C ;
IROUT_BYTE1: RRC A ; 低位在前
JC IROUT_DA_BIT1 ; 判断是1还是0
MOV R6,#17H ;
IROUT_DA_BIT0: CALL IROUT_LOW ;
DJNZ R6,IROUT_DA_BIT0 ;
MOV R6,#14H ;
IROUT_DA_BIT01: CALL IROUT_HIGH ;
DJNZ R6,IROUT_DA_BIT01 ;
AJMP IROUT_BYTE_LOOP ;
IROUT_DA_BIT1: MOV R6,#17H ;
IROUT_DA_BIT11: CALL IROUT_LOW ;
DJNZ R6,IROUT_DA_BIT11 ;
MOV R6,#3FH ;
IROUT_DA_BIT12: CALL IROUT_HIGH ;
DJNZ R6,IROUT_DA_BIT12 ;
IROUT_BYTE_LOOP:DJNZ R2,IROUT_BYTE1 ;
RET ;
;****************************************************
IROUT_DA_HEAD: MOV R7,#2 ;
MOV R6,#05DH ;
IROUT_DA_HEAD1: CALL IROUT_LOW ;
DJNZ R6,IROUT_DA_HEAD1 ;
DJNZ R7,IROUT_DA_HEAD1 ;
MOV R6,#0AAH ;
IROUT_DA_HEAD2: CALL IROUT_HIGH ;
DJNZ R6,IROUT_DA_HEAD2 ;
RET ;
;****************************************************
IROUT_LOW: SETB f_IR_OUT ;
MOV R1,#3 ;
DJNZ R1,$ ;
CLR f_IR_OUT ;
MOV R1,#4 ;
DJNZ R1,$ ;
RET ;
IROUT_HIGH: CLR f_IR_OUT ;
MOV R1,#8 ;
DJNZ R1,$ ;
RET ;
;***************************************************;
;┌─────┬─────────────────-┐;
;│INT_TMER1 │定时器1中断服务程序 │;
;├─────┼─────────────────-┤;
;│入口参数: │定时器中断 1 产生 │;
;├─────┼─────────────────-┤;
;│出口参数: │ │;
;├─────┼─────────────────-┤;
;│影响资源: │g_IR_TIME、g_WINK_TMER │;
;└─────┴─────────────────-┘;
INT_TMER1: MOV TH0,#c_TMER0H+08H ; 定时器0 另外一个8位定时器 初值 用TMER1中断 50US
JNB f_LED_WINK,IR_TIME ;
DJNZ g_WINK_TMER,IR_TIME ;
MOV g_WINK_TMER,#255 ;
CPL f_LED1 ;
DJNZ g_WINK_TMER1,IR_TIME ;
MOV g_WINK_TMER1,#4 ;
CLR f_LED_WINK ;
IR_TIME: DJNZ g_IR_TMER_DOG,TMER1_RETI ;
SETB f_IR_TIME_OVER ;
DJNZ g_IR_TMER_DOG1,TMER1_RETI ;
MOV g_IR_TMER_DOG1,#c_TMER_OVER ;
SETB f_TIME_OVER ; 定时器溢出标志 溢出时间:122880us
TMER1_RETI: RETI ;
;***************************************************;
;┌─────┬─────────────────-┐;
;│INT_UART │串口接收中断程序 │;
;├─────┼─────────────────-┤;
;│入口参数: │串口接收中断产生 RI=1 │;
;├─────┼─────────────────-┤;
;│出口参数: │ACC=SBUF │;
;├─────┼─────────────────-┤;
;│影响资源: │ACC │;
;└─────┴─────────────────-┘;
;***************************************************;
;┌─────┬─────────────────-┐;
;│INT_MOUSE │鼠标处理程序 │;
;├─────┼─────────────────-┤;
;│入口参数: │TMER0 计数溢出中断 产生 │;
;├─────┼─────────────────-┤;
;│出口参数: │鼠标数据:g_MOUSE_HEAD1-3 │;
;├─────┼─────────────────-┤;
;│影响资源: │ACC,PSW,g_MOUSE_DATA,g_MOUSE_HEAD1 │;
;└─────┴─────────────────-┘;
;***************************************************;
;┌─────┬─────────────────-┐;
;│INT_KB │键盘处理程序 │;
;├─────┼─────────────────-┤;
;│入口参数: │外部中断 1 产生 键盘CLK中断 │;
;├─────┼─────────────────-┤;
;│出口参数: │键盘数据:g_KB_HEAD1-3 │;
;├─────┼─────────────────-┤;
;│影响资源: │ACC,PSW,g_KB_DATA,g_KB_HEAD1-3 │;
;└─────┴─────────────────-┘;
;***************************************************;
;┌─────┬─────────────────-┐;
;│INT_IRDA │红外中断服务程序 │;
;├─────┼─────────────────-┤;
;│入口参数: │外部中断 0 产生 红外CLK中断 │;
;├─────┼─────────────────-┤;
;│出口参数: │红外数据:g_IR_HEAD1-3 │;
;├─────┼─────────────────-┤;
;│影响资源: │ACC,PSW,g_IR_DATA,g_IR_HEAD1-3 │;
;└─────┴─────────────────-┘; 所有处理在CLK为低的时候
INT_IRDA: PUSH ACC ; ACC压栈
MOV g_IR_TMER_DOG,#0 ; 计时看门狗清零
MOV g_IR_TMER_DOG1,#c_TMER_OVER ;
CLR f_IR_TIME_OVER ; 计时清零
ACALL IR_CLK ; 导引头时钟
JB F0,INT_IRDA_ERR ; 判断导引头的时钟是否正确
ACALL IR_HEAD ; 判断引导头
JB F0,INT_IRDA_ERR ; 判断导引头数据是否正确
JB f_YKQ,IR_TASK1 ; 是遥控器吗?
JB f_YKQ_ACK,IR_TASK2 ; 是遥控器应答吗?
JB f_IR_KB,IR_TASK3 ; 是遥控键盘普通键吗?
JB f_IR_EKB,IR_TASK4 ; 是遥控键盘扩展键吗?
JB f_IR_MOUSE,IR_TASK5 ; 是遥控鼠标吗?
INT_IRDA_ERR: ACALL INT_DELAY20MS ; 要延时到干扰过去 都不是 肯定有问题?或者是干扰 错误处理中继站
CLR F0 ; 清除错误标志 错误标志只在本身自己的模块中起作用 不要对其他模块造成影响
IRDA_RETI: SETB f_IR_CLK ;
MOV TL0,#c_TMER0L ; 送0FFH 确保下次还能中断
CLR TF0 ; 清除鼠标中断
CLR IE1 ; 清除键盘中断标志位
CLR IE0 ; 清除红外中断
POP ACC ; ACC出栈
RETI ; 中断返回
;***************************************************;
IR_TASK1: AJMP YKQ ; 遥控器
IR_TASK2: AJMP YKQ_ACK ; 遥控器应答
IR_TASK3: AJMP IR_KB ; 遥控键盘普通键
IR_TASK4: AJMP IR_EKB ; 遥控键盘扩展键
IR_TASK5: AJMP IR_MOUSE ; 遥控鼠标
;***************************************************;
;┌───────┬───────────────-┐;
;│YKQ │红外遥控器处理 │; IR_TASK1
;└───────┴───────────────-┘;
YKQ: ACALL READ_YKQ_BYTE ; 遥控器处理 读一个字节数据
JB F0,YKQ_ERR ; 接收一个字节是否正确
MOV g_IR_HEAD1,A ; 保存
ACALL READ_YKQ_BYTE ;
JB F0,YKQ_ERR ;
MOV g_IR_HEAD2,A ;
ACALL READ_YKQ_BYTE ;
JB F0,YKQ_ERR ;
MOV g_IR_HEAD3,A ;
ACALL READ_YKQ_BYTE ; 第3个字节的反码
JB F0,YKQ_ERR ;
CPL A ; 取反
CJNE A,g_IR_HEAD3,YKQ_ERR ; 比较反码是否正确
CLR f_TIME_OVER ; 时间溢出标志 初始化
ACALL OUT_IR_DATA ; 送出数据
MOV g_YKQ_DELAY,#c_YKQKEY_delay ; 遥控器连健重码连发个数初值
AJMP IRDA_RETI ;
YKQ_ERR: AJMP INT_IRDA_ERR ; 错误处理中继站
;┌───────┬───────────────-┐;
;│YKQ_ACK │处理应答信号 │; IR_TASK2
;└───────┴───────────────-┘;
YKQ_ACK: JB f_TIME_OVER,YKQ_ACK_RET ; 判断是否时间有溢出过 时间溢出过是不处理应答信号
DJNZ g_YKQ_DELAY,YKQ_ACK_RET ; 计数器还没有为0
MOV g_YKQ_DELAY,#c_YKQKEY_again ; 遥控器重码连发个数初值
ACALL OUT_IR_DATA ; 遥控器应答处理 送出数据
YKQ_ACK_RET: AJMP IRDA_RETI ;
;┌───────┬───────────────-┐;
;│IR_KB │红外键盘普通键处理 │; IR_TASK3
;└───────┴───────────────-┘;
IR_KB: ACALL IR_BIT4 ; 前面4bit的处理都一样 为了节省代码做成子程序的方式
JB F0,IR_KB_ERR ; 判断时候处理成功
MOV g_BIT1_NUM,#0 ; 1的计数器清零
ACALL READ_IRKB_BYTE ; 读取一个字节
JB F0,IR_KB_ERR ;
MOV g_IR_HEAD3,A ;
MOV g_IR_HEAD2,B ; 前4bit 放在第二个字节
JBC B.3,IR_KEY_DM ; B.3=0通码 B.3=1 断码
JB f_TIME_OVER,IR_KEY_TM ; 通码判断是否第一键 立即发 通过判断时间有没有溢出 可知是否第一次按键
DJNZ g_IRKB_DELAY,IR_KB_RET ; 计数延时
MOV g_IRKB_DELAY,#c_IRKB_again ; 接下来的 按键延时相对较短
AJMP IR_KB_DATA ;
IR_KEY_TM: MOV g_IRKB_DELAY,#c_IRKB_delay ; 初始化 按键延时 放在断码发送之后 因为断码发送之后肯定要接收通码
CLR f_TIME_OVER ; 时间溢出标志 初始化
AJMP IR_KB_DATA ;
IR_KEY_DM: SETB f_TIME_OVER ;
IR_KB_DATA: MOV A,g_BIT1_NUM ; 断码 立即发
CJNE A,B,IR_KB_ERR ; 计算1的个数是否正确
MOV g_IR_HEAD1,#c_IR_KB ; 红外键盘扩展键 导引头
ACALL OUT_IR_DATA ; 送出数据
IR_KB_RET: AJMP IRDA_RETI ;
IR_KB_ERR: AJMP INT_IRDA_ERR ; 错误处理中继站
;┌───────┬───────────────-┐;
;│IR_EKB │红外键盘扩展键处理 │; IR_TASK4
;└───────┴───────────────-┘;
IR_EKB: ACALL IR_BIT4 ; 前面4bit的处理都一样 为了节省代码做成子程序的方式
JB F0,IR_EKB_ERR ;
MOV g_BIT1_NUM,#0 ; 1的计数器清零
ACALL READ_IRKB_BYTE ;
JB F0,IR_EKB_ERR ;
MOV g_IR_HEAD2,A ;
ACALL READ_IRKB_BYTE ;
JB F0,IR_EKB_ERR ;
MOV g_IR_HEAD3,A ;
MOV A,g_BIT1_NUM ;
CJNE A,B,IR_EKB_ERR ; 计算1的个数是否正确
MOV g_IR_HEAD1,#c_IR_EKB ; 红外键盘扩展键 导引头
MOV A,g_IR_HEAD3 ;
IRKB_Alt: CJNE A,#c_IRKB_Alt,IRKB_Ctrl ; 判断是 Alt
AJMP IRDA_RETI ;
IRKB_Ctrl: CJNE A,#c_IRKB_Ctrl,IRKB_Shift ; 判断是 Ctrl
AJMP IRDA_RETI ;
IRKB_Shift: CJNE A,#c_IRKB_Shift,IRKB_Shift_R; 判断是 Shift
AJMP IRDA_RETI ;
IRKB_Shift_R: CJNE A,#c_IRKB_Shift_R,IRKB_Win ; 判断是 Shift_R
AJMP IRDA_RETI ;
IRKB_Win: CJNE A,#c_IRKB_Win,IRKB_KEY ; 判断是 Win
AJMP IRDA_RETI ;
IRKB_KEY: JB f_TIME_OVER,IR_EKEY_TM ; 通码判断是否第一键 立即发 通过判断时间有没有溢出 可知是否第一次按键
DJNZ g_IRKB_DELAY,IR_EKB_RET ; 计数延时
MOV g_IRKB_DELAY,#c_IRKB_again ; 接下来的 按键延时相对较短
AJMP IR_EKB_DATA ;
IR_EKEY_TM: MOV g_IRKB_DELAY,#c_IRKB_delay ; 初始化 按键延时 放在断码发送之后 因为断码发送之后肯定要接收通码
CLR f_TIME_OVER ; 时间溢出标志 初始化
IR_EKB_DATA: ACALL OUT_IR_DATA ; 送出数据
IR_EKB_RET: AJMP IRDA_RETI ;
IR_EKB_ERR: AJMP INT_IRDA_ERR ; 错误处理中继站
;┌───────┬───────────────-┐;
;│IR_MOUSE │红外鼠标处理 │; IR_TASK5
;└───────┴───────────────-┘;
IR_MOUSE: ACALL IR_BIT4 ; 前面4bit的处理都一样 为了节省代码做成子程序的方式
JB F0,IR_MOUSE_ERR ;
MOV g_BIT1_NUM,#0 ; 1的计数器清零
ACALL READ_IRKB_BYTE ;
JB F0,IR_MOUSE_ERR ;
MOV g_IR_HEAD2,A ;
ACALL READ_IRKB_BYTE ;
JB F0,IR_MOUSE_ERR ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -