📄 ir_uart.asm
字号:
MOV g_IR_HEAD3,A ;
MOV A,g_BIT1_NUM ;
CJNE A,B,IR_MOUSE_ERR ; 计算1的个数是否正确
MOV g_IR_HEAD1,#c_IR_MOUSE ; 红外鼠标 导引头
ACALL OUT_IR_DATA ; 送出数据
AJMP IRDA_RETI ;
IR_MOUSE_ERR: AJMP INT_IRDA_ERR ; 错误处理中继站
;┌───────┬───────────────-┐;
;│IR_BIT4 │红外鼠标处理 │;
;└───────┴───────────────-┘;
IR_BIT4: MOV R3,#4 ; 红外键盘普通键处理
MOV B,#0 ;
IR_BIT4_PAR: ACALL IR_CLK ; 产生一个CLK
JB F0,IR_BIT4_RET ;
ACALL READ_IRKB_BIT ;
JB F0,IR_BIT4_RET ;
MOV A,B ; 暂存B
RRC A ;
MOV B,A ; 暂存B
DJNZ R3,IR_BIT4_PAR ; 4个bit 1的个数
SWAP A ; 高低位互换 因为接收的高四位才是1的个数
MOV B,A ; 暂存B
IR_BIT4_RET: RET ;
;┌───────┬───────────────-┐;
;│READ_YKQ_BYTE │读取遥控器一个字节数据 │;
;└───────┴───────────────-┘;
READ_YKQ_BYTE: MOV R4,#8 ; 接收一个字节8位
READ_YKQ_DATA: ACALL IR_CLK ; 产生一个CLK
JB F0,YKQ_DATA_ERR ;
ACALL READ_YKQ_BIT ; 读取一个BIT
JB F0,YKQ_DATA_ERR ; 接收一个BIT是否正确 压缩求值
MOV A,g_IR_DATA ;
RRC A ; 右移一位
MOV g_IR_DATA,A ;
DJNZ R4,READ_YKQ_DATA ;
YKQ_DATA_ERR: RET ; 返回时通过F0来表示正确与否
;┌───────┬───────────────-┐;
;│READ_IRKB_BYTE│读取红外键盘一个字节数据 │;
;└───────┴───────────────-┘;
READ_IRKB_BYTE: MOV R4,#8 ; 接收一个字节8位
READ_IRKB_DATA: ACALL IR_CLK ; 产生一个CLK
JB F0,IRKB_DATA_ERR ;
ACALL READ_IRKB_BIT ; 读取一个BIT
JB F0,IRKB_DATA_ERR ; 接收一个BIT是否正确 压缩求值
MOV A,g_IR_DATA ;
RRC A ; 右移一位
MOV g_IR_DATA,A ;
DJNZ R4,READ_IRKB_DATA ;
IRKB_DATA_ERR: RET ; 错误返回
;┌───────┬───────────────-┐;
;│READ_YKQ_BIT │读取遥控器一个BIT │;
;└───────┴───────────────-┘;
READ_YKQ_BIT: SETB F0 ; 错误标志
CLR C ; 清除 C 防止以前留下的 C=1
MOV A,g_IR_TMER ; 和最小的比
SUBB A,#c_YKQ_BIT1_E ; 先要掐头
JC YKQ_BIT_ERR ; C=1 说明 A<c_YKQ_BIT1_E 比最小的还要小 ERR
MOV A,g_IR_TMER ; 和最大的比
SUBB A,#c_YKQ_BIT0_S ; 去尾 增加一个一样大的
JNC YKQ_BIT_ERR ; C=0 说明 A>c_YKQ_BIT0_E 比最大的还要大 ERR
MOV A,g_IR_TMER ; 和BIT1比较
SUBB A,#c_YKQ_BIT1_S ; 和c_YKQ_BIT1_S 比小
JC YKQ_BIT_1 ; C=1 说明 c_YKQ_BIT1_E<A<c_YKQ_BIT1_S 是BIT1
MOV A,g_IR_TMER ; C=0 说明 A>c_YKQ_BIT1_S 还要和BIT0比较
SUBB A,#c_YKQ_BIT0_E ; 和c_YKQ_BIT0_E 比大 包括一样大
JNC YKQ_BIT_0 ; C=0 说明 c_YKQ_BIT0_E<A<c_YKQ_BIT0_S 是BIT0 C=1 说明 c_YKQ_BIT1_S<A<c_YKQ_BIT0_E ERR
RET ; 在 BIT1 和 BIT0 的之间的数值 可以滤掉 也可以保留 c_YKQ_BIT1_S<A<c_YKQ_BIT0_E
YKQ_BIT_1: SETB C ; BIT1通过C传递 C=1
YKQ_BIT_0: CLR F0 ; 处理正确 清除 错误标志 并且C=0 通过C传递 BIT0
YKQ_BIT_ERR: RET ; BIT0通过C传递 C=0 默认
;┌───────┬───────────────-┐;
;│READ_IRKB_BIT │读取红外键盘一个BIT │;
;└───────┴───────────────-┘;
READ_IRKB_BIT: SETB F0 ; 错误标志
CLR C ; 清除 C 防止以前留下的 C=1
MOV A,g_IR_TMER ; 和最小的比
SUBB A,#c_IRKB_BIT1_E ; 先要掐头
JC IRKB_BIT_ERR ; C=1 说明 比最小的还要小 ERR
MOV A,g_IR_TMER ; 和最大的比
SUBB A,#c_IRKB_BIT0_S ; 去尾 增加一个一样大的
JNC IRKB_BIT_ERR ; C=0 说明 比最大的还要大 ERR 还有一个刚好够减的情况
MOV A,g_IR_TMER ; 和BIT1比较
SUBB A,#c_IRKB_BIT1_S ; 和c_YKQ_BIT1_S 比小
JC IRKB_BIT_1 ; C=1 说明 c_YKQ_BIT1_E<A<c_YKQ_BIT1_S 是BIT1
MOV A,g_IR_TMER ; C=0 说明 A>c_YKQ_BIT1_S 还要和BIT0比较
SUBB A,#c_IRKB_BIT0_E ; 和c_YKQ_BIT1_E 比大 包括一样大
JNC IRKB_BIT_0 ; C=0 说明 c_YKQ_BIT0_E<A<c_YKQ_BIT0_S 是BIT0 C=1 说明比c_YKQ_BIT1_E 小 ERR
RET ; 在 BIT1 和 BIT0 的之间的数值 可以滤掉 也可以保留
IRKB_BIT_1: SETB C ; BIT1通过C传递 C=1
INC g_BIT1_NUM ; 1 的个数计数器加一
IRKB_BIT_0: CLR F0 ; 处理正确 清除 错误标志 并且C=0 通过C传递 BIT0
IRKB_BIT_ERR: RET ; BIT0通过C传递 C=0 默认
;┌───────┬───────────────-┐;
;│IR_HEAD │红外导引头判断 │;
;└───────┴───────────────-┘;
IR_HEAD: SETB F0 ; 错误标志
CLR f_YKQ ;
CLR f_YKQ_ACK ;
CLR f_IR_KB ;
CLR f_IR_EKB ;
CLR f_IR_MOUSE ;
MOV A,g_IR_TMER ; 照样掐头去尾
SUBB A,#c_YKQ_HEAD_E ; 和最小的比 包含一个相等的
JC IR_HEAD_ERR ; C=1 说明 比最小的还要小 ERR
MOV A,g_IR_TMER ; 和最大的比
SUBB A,#c_IRMS_HEAD_S ; 去尾
JNC IR_HEAD_ERR ; C=0 说明 比最大的还要大 ERR 还有一个相等的
MOV A,g_IR_TMER ; 判断是遥控器还是遥控键盘
SUBB A,#c_YKQ_ACK_S ;
JC YKQ_HEAD ; C=1 是遥控器 C=0还要判断
MOV A,g_IR_TMER ;
SUBB A,#c_IREK_HEAD_E ; 先判断错误 会不会比最小的还要小
JC IR_HEAD_ERR ; C=1 说明不够减 即比c_IRMS_HEAD_E小 不在遥控键盘范围
MOV A,g_IR_TMER ;
SUBB A,#c_IREK_HEAD_S ; 判断键盘还是鼠标
JNC IRKB_HEAD ; C=0 是红外键盘
SETB f_IR_EKB ; C=1 (包括刚好够减) 红外鼠标
AJMP IR_HEAD_RET ; 置标志位
IRKB_HEAD: MOV A,g_IR_TMER ; 判断是扩展键还是普通键
SUBB A,#c_IRKB_HEAD_S ;
JNC IREKB_HEAD ; C=0 比大的还大 ERR
SETB f_IR_KB ;
AJMP IR_HEAD_RET ;
IREKB_HEAD: MOV A,g_IR_TMER ;
SUBB A,#c_IRMS_HEAD_E ;
JC IR_HEAD_ERR ;
SETB f_IR_MOUSE ;
AJMP IR_HEAD_RET ;
YKQ_HEAD: MOV A,g_IR_TMER ; 遥控器头判断
SUBB A,#c_YKQ_HEAD_S ; 判断遥控器
JNC YKQ_ACK_HEAD ; C=0 说明够减 比c_YKQ_HEAD_S大 还有一种等于的 是 ACK
SETB f_YKQ ; C=1 说明是遥控器 不够减 比c_YKQ_HEAD_S小
AJMP IR_HEAD_RET ;
YKQ_ACK_HEAD: MOV A,g_IR_TMER ;
SUBB A,#c_YKQ_ACK_E ; 和c_YKQ_ACK_E比大
JC IR_HEAD_ERR ; C=1 说明不够减 比 c_YKQ_ACK_E小 err
SETB f_YKQ_ACK ; C=0 说明够减 比 c_YKQ_ACK_E大
IR_HEAD_RET: CLR F0 ; 正确判断 清除标志位
IR_HEAD_ERR: RET ;
;┌───────┬───────────────-┐;
;│IR_CLK │等待一个红外时钟 │;
;└───────┴───────────────-┘;
IR_CLK: SETB F0 ; 错误标志
IR_CLK_UP: JB f_IR_CLK,IR_CLK_DOWN ; 等待时钟为1
JNB f_IR_TIME_OVER,IR_CLK_UP ; 判断 时间溢出
RET ; 时间溢出 F0=1 时间溢出
IR_CLK_DOWN: JNB f_IR_CLK,IR_CLK_RET ; 等待时钟为0
JNB f_IR_TIME_OVER,IR_CLK_DOWN ; 判断 时间溢出
RET ; 时间溢出 F0=1 时间溢出
IR_CLK_RET: MOV g_IR_TMER,g_IR_TMER_DOG ; 传送本次计时数据
MOV g_IR_TMER_DOG,#0 ; 计时看门狗清零 进行下一个CLK计时
CLR F0 ; 正确 清除错误标志
RET ; 处理结束 F0=1 时间溢出
;┌───────┬───────────────-┐;
;│OUT_IR_DATA │红外数据压入数据缓冲区 │;
;└───────┴───────────────-┘;
OUT_IR_DATA: MOV R0,g_DATA_SP_E ; 取缓冲区指针
MOV @R0,g_IR_HEAD1 ; 送数据
INC R0 ; 缓冲区指针加一
MOV @R0,g_IR_HEAD2 ; 送数据
INC R0 ;
MOV @R0,g_IR_HEAD3 ;
INC R0 ;
MOV g_DATA_SP_E,R0 ; 保存指针
SETB f_DATA ; 申请输出数据
RET ;
;***************************************************;
;┌─────┬─────────────────-┐;
;│IR_INI │遥控参数初始化程序 │;
;├─────┼─────────────────-┤;
;│入口参数: │f_IR_IN=1 │;
;└─────┴─────────────────-┘;
IR_INI: CLR IE0 ; 清除红外中断
SETB TR1 ; 开定时器1
SETB ET1 ; 允许定时器1中断
SETB EX0 ; 允许外部中断0中断
SETB f_IR_CLK ; 置一输入
RET ;
;***************************************************;
;┌─────┬─────────────────-┐;
;│MYMCU │设置单片机的寄存器参数程序 │;
;├─────┼─────────────────-┤;
;│入口参数: │上电初始化,电源控制 │;
;├─────┼─────────────────-┤;
;│影响资源: │SFR │;
;└─────┴─────────────────-┘;
MYMCU: MOV TMOD,#c_TMOD ; T1编程为方式2定时状态,T0编程为方式3定时状态
MOV SCON,#c_SCON ; 串口方式 模式1 数据位8 停止位1
MOV PCON,#c_PCON ; 波特率加倍
MOV TL0,#c_TMER0L ; 定时器0 初值 工作在方式 3 计数方式
MOV TH0,#c_TMER0H ; 定时器0 另外一个8位定时器 初值 用TMER1中断
MOV TL1,#c_TMER1L ; 赋初值
MOV TH1,#c_TMER1H ; 波特率=19200,误差0( f =11.0592MHz)
SETB IT0 ; 选择外部中断 0 工作方式:负边沿触发方式
SETB IT1 ; 选择外部中断 1 工作方式:负边沿触发方式
CLR TR0 ; 关闭定时0
; CLR TR1 ; 开串口波特率
CLR EX0 ; 不允许 外部 0 中断
CLR ET0 ; 不允许 定时 0 中断
CLR EX1 ; 不允许 外部 1 中断
; CLR ET1 ; 不允许 定时 1 中断 串口波特率
; CLR ES ; 不允许 串口 中断
; CLR PX0 ; 设置 INT0 中断的优先级别 最高 红外
; CLR PT0 ; 设置 定时0中断的优先级别 最高 鼠标
; CLR PX1 ; 设置 INT1 中断的优先级别 最高 键盘
SETB PT1 ; 设置 定时1中断的优先级别 最高 系统时钟
; CLR PS ; 设置 串口 中断的优先级别 最高
CLR TF0 ; 清除鼠标中断
CLR TF1 ; 清除定时器1
CLR IE1 ; 清除键盘中断标志位
CLR IE0 ; 清除红外中断
CLR RI ; 串口接收中断
SETB EA ; 开启总中断
RET ;
;***************************************************;
;┌─────┬─────────────────-┐;
;│ DELAY │软件延时程序 │;
;├─────┼─────────────────-┤;
;│影响资源: │R5,R6,R7,g_INT_TMER_MS │;
;└─────┴─────────────────-┘;
INT_DELAY20MS: MOV R7,#20 ;
INT_DEL20MS: ACALL INT_DELAY1MS ;
DJNZ R7,INT_DEL20MS ;
RET ;
INI_DELAY3MS: MOV R6,#3 ;
INI_DEL3MS: ACALL INI_DELAY1MS ;
DJNZ R6,INI_DEL3MS ;
RET ;
INT_DELAY3MS: MOV R5,#3 ;
INT_DEL3MS: ACALL INT_DELAY1MS ;
DJNZ R5,INT_DEL3MS ;
RET ;
INT_DELAY1MS: MOV g_INT_TMER_MS,#0E5H ; 中断中的延时 1ms 计数值 晶振 11.0592MHZ
NOP ;
NOP ;
DJNZ g_INT_TMER_MS,$-2 ; 延时 4.4uS
RET ; 用了一个 R6 进行参数传递
INI_DELAY1MS: MOV g_INI_TMER_MS,#0E5H ; 初始化主程序中的延时 1ms 计数值 晶振 11.0592MHZ
NOP ;
NOP ;
DJNZ g_INI_TMER_MS,$-2 ; 延时 "R6"ms
RET ; 用了一个 R6 进行参数传递
DELAY100US: MOV g_TMER_US,#040H ; 延时 100Us 计数值 晶振 11.0592MHZ 指令周期 1.1US
DJNZ g_TMER_US,$ ; 延时 "g_TMER_US"Us
RET ;
;***************************************************;
; ORG 7FDH ; 最后两个字节
; LJMP MAIN ; 最后一条指令
END ; 代码结束
;***************************************************;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -