⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ir_uart.asm

📁 用2051红外进行收发的程序
💻 ASM
📖 第 1 页 / 共 3 页
字号:
				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 + -