📄 ir_uart.asm
字号:
;*******************************************************************************************
; 文件名: IR_UART.ASM *
; 创建人: 邱作霖 创建时间 : 2005.10.1 *
; 修改人: 邱作霖 修改时间 : 2005.10.1 *
; 功能 : 接收红外键盘\鼠标数据 上位机通讯 送出数据 红外学习、红外发射 *
; 版权 : *
;*******************************************************************************************
; IR_UART.asm ; 文件名
; IR1.0 ; 版本
INCLUDE "MAIN.H" ; 包含文件 伟福自定义包含文件
;$INCLUDE (MAIN.H) ; 包含文件 COMP51定义包含文件
; 代码开始 ;┌──────────────────┐
ORG 0000H ;│代码段开始地址 │
LJMP MAIN ;│ │
ORG 0003H ;│外部中断0 入口: IE0 红外通讯 │
LJMP INT_IRDA ;│ │
DB 32H ;│防止 程序调入 中断向量地址, 清零 │
ORG 000BH ;│定时器 T0 中断入口地址 32H = RETI │
DB 32H ;│将 不使用的 中断地址 清零 │
ORG 0013H ;│外部中断1 入口: IE1 键盘通讯 │
DB 32H ;│防止 程序调入 中断向量地址, 清零 │
ORG 001BH ;│定时器 T1 中断入口地址 │
LJMP INT_TMER1 ;│定时器 T1 中断入口地址 │
DB 32H ;│ │
; ORG 0023H ;│串口 中断入口地址 │
; LJMP INT_UART ;│串口 中断入口地址 │
; DB 00H,00H,00H,00H,32H ;│ │
;***************************************************;└──────────────────┘
; 程序开始 ;
MAIN: ACALL MYMCU ; 设置单片机的参数
MOV R0,#7FH ; 清零前 RAM 128 字节
MOV @R0,#00H ; 00H-7FH
DJNZ R0,$-2 ; 清理 残留的数据,在热启动时有用 一般在软开机
CLR f_IR_OUT ; 置0 红外发射
CLR f_LED1 ; LED灭
CLR f_LED2 ; LED灭
CLR f_LED3 ; LED灭
CLR f_LED4 ; LED灭
;***************************************************;
; 系统资源初始化 ;
SYSTEM: MOV SP,#c_SYSTEM_SP ; 设置堆栈
MOV g_DATA_SP_E,#c_DATA_SP_S ; 送数据缓冲区片内数据 RAM 指针 初始值
MOV g_WINK_TMER,#255 ; LED闪烁时间计数器 初值 大概255*60us
MOV g_WINK_TMER1,#2 ; LED闪烁次数计数器 初值 闪两次
MOV g_IR_TMER_DOG1,#c_TMER_OVER ;
ACALL IR_INI ; 红外复位子程序
SETB EA ; 开启总中断
;***************************************************;
; 主循环 优先级从上到下减小 ;
MAIN_LOOP: JB f_DATA,TASK1 ; 单片机是否有数据要上传给CPU
JB RI,TASK2 ; 是否收到串口数据
SETB EX0 ; 允许 外部 0 中断 实时设置中断,防止中断被屏蔽。红外通讯
LOOP: AJMP MAIN_LOOP ; 循环结束
; 主循环结束 ;
;***************************************************;
; 任务表 ; 优先级从上到下减小
TASK1: AJMP DATA_OUT ; 键盘鼠标数据缓冲区满 使用模拟串口送给上位机cpu19200
TASK2: AJMP UART_RXD ; 接收到上位机CPU数据 处理 19200
; 任务表结束 ; 任务表结束
;***************************************************;
;┌─────┬─────────────────-┐;
;│DATA_OUT │送出缓冲区数据 │;
;├─────┼─────────────────-┤;
;│入口参数: │f_DATA=1 │;
;├─────┼─────────────────-┤;
;│出口参数: │ │;
;├─────┼─────────────────-┤;
;│影响资源: │A,R1,g_DATA_SP_E │;
;└─────┴─────────────────-┘;
DATA_OUT: ACALL DATA_TXD ; TASK1 送出数据
CLR f_DATA ; 处理完毕
AJMP MAIN_LOOP ; 退出
;┌─────┬─────────────────-┐;
;│DATA_TXD │ 清缓冲区 │;
;└─────┴─────────────────-┘;
DATA_TXD: MOV R1,#c_DATA_SP_S ; 送数据缓冲区片内数据 RAM 指针 初始值
DATA_TXD_LOOP: MOV A,R1 ;
CJNE A,g_DATA_SP_E,DATA_TXD_BYTE ; 判断是否栈底 不是就送出数据
SETB f_LED_WINK ; 申请LED 闪烁
DATA_TXD_RET: MOV g_DATA_SP_E,#c_DATA_SP_S ; 送数据缓冲区片内数据 RAM 指针 初始值
RET ;
DATA_TXD_BYTE: MOV A,@R1 ; 取数据 间接寻址
ACALL UART_TXD ;
INC R1 ; 调整指针
AJMP DATA_TXD_LOOP ; 继续送出数据
;┌─────┬─────────────────-┐;
;│UART_TXD │ 从串口送出数据 │;
;└─────┴─────────────────-┘;
UART_TXD: CLR TI ; 冗余指令 防止 以前的TI没有清除 TI中断需要软件清除
MOV SBUF,A ; 串口送出数据
MOV g_SOFT_DOG,#0 ; 软件看门狗延时 最大4*256=1024us
WAIT_TI: JB TI,TXD_RET ; 等待发送完毕 ,需要加限时服务 如果 1024us内没有收到 放弃本次发送
DJNZ g_SOFT_DOG,WAIT_TI ; 防止串口出错一直在这里等待
RET ; 时间溢出 返回 暂时没有考虑传输错误的处理
TXD_RET: CLR TI ; TI中断需要软件清除
RET ;
;****************************************************
;┌─────┬─────────────────-┐;
;│UART_RXD │上位机串口命令处理 │;
;├─────┼─────────────────-┤;
;│入口参数: │RI=1 │;
;├─────┼─────────────────-┤;
;│出口参数: │ │;
;├─────┼─────────────────-┤;
;│影响资源: │A,SBUF │;
;└─────┴─────────────────-┘;
UART_RXD: CLR RI ; TASK2 处理了 清除标志位
MOV A,SBUF ; 接收的CPU模拟串口数据
;┌──────┬────────────────-┐;
;│FACTORY │工厂测试命令 │;
;└──────┴────────────────-┘;
FACTORY: CJNE A,#"F",IROUT ;
CLR f_LED3 ; 工厂测试 LED关闭
ACALL UART_TXD ;
MOV A,#0DH ;
ACALL UART_TXD ;
MOV DPTR,#FACTORY_LIST ;
MOV R7,#19 ; 计数器
FACTORY_LOOP: CLR A ;
MOVC A,@A+DPTR ;
ACALL UART_TXD ;
INC DPTR ;
DJNZ R7,FACTORY_LOOP ; 是否传输完毕
AJMP FACTORY_TEST ;
FACTORY_LIST: DB "enter factory mode" ;
DB 0DH, ; 回车 0AH:新行
;┌──────┬────────────────-┐;
;│FACTORY_TEST│工厂测试 │;
;├──────┼────────────────-┤;
;│入口参数: │收到上位机串口命令“F” │;
;└──────┴────────────────-┘;
FACTORY_TEST: CLR EX0 ; 不允许红外中断 进入工厂测试,独占模式 只有定时器和串口工作
CLR ET0 ; 不允许鼠标中断
CLR EX1 ; 不允许键盘中断
MOV R3,#0 ; 计时器清零
CLR f_TIME_OVER ; 标志位清零
TEST_LOOP: JB RI,TEST_RI ; 是否收到串口数据
JB f_TIME_OVER,TEST_TIME ; 是否计满122880us
AJMP TEST_LOOP ; 循环
TEST_RI: CLR RI ; TASK2 处理了 清除标志位
MOV A,SBUF ; 接收的CPU模拟串口数据
CJNE A,#"f",TEST_LOOP ; 除了"f"啥子都不处理。 "f":喂狗指令
ACALL UART_TXD ;
MOV A,#0DH ;
ACALL UART_TXD ;
MOV R3,#0 ; 计时器清零
AJMP TEST_LOOP ; 上位机工厂测试清零指令
TEST_TIME: CLR f_TIME_OVER ; 清除122880us时间溢出标志位
INC R3 ; 计数器加一
MOV A,R3 ; 判断是否溢出
CJNE A,#60,TEST_LOOP ; 总时间 :60*122880uS= 7.372800秒
SETB f_LED3 ; 工厂测试看门狗溢出 LED打开 报警
MOV DPTR,#TEST_TIME_LIST ;
MOV R7,#10 ; 计数器
TEST_TIME_LOOP: CLR A ;
MOVC A,@A+DPTR ;
ACALL UART_TXD ;
INC DPTR ;
DJNZ R7,TEST_TIME_LOOP ; 是否传输完毕
AJMP MAIN_LOOP ;
TEST_TIME_LIST: DB "time over" ;
DB 0DH, ; 回车 0AH:新行
;┌─────┬─────────────────-┐;
;│IROUT │红外发射处理程序 │;
;└─────┴─────────────────-┘;
IROUT: CJNE A,#"S",VER ; 判断是否红外发射 后面跟3个字节的遥控器键码数据
CALL IROUT_OUT ; 调用红外发射程序
ACALL UART_TXD ; 返回命令字
MOV A,#0DH ; 送回车换行
ACALL UART_TXD ;
AJMP MAIN_LOOP ;
;┌─────┬─────────────────-┐;
;│VER │上位机命令处理: 要求版本 │;
;└─────┴─────────────────-┘;
VER: CJNE A,#"V",DATE ; 判断是要输出:时间,版本信息,键盘鼠标命令
ACALL UART_TXD ;
MOV A,#0DH ;
ACALL UART_TXD ;
MOV DPTR,#VER_LIST ;
MOV R7,#7 ; 计数器
VER_LOOP: CLR A ;
MOVC A,@A+DPTR ;
ACALL UART_TXD ;
INC DPTR ;
DJNZ R7,VER_LOOP ; 是否传输完毕
AJMP MAIN_LOOP ;
VER_LIST: DB "IR1.00" ; IR1.00
DB 0DH ; 回车
;┌─────┬─────────────────-┐;
;│DATE │上位机命令处理: 请求日期 │; 暂时没有用到
;└─────┴─────────────────-┘;
DATE: CJNE A,#"D",RI_RET ; 判断命令是否请求日期
ACALL UART_TXD ;
MOV A,#0DH ;
ACALL UART_TXD ;
MOV DPTR,#DATA_LIST ;
MOV R7,#11 ; 计数器
DATE_LOOP: CLR A ;
MOVC A,@A+DPTR ;
ACALL UART_TXD ;
INC DPTR ;
DJNZ R7,DATE_LOOP ; 是否传输完毕
DATA_LIST: DB "2005 10 01" ; 2005-10-1
DB 0DH, ; 回车 0AH:新行
;**************************************************** 错误命令
RI_RET: ACALL UART_TXD ; 命令返回
MOV A,#0DH ;
ACALL UART_TXD ;
MOV DPTR,#BAD_LIST ;
MOV R7,#12 ; 计数器
BAD_LOOP: CLR A ;
MOVC A,@A+DPTR ;
ACALL UART_TXD ;
INC DPTR ;
DJNZ R7,BAD_LOOP ; 是否传输完毕
AJMP MAIN_LOOP ;
BAD_LIST: DB "bad command" ;
DB 0DH ; 回车 0AH:新行
;┌─────┬─────────────────-┐;
;│IROUT_OUT │红外发射处理程序 │;
;└─────┴─────────────────-┘;
IROUT_OUT: CLR EA ; 禁止所有中断
MOV g_SOFT_DOG,#0 ; 软件看门狗延时 最大4*256=1024us
IROUT_HEAD1: JB RI,IROUT_HEAD2 ; 等待发送完毕 ,需要加限时服务 如果 1024us内没有收到 放弃本次发送
NOP ; 增加计时时间
DJNZ g_SOFT_DOG,IROUT_HEAD1 ; 防止串口出错一直在这里等待
AJMP IROUT_RET ; 时间溢出 返回
IROUT_HEAD2: CLR RI ;
MOV A,SBUF ;
MOV g_IR_HEAD1,A ; 传送数据
MOV g_SOFT_DOG,#0 ; 软件看门狗延时 最大4*256=1024us
IROUT_HEAD3: JB RI,IROUT_HEAD4 ; 等待发送完毕 ,需要加限时服务 如果 1024us内没有收到 放弃本次发送
NOP ;
DJNZ g_SOFT_DOG,IROUT_HEAD3 ; 防止串口出错一直在这里等待
AJMP IROUT_RET ; 时间溢出 返回
IROUT_HEAD4: CLR RI ;
MOV A,SBUF ;
MOV g_IR_HEAD2,A ; 传送数据
MOV g_SOFT_DOG,#0 ; 软件看门狗延时 最大4*256=1024us
IROUT_HEAD5: JB RI,IROUT_HEAD6 ; 等待发送完毕 ,需要加限时服务 如果 1024us内没有收到 放弃本次发送
NOP ;
DJNZ g_SOFT_DOG,IROUT_HEAD5 ; 防止串口出错一直在这里等待
AJMP IROUT_RET ; 时间溢出 返回
IROUT_HEAD6: CLR RI ;
MOV A,SBUF ;
MOV g_IR_HEAD3,A ; 传送数据
ACALL IROUT_DATA ;
ACALL LED_WINK ;
IROUT_RET: CLR TF1 ; 清除定时器1
CLR IE0 ; 清除红外中断
SETB EA ; 开中断
RET ;
;****************************************************
LED_WINK: MOV g_SOFT_DOG,#10 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -