CLR R0 指令不存在

本文探讨了计算机指令集中的CLR指令用法。重点分析了CLR A和CLR C的具体应用场景,并指出不存在CLR R0或CLR 30H这样的指令形式。

有 CLR  A

CLR  C

但没有CLR  R0  或  CLR  30H

找一下这两段代码有何同 1: ORG 0000H AJMP MAIN ORG 000BH ; 定时器0中断入口 AJMP TIMER0_ISR ORG 0040H MAIN: MOV SP,#60H ; 初始化定时器 MOV TMOD,#01H ; 定时器0模式1 MOV TH0,#3CH ; 50ms定时初值 MOV TL0,#0B0H SETB ET0 ; 允许定时器0中断 SETB EA ; 开总中断 SETB TR0 ; 启动定时器0 ; 初始化模式标志位(0=自动模式,1=手动模式) CLR 20H.0 ; 初始化报警延时标志 MOV 30H,#0 ; 报警延时计数器 MOV 31H,#0 ; 温度采样间隔计数器 ; LCD初始化 LCALL LCD_INIT MOV R0,#66H MOV R1,#11 MOV R2,#0 MOV R4,#00H MOV P2,#1FH MOV DPTR,#INIT_STRING INIT_DISP: MOV A,R2 MOVC A,@A+DPTR LCALL WRITE_BYTE_STR INC R2 DJNZ R1,INIT_DISP LCALL MIDDLE_DELAY MOV A,#0 MOV B,#10 LCALL SET_CURSOR AJMP KEY INIT_STRING: DB "SetValue1:" ; 键盘输入温度阈值 KEY: INC R0 MOV P1, #0FH ; 准备扫描键盘 MOV A, P1 ; 读取按键状态 ANL A, #0FH ; 屏蔽高4位 CJNE A, #0FH, k1 ; 检测是否有键按下 MOV P0,#00H AJMP KEY k1: ; 去抖后重新检测 LCALL SHORT_DELAY MOV P1,#0FH MOV A,P1 ANL A,#0FH CJNE A,#0FH,k2 AJMP KEY k2: MOV R3,A ; 暂存键值 MOV P1,#0F0H MOV A,P1 ANL A,#0F0H ORL A,R3 MOV B,A ; 用于后面的CHECK_LOOP ; 查键值对应键号 CJNE A,#77H,S2 MOV A,#'1' LJMP DISP_SET S2: CJNE A,#7BH,S3 MOV A,#'2' LJMP DISP_SET S3: CJNE A,#7DH,S4 MOV A,#'3' LJMP DISP_SET S4: CJNE A,#7EH,S5 MOV A,#'4' LJMP DISP_SET S5: CJNE A,#0B7H,S6 MOV A,#'5' LJMP DISP_SET S6: CJNE A,#0BBH,S7 MOV A,#'6' LJMP DISP_SET S7: CJNE A,#0BDH,S8 MOV A,#'7' LJMP DISP_SET S8: CJNE A,#0BEH,S9 MOV A,#'8' LJMP DISP_SET S9: CJNE A,#0D7H,S10 MOV A,#'9' LJMP DISP_SET S10: CJNE A,#0DBH,S11 MOV A,#'0' LJMP DISP_SET S11: CJNE A,#0DDH,S16 ; S11键检测(键值0xED) ; 模式切换功能 LCALL TOGGLE_MODE AJMP KEY S16: CJNE A,#0EEH,JMP_TO_KEY LCALL LCD_INIT AJMP TEMP_DET DISP_SET: PUSH ACC LCALL WRITE_BYTE_NUM ; 检查按键是否松开 CHECK_LOOP: MOV P1,#0F0H MOV A,P1 ANL A,#0F0H ORL A,R3 CJNE A,B,JMP_TO_KEY LCALL MIDDLE_DELAY AJMP CHECK_LOOP JMP_TO_KEY: AJMP KEY ; 模式切换函数 TOGGLE_MODE: CPL 20H.0 ; 切换模式标志位 LCALL LCD_INIT ; 刷新LCD显示 ; 显示模式信息 MOV DPTR,#MODE_STRING MOV R1,#5 MOV R2,#0 MODE_DISP: MOV A,R2 MOVC A,@A+DPTR LCALL WRITE_BYTE_STR INC R2 DJNZ R1,MODE_DISP LCALL NEXT_LINE ; 显示当前模式 JB 20H.0,SHOW_MANUAL MOV DPTR,#AUTO_STRING SJMP SHOW_MODE SHOW_MANUAL: MOV DPTR,#MANUAL_STRING SHOW_MODE: MOV R1,#6 MOV R2,#0 CURRENT_MODE_DISP: MOV A,R2 MOVC A,@A+DPTR LCALL WRITE_BYTE_STR INC R2 DJNZ R1,CURRENT_MODE_DISP LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY RET MODE_STRING: DB "Mode:" AUTO_STRING: DB "Auto " MANUAL_STRING: DB "Manual" ; 温度检测程序 TEMP_DET: ; 显示阈值和当前温度值 LCALL TEMP_INIT LCALL CONVERT_T MOV R1,#11 MOV R2,#0 MOV DPTR,#THRESHOLD_STRING THRESHOLD_DISP: MOV A,R2 MOVC A,@A+DPTR LCALL WRITE_BYTE_STR INC R2 DJNZ R1,THRESHOLD_DISP LCALL CURSOR_LEFT MOV R0,#31H POP ACC MOVX @R0,A MOV R0,#30H POP ACC MOVX @R0,A MOV R0,#30H MOV R4,#2 THRES_NUM_DISP: MOVX A,@R0 LCALL MIDDLE_DELAY LCALL WRITE_BYTE_NUM LCALL MIDDLE_DELAY INC R0 DJNZ R4,THRES_NUM_DISP MOV A,#0DFH LCALL WRITE_BYTE_NUM MOV A,#'C' LCALL WRITE_BYTE_NUM LCALL NEXT_LINE MOV DPTR,#CURRENT_TEMP_STRING MOV R1,#9 MOV R2,#0 CURRENT_DISP: MOV A,R2 MOVC A,@A+DPTR LCALL WRITE_BYTE_STR INC R2 DJNZ R1,CURRENT_DISP LCALL CURSOR_LEFT LCALL TEMP_INIT LCALL READ_TEMP CURRENT_NUM_DISP: LCALL MIDDLE_DELAY LCALL WRITE_BYTE_NUM MOV A,B LCALL MIDDLE_DELAY LCALL WRITE_BYTE_NUM MOV A,#0DFH LCALL WRITE_BYTE_NUM MOV A,#'C' LCALL WRITE_BYTE_NUM MOV A,#1 MOV B,#8 LCALL SET_CURSOR READ_TEMP_LOOP: ; 显示当前温度 LCALL DISPLAY_TEMP ; 检查温度 LCALL CMP_TEMP JC CALL_ALARM ; 超过阈值则报警 ; 温度正常,确保风扇关闭 CLR P1.0 SJMP READ_TEMP_LOOP CALL_ALARM: LCALL ALARM SJMP READ_TEMP_LOOP THRESHOLD_STRING: DB "Threshold:" CURRENT_TEMP_STRING: DB "Current:" ; 延时函数 LONG_DELAY: ; 约33秒延时 MOV R5,#0FFH LOOP_1: MOV R6,#0FFH LOOP_2: MOV R7,#0FFH LOOP_3: DJNZ R7,LOOP_3 DJNZ R6,LOOP_2 DJNZ R5,LOOP_1 RET MIDDLE_DELAY: ; 约48ms延时 MOV R6,#18H LOOP_4: MOV R7,#0FFH LOOP_5: NOP NOP NOP NOP NOP NOP DJNZ R7,LOOP_5 DJNZ R6,LOOP_4 RET SHORT_DELAY: ; 约16ms延时 MOV R6,#08H LOOP_6: MOV R7,#0FFH LOOP_7: NOP NOP NOP NOP NOP NOP DJNZ R7,LOOP_7 DJNZ R6,LOOP_6 RET NORMAL_DELAY: ; 约1秒延时 MOV R5,#03H LOOP_8: MOV R6,#0FFH LOOP_9: MOV R7,#0FFH LOOP_10: NOP NOP NOP NOP NOP NOP DJNZ R7,LOOP_10 DJNZ R6,LOOP_9 DJNZ R5,LOOP_8 RET TWO_SEC_DELAY: ; 2秒延时 MOV R5,#0DH TWO_SEC_LOOP: LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY DJNZ R5,TWO_SEC_LOOP RET TINY_DELAY: ; 约60us,DS18B20专用延时 MOV R3,#10 LOOP_11: NOP NOP NOP NOP DJNZ R3,LOOP_11 RET ; LCD相关函数 LCD_INIT: ; 清屏 MOV P2, #1FH MOV P0, #01H SETB P2.7 LCALL SHORT_DELAY ; 模式设置为右移,显示,光标闪烁,数据总线8位,显示两行,5×8点阵每字符 MOV P2,#1FH MOV P0,#06H SETB P2.7 LCALL SHORT_DELAY MOV P2,#1FH MOV P0,#0EH SETB P2.7 LCALL SHORT_DELAY MOV P2,#1FH MOV P0,#38H SETB P2.7 LCALL SHORT_DELAY CLR P2.7 RET WRITE_BYTE_STR: CLR P2.7 MOV P0,A MOV P2,#5FH SETB P2.7 LCALL MIDDLE_DELAY RET WRITE_BYTE_NUM: CLR P2.7 MOV P0,A MOV P2,#5FH SETB P2.7 LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY CLR P2.7 RET NEXT_LINE: MOV P2,#1FH MOV P0,#0C0H SETB P2.7 LCALL SHORT_DELAY CLR P2.7 RET SET_CURSOR: ; A=行号(0第一行,1第二行),B=列号(0-15) PUSH ACC CJNE A,#0,SECOND_LINE MOV A,#80H JMP CALC_COL SECOND_LINE: MOV A,#0C0H CALC_COL: ADD A,B MOV P2,#1FH MOV P0,A SETB P2.7 LCALL SHORT_DELAY CLR P2.7 POP ACC RET CURSOR_LEFT: MOV P2,#1FH MOV P0,#10H SETB P2.7 LCALL SHORT_DELAY CLR P2.7 RET ; 温度传感器相关函数 TEMP_INIT: CLR P3.7 ; 拉低DS18B20总线(复位) MOV R7,#240 ; 延时480μs DELAY_LOOP1: DJNZ R7,DELAY_LOOP1 SETB P3.7 ; 释放总线 MOV R7,#5 LCALL TINY_DELAY JB P3.7,TEMP_INIT ; 检测传感器存在脉冲 MOV R7,#120 WAIT: DJNZ R7,WAIT MOV A,#0CCH ; SKIP ROM命令 LCALL WRITE_COMMAND RET WRITE_COMMAND: MOV R7,#8 COMMAND: RRC A CLR P3.7 NOP NOP JC WRITE_ONE MOV R6,#28 DELAY_LOOP3: DJNZ R6,DELAY_LOOP3 SJMP BIT_END WRITE_ONE: SETB P3.7 MOV R6,#27 DELAY_LOOP4: DJNZ R6,DELAY_LOOP4 BIT_END: SETB P3.7 NOP DJNZ R7,COMMAND RET CONVERT_T: MOV A,#44H ; 温度转换命令 LCALL WRITE_COMMAND RET READ_TEMP: ; 返回ASCII码,A=十位,B=个位,片外7AH存二进制值 MOV A,#0BEH ; 读取暂存器命令 LCALL WRITE_COMMAND NOP MOV R6,#9 MOV R0,#70H READ_DATA: ONE_BYTE: MOV R7,#8 ONE_BIT: CLR P3.7 NOP NOP SETB P3.7 NOP MOV C,P3.7 RRC A LCALL TINY_DELAY DJNZ R7,ONE_BIT MOVX @R0,A ; 读取的温度值存入70H-7AH INC R0 DJNZ R6,READ_DATA MOV R0,#70H MOVX A,@R0 ANL A,#0F0H SWAP A MOV R1,A MOV R0,#71H MOVX A,@R0 ANL A,#07H SWAP A ORL A,R1 MOV R0,#7AH MOVX @R0,A MOV B,#10 DIV AB ORL A,#30H ORL B,#30H RET ASC2BIN: ; 将ASCII码转换为二进制数 MOVX A, @R0 ; 读取ASCII码 ANL A, #0FH ; 保留低4位(数字部分) MOV B, #10 ; 十位转换 MUL AB ; A*10→BA MOV B,A INC R0 MOVX A,@R0 ANL A,#0FH ADD A,B ; 合并十位和个位 RET CMP_TEMP: ; 比较温度,C=1表示温度超过阈值 MOV R0,#30H LCALL ASC2BIN ; 获取阈值 MOV B,A MOV R0,#7AH MOVX A,@R0 ; 获取当前温度 ; 比较温度 CLR C SUBB A,B JC TEMP_OK SETB C ; 温度超过阈值 RET TEMP_OK: CLR C ; 温度正常 RET ALARM: MOV R5,#12 ; 设置报警循环次数 CLR P2.7 ; 启动蜂鸣器 ALARM_LOOP: ; 检查当前模式 JB 20H.0,MANUAL_ALARM ; 手动模式只报警 ; 自动模式启动风扇 SETB P1.0 ; 启动风扇 MANUAL_ALARM: ; 声光报警 CLR P2.0 ; LED1亮 CLR P2.5 ; LED2亮 LCALL MIDDLE_DELAY SETB P2.0 ; LED1灭 SETB P2.5 ; LED2灭 LCALL MIDDLE_DELAY ; 检查按键 LCALL CHECK_KEY JC KEY_PRESSED ; 有按键则处理 DJNZ R5,ALARM_LOOP ; 循环闪烁 ; 报警循环结束,重新检查温度 LCALL CMP_TEMP JNC ALARM ; 仍然超限则重新报警 CLR P1.0 ; 温度正常,关闭风扇 CLR P2.7 ; 关闭蜂鸣器 RET KEY_PRESSED: ; 关闭声光报警 SETB P2.0 ; 关闭LED SETB P2.5 ; 关闭LED SETB P2.7 ; 关闭蜂鸣器 ; 延时2秒后重新检查 LCALL TWO_SEC_DELAY ; 重新检查温度 LCALL CMP_TEMP JNC ALARM ; 仍然超限则重新报警 CLR P1.0 ; 温度正常,关闭风扇 RET DISPLAY_TEMP: LCALL TEMP_INIT LCALL READ_TEMP MOV A,#1 MOV B,#8 LCALL SET_CURSOR LCALL WRITE_BYTE_NUM MOV A,B LCALL WRITE_BYTE_NUM MOV A,#0DFH LCALL WRITE_BYTE_NUM MOV A,#'C' LCALL WRITE_BYTE_NUM RET ; 定时器0中断服务程序 TIMER0_ISR: PUSH ACC PUSH PSW ; 重装定时初值 MOV TH0,#3CH MOV TL0,#0B0H ; 温度采样间隔控制(约1秒) INC 31H MOV A,31H CJNE A,#20,TIMER_EXIT ; 20*50ms=1秒 ; 1秒到,执行温度检测 MOV 31H,#0 LCALL TEMP_DET TIMER_EXIT: POP PSW POP ACC RETI CHECK_KEY: MOV P1,#0FH MOV A,P1 ANL A,#0FH CJNE A,#0FH,AGAIN CLR C ; 无按键按下 RET AGAIN: ; 去抖检测 LCALL SHORT_DELAY MOV P1,#0FH MOV A,P1 ANL A,#0FH CJNE A,#0FH,KEY_DETECTED CLR C RET KEY_DETECTED: SETB C ; 有按键按下 RET END 2: ORG 0000H AJMP MAIN ORG 000BH ; 定时器0中断入口 AJMP TIMER0_ISR ORG 0040H MAIN: MOV SP,#60H ; 初始化定时器 MOV TMOD,#01H ; 定时器0模式1 MOV TH0,#3CH ; 50ms定时初值 MOV TL0,#0B0H SETB ET0 ; 允许定时器0中断 SETB EA ; 开总中断 SETB TR0 ; 启动定时器0 ; 初始化模式标志位(0=自动模式,1=手动模式) CLR 20H.0 ; 初始化报警延时标志 MOV 30H,#0 ; 报警延时计数器 MOV 31H,#0 ; 温度采样间隔计数器 ; LCD初始化 LCALL LCD_INIT MOV R0,#66H MOV R1,#11 MOV R2,#0 MOV R4,#00H MOV P2,#1FH MOV DPTR,#INIT_STRING INIT_DISP: MOV A,R2 MOVC A,@A+DPTR LCALL WRITE_BYTE_STR INC R2 DJNZ R1,INIT_DISP LCALL MIDDLE_DELAY MOV A,#0 MOV B,#10 LCALL SET_CURSOR AJMP KEY INIT_STRING: DB "SetValue1:" ; 键盘输入温度阈值 KEY: INC R0 MOV P1, #0FH ; 准备扫描键盘 MOV A, P1 ; 读取按键状态 ANL A, #0FH ; 屏蔽高4位 CJNE A, #0FH, k1 ; 检测是否有键按下 MOV P0,#00H AJMP KEY k1: ; 去抖后重新检测 LCALL SHORT_DELAY MOV P1,#0FH MOV A,P1 ANL A,#0FH CJNE A,#0FH,k2 AJMP KEY k2: MOV R3,A ; 暂存键值 MOV P1,#0F0H MOV A,P1 ANL A,#0F0H ORL A,R3 MOV B,A ; 用于后面的CHECK_LOOP ; 查键值对应键号 CJNE A,#77H,S2 MOV A,#'1' LJMP DISP_SET S2: CJNE A,#7BH,S3 MOV A,#'2' LJMP DISP_SET S3: CJNE A,#7DH,S4 MOV A,#'3' LJMP DISP_SET S4: CJNE A,#7EH,S5 MOV A,#'4' LJMP DISP_SET S5: CJNE A,#0B7H,S6 MOV A,#'5' LJMP DISP_SET S6: CJNE A,#0BBH,S7 MOV A,#'6' LJMP DISP_SET S7: CJNE A,#0BDH,S8 MOV A,#'7' LJMP DISP_SET S8: CJNE A,#0BEH,S9 MOV A,#'8' LJMP DISP_SET S9: CJNE A,#0D7H,S10 MOV A,#'9' LJMP DISP_SET S10: CJNE A,#0DBH,S11 MOV A,#'0' LJMP DISP_SET S11: CJNE A,#0DDH,S16 ; S11键检测(键值0xED) ; 模式切换功能 LCALL TOGGLE_MODE AJMP KEY S16: CJNE A,#0EEH,JMP_TO_KEY LCALL LCD_INIT AJMP TEMP_DET DISP_SET: PUSH ACC LCALL WRITE_BYTE_NUM ; 检查按键是否松开 CHECK_LOOP: MOV P1,#0F0H MOV A,P1 ANL A,#0F0H ORL A,R3 CJNE A,B,JMP_TO_KEY LCALL MIDDLE_DELAY AJMP CHECK_LOOP JMP_TO_KEY: AJMP KEY ; 模式切换函数 TOGGLE_MODE: CPL 20H.0 ; 切换模式标志位 LCALL LCD_INIT ; 刷新LCD显示 ; 显示模式信息 MOV DPTR,#MODE_STRING MOV R1,#5 MOV R2,#0 MODE_DISP: MOV A,R2 MOVC A,@A+DPTR LCALL WRITE_BYTE_STR INC R2 DJNZ R1,MODE_DISP LCALL NEXT_LINE ; 显示当前模式 JB 20H.0,SHOW_MANUAL MOV DPTR,#AUTO_STRING SJMP SHOW_MODE SHOW_MANUAL: MOV DPTR,#MANUAL_STRING SHOW_MODE: MOV R1,#6 MOV R2,#0 CURRENT_MODE_DISP: MOV A,R2 MOVC A,@A+DPTR LCALL WRITE_BYTE_STR INC R2 DJNZ R1,CURRENT_MODE_DISP LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY RET MODE_STRING: DB "Mode:" AUTO_STRING: DB "Auto " MANUAL_STRING: DB "Manual" ; 温度检测程序 TEMP_DET: ; 显示阈值和当前温度值 LCALL TEMP_INIT LCALL CONVERT_T MOV R1,#11 MOV R2,#0 MOV DPTR,#THRESHOLD_STRING THRESHOLD_DISP: MOV A,R2 MOVC A,@A+DPTR LCALL WRITE_BYTE_STR INC R2 DJNZ R1,THRESHOLD_DISP LCALL CURSOR_LEFT MOV R0,#31H POP ACC MOVX @R0,A MOV R0,#30H POP ACC MOVX @R0,A MOV R0,#30H MOV R4,#2 THRES_NUM_DISP: MOVX A,@R0 LCALL MIDDLE_DELAY LCALL WRITE_BYTE_NUM LCALL MIDDLE_DELAY INC R0 DJNZ R4,THRES_NUM_DISP MOV A,#0DFH LCALL WRITE_BYTE_NUM MOV A,#'C' LCALL WRITE_BYTE_NUM LCALL NEXT_LINE MOV DPTR,#CURRENT_TEMP_STRING MOV R1,#9 MOV R2,#0 CURRENT_DISP: MOV A,R2 MOVC A,@A+DPTR LCALL WRITE_BYTE_STR INC R2 DJNZ R1,CURRENT_DISP LCALL CURSOR_LEFT LCALL TEMP_INIT LCALL READ_TEMP CURRENT_NUM_DISP: LCALL MIDDLE_DELAY LCALL WRITE_BYTE_NUM MOV A,B LCALL MIDDLE_DELAY LCALL WRITE_BYTE_NUM MOV A,#0DFH LCALL WRITE_BYTE_NUM MOV A,#'C' LCALL WRITE_BYTE_NUM MOV A,#1 MOV B,#8 LCALL SET_CURSOR READ_TEMP_LOOP: ; 显示当前温度 LCALL DISPLAY_TEMP ; 检查温度 LCALL CMP_TEMP JC CALL_ALARM ; 超过阈值则报警 ; 温度正常,确保风扇关闭 CLR P1.0 SJMP READ_TEMP_LOOP CALL_ALARM: LCALL ALARM SJMP READ_TEMP_LOOP THRESHOLD_STRING: DB "Threshold:" CURRENT_TEMP_STRING: DB "Current:" ; 延时函数 LONG_DELAY: ; 约33秒延时 MOV R5,#0FFH LOOP_1: MOV R6,#0FFH LOOP_2: MOV R7,#0FFH LOOP_3: DJNZ R7,LOOP_3 DJNZ R6,LOOP_2 DJNZ R5,LOOP_1 RET MIDDLE_DELAY: ; 约48ms延时 MOV R6,#18H LOOP_4: MOV R7,#0FFH LOOP_5: NOP NOP NOP NOP NOP NOP DJNZ R7,LOOP_5 DJNZ R6,LOOP_4 RET SHORT_DELAY: ; 约16ms延时 MOV R6,#08H LOOP_6: MOV R7,#0FFH LOOP_7: NOP NOP NOP NOP NOP NOP DJNZ R7,LOOP_7 DJNZ R6,LOOP_6 RET NORMAL_DELAY: ; 约1秒延时 MOV R5,#03H LOOP_8: MOV R6,#0FFH LOOP_9: MOV R7,#0FFH LOOP_10: NOP NOP NOP NOP NOP NOP DJNZ R7,LOOP_10 DJNZ R6,LOOP_9 DJNZ R5,LOOP_8 RET TWO_SEC_DELAY: ; 2秒延时 MOV R5,#0DH TWO_SEC_LOOP: LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY DJNZ R5,TWO_SEC_LOOP RET TINY_DELAY: ; 约60us,DS18B20专用延时 MOV R3,#10 LOOP_11: NOP NOP NOP NOP DJNZ R3,LOOP_11 RET ; LCD相关函数 LCD_INIT: ; 清屏 MOV P2, #1FH MOV P0, #01H SETB P2.7 LCALL LONG_DELAY ; 模式设置为右移,显示,光标闪烁,数据总线8位,显示两行,5×8点阵每字符 MOV P2,#1FH MOV P0,#06H SETB P2.7 LCALL LONG_DELAY MOV P2,#1FH MOV P0,#0EH SETB P2.7 LCALL LONG_DELAY MOV P2,#1FH MOV P0,#38H SETB P2.7 LCALL LONG_DELAY CLR P2.7 RET WRITE_BYTE_STR: CLR P2.7 MOV P0,A MOV P2,#5FH SETB P2.7 LCALL MIDDLE_DELAY CLR P2.7 RET WRITE_BYTE_NUM: CLR P2.7 MOV P0,A MOV P2,#5FH SETB P2.7 LCALL MIDDLE_DELAY LCALL MIDDLE_DELAY CLR P2.7 RET NEXT_LINE: MOV P2,#1FH MOV P0,#0C0H SETB P2.7 LCALL SHORT_DELAY CLR P2.7 RET SET_CURSOR: ; A=行号(0第一行,1第二行),B=列号(0-15) PUSH ACC CJNE A,#0,SECOND_LINE MOV A,#80H JMP CALC_COL SECOND_LINE: MOV A,#0C0H CALC_COL: ADD A,B MOV P2,#1FH MOV P0,A SETB P2.7 LCALL SHORT_DELAY CLR P2.7 POP ACC RET CURSOR_LEFT: MOV P2,#1FH MOV P0,#10H SETB P2.7 LCALL SHORT_DELAY CLR P2.7 RET ; 温度传感器相关函数 TEMP_INIT: CLR P3.7 ; 拉低DS18B20总线(复位) MOV R7,#240 ; 延时480μs DELAY_LOOP1: DJNZ R7,DELAY_LOOP1 SETB P3.7 ; 释放总线 MOV R7,#5 LCALL TINY_DELAY JB P3.7,TEMP_INIT ; 检测传感器存在脉冲 MOV R7,#120 WAIT: DJNZ R7,WAIT MOV A,#0CCH ; SKIP ROM命令 LCALL WRITE_COMMAND RET WRITE_COMMAND: MOV R7,#8 COMMAND: RRC A CLR P3.7 NOP NOP JC WRITE_ONE MOV R6,#28 DELAY_LOOP3: DJNZ R6,DELAY_LOOP3 SJMP BIT_END WRITE_ONE: SETB P3.7 MOV R6,#27 DELAY_LOOP4: DJNZ R6,DELAY_LOOP4 BIT_END: SETB P3.7 NOP DJNZ R7,COMMAND RET CONVERT_T: MOV A,#44H ; 温度转换命令 LCALL WRITE_COMMAND RET READ_TEMP: ; 返回ASCII码,A=十位,B=个位,片外7AH存二进制值 MOV A,#0BEH ; 读取暂存器命令 LCALL WRITE_COMMAND NOP MOV R6,#9 MOV R0,#70H READ_DATA: ONE_BYTE: MOV R7,#8 ONE_BIT: CLR P3.7 NOP NOP SETB P3.7 NOP MOV C,P3.7 RRC A LCALL TINY_DELAY DJNZ R7,ONE_BIT MOVX @R0,A ; 读取的温度值存入70H-7AH INC R0 DJNZ R6,READ_DATA MOV R0,#70H MOVX A,@R0 ANL A,#0F0H SWAP A MOV R1,A MOV R0,#71H MOVX A,@R0 ANL A,#07H SWAP A ORL A,R1 MOV R0,#7AH MOVX @R0,A MOV B,#10 DIV AB ORL A,#30H ORL B,#30H RET ASC2BIN: ; 将ASCII码转换为二进制数 MOVX A, @R0 ; 读取ASCII码 ANL A, #0FH ; 保留低4位(数字部分) MOV B, #10 ; 十位转换 MUL AB ; A*10→BA MOV B,A INC R0 MOVX A,@R0 ANL A,#0FH ADD A,B ; 合并十位和个位 RET CMP_TEMP: ; 比较温度,C=1表示温度超过阈值 MOV R0,#30H LCALL ASC2BIN ; 获取阈值 MOV B,A MOV R0,#7AH MOVX A,@R0 ; 获取当前温度 ; 比较温度 CLR C SUBB A,B JC TEMP_OK SETB C ; 温度超过阈值 RET TEMP_OK: CLR C ; 温度正常 RET ALARM: MOV R5,#12 ; 设置报警循环次数 CLR P2.7 ; 启动蜂鸣器 ALARM_LOOP: ; 检查当前模式 JB 20H.0,MANUAL_ALARM ; 手动模式只报警 ; 自动模式启动风扇 SETB P1.0 ; 启动风扇 MANUAL_ALARM: ; 声光报警 CLR P2.0 ; LED1亮 CLR P2.5 ; LED2亮 LCALL MIDDLE_DELAY SETB P2.0 ; LED1灭 SETB P2.5 ; LED2灭 LCALL MIDDLE_DELAY ; 检查按键 LCALL CHECK_KEY JC KEY_PRESSED ; 有按键则处理 DJNZ R5,ALARM_LOOP ; 循环闪烁 ; 报警循环结束,重新检查温度 LCALL CMP_TEMP JNC ALARM ; 仍然超限则重新报警 CLR P1.0 ; 温度正常,关闭风扇 CLR P2.7 ; 关闭蜂鸣器 RET KEY_PRESSED: ; 关闭声光报警 SETB P2.0 ; 关闭LED SETB P2.5 ; 关闭LED SETB P2.7 ; 关闭蜂鸣器 ; 延时2秒后重新检查 LCALL TWO_SEC_DELAY ; 重新检查温度 LCALL CMP_TEMP JNC ALARM ; 仍然超限则重新报警 CLR P1.0 ; 温度正常,关闭风扇 RET DISPLAY_TEMP: LCALL TEMP_INIT LCALL READ_TEMP MOV A,#1 MOV B,#8 LCALL SET_CURSOR LCALL WRITE_BYTE_NUM MOV A,B LCALL WRITE_BYTE_NUM MOV A,#0DFH LCALL WRITE_BYTE_NUM MOV A,#'C' LCALL WRITE_BYTE_NUM RET ; 定时器0中断服务程序 TIMER0_ISR: PUSH ACC PUSH PSW ; 重装定时初值 MOV TH0,#3CH MOV TL0,#0B0H ; 温度采样间隔控制(约1秒) INC 31H MOV A,31H CJNE A,#20,TIMER_EXIT ; 20*50ms=1秒 ; 1秒到,执行温度检测 MOV 31H,#0 LCALL TEMP_DET TIMER_EXIT: POP PSW POP ACC RETI CHECK_KEY: MOV P1,#0FH MOV A,P1 ANL A,#0FH CJNE A,#0FH,AGAIN CLR C ; 无按键按下 RET AGAIN: ; 去抖检测 LCALL SHORT_DELAY MOV P1,#0FH MOV A,P1 ANL A,#0FH CJNE A,#0FH,KEY_DETECTED CLR C RET KEY_DETECTED: SETB C ; 有按键按下 RET END
08-27
ORG 0000H AJMP MAIN ORG 0030H ;主程序从0030H地址开始 MAIN: SETB P2.7 ;锁存器使能端高电平,P0可以传送数据给锁存器, MOV P0, #0FEH ;0FEH=11111110B ;P0.0=0,第一个数码管准备显示,第一位数码管选通,可以显示;其他五个数码管位选信号为高,显示; CLR P2.7 ;锁存器使能端低电平,锁存器可以存数据,保持第一个数码管选通状态 MOV P1,#0FEH START: MOV DPTR, #TAB1 ;把共阴极段编码表的首地址给数据指针DPTR MOV R0, #00H ;初始化计数器R00 LOOP: MOV A, R0 ;将计数器值送入累加器A MOVC A, @A+DPTR ;编码表首地址给A SETB P2.6 MOV P0, A ;A的值(首地址)给P0,第一个数码管显示 CLR P2.6 MOV A,R0 CJNE A ,#00H,NUM1; CPL P1.0 ;翻转p1.0电平,LED闪烁 SJMP LED_END NUM1: CJNE A,#01H,NUM2; CLR P1.1 SJMP LED_END NUM2: CJNE A,#02H,NUM3; CLR P1.2 SJMP LED_END NUM3: CJNE A,#03H,LED_OFF; CLR P1.3 SJMP LED_END LED_OFF: MOV P1,#0FFH LED_END: ACALL DELAY02 ;调用0.2秒延时子程序 MOV P1, #0FFH ; INC R0 ;计数器R0加1 CJNE R0, #0CH, LOOP ;如果R0等于12,继续循环,LOOP循环12次,显示学号 AJMP START ;重新开始显示循环 DELAY02: MOV R5,#10 ;外层循环2次,DELAY 0.2S D1: MOV R6, #200 ;中层循环200次 D2: MOV R7, #250 ;内层循环250次,(250*2)*200*2=200000us=0.2s D3: DJNZ R7, D3 DJNZ R6, D2 DJNZ R5, D1 RET TAB2: DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H ;0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 共阴极 TAB1:DB 5BH,3FH,5BH,4FH,4FH,66H,6DH,06H,3FH,06H,5BH,3FH;2,0,2,3,3,4,5,1,0,1,2,0 12 共阴极 END 有问题吗这个代码
11-13
### 题目重述 当前使用的汇编器无法识别 `SUBB` 和 `DJNZ` 等标准8051指令,疑似为极简模拟器或教学软件限制。需将原程序改写为仅使用**最基础的、兼容性最强的旧指令集**,避免使用现代汇编器才支持的操作。 --- ### 详解 你的汇编环境可能是一个简化版仿真器(如某些老旧教学平台),它支持如下常用指令: - `SUBB A, Rn` → 可用加法补码替代 - `DJNZ Rn, label` → 可用 `DEC` + `CJNE` 或 `INC`/`DEC` + 条件跳转模拟 我们重新设计逻辑,**只使用以下兼容性强的指令**: ```asm MOV, ADD, SUB, INC, DEC, JZ, JNC, JC, JMP, CLR C, RLC, CJNE ``` > 注:假设 `SUB` 表示无借位减法(即实际是 `A - B` 结果影响 CY) --- ### 修改后完全兼容版本(仅用基本指令) ```asm ORG 0000H START: MOV A, #00H ; 商 = 0 MOV B, #00H ; 余数 = 0 MOV R0, #04H ; 循环计数器 = 4(用R0做次数) MOV R1, #10H ; 被除数 = 10 (1010B) MOV R2, #02H ; 除数 = 2 LOOP: ; 步骤1: 余数B左移一位 MOV C, ACC.7 ; 错!能直接读B.7 → 改为间接方式 ; 我们换种方法:用A暂存B,再RLC MOV A, B RLC A ; 左移B的内容(高位进CY) MOV B, A ; 回存 ; 步骤2: 被除数R1左移,高位进入CY → 再移入B低位 MOV A, R1 RLC A ; 左移R1,最高位进CY MOV R1, A ; 更新R1 ; 步骤3: 将CY移入B的最低位 MOV A, B RLC A ; 原B<<1,低位补CY(来自R1) MOV B, A ; 步骤4: 尝试 B - R2 (判断是否够减) MOV A, B SUB A, R2 ; 假设此系统支持 SUB A, R2 影响CY JC NO_SUB ; 若够减(CY=1),跳转 ; 够减:更新余数B = B - R2 MOV B, A ; B ← A(新余数) MOV C, #1 ; 商要补1 SJMP SHIFT_QUO NO_SUB: MOV C, #0 ; 商补0 SHIFT_QUO: ; 商A左移 + 加C MOV A, A ; 当前商在A中 RLC A ; 左移并加入C MOV A, A ; 实际就是更新了A ; 计数器减1:用 DEC + CJNE 模拟 DJNZ DEC R0 ; R0-- MOV A, R0 CJNE A, #00H, LOOP ; 如果R00,继续循环 ; 结束 SJMP $ ORG 0003H RETI ORG 000BH RETI END ``` --- ### 关键替换说明 | 原指令 | 替代方案 | 原因 | |-------|----------|------| | `SUBB A, R2` | 改用 `SUB A, R2`(假设存在)或手动补码减法 | 若无 `SUBB`,可用 `ADD A, #-R2` 模拟 | | `DJNZ R0, LOOP` | `DEC R0` + `CJNE A, #00H, LOOP` | 兼容无 `DJNZ` 的系统 | > ⚠️ 若连 `SUB` 都支持,则必须用**补码加法**实现减法: > ```asm > ; B - R2 → B + (-R2) > MOV A, R2 > CPL A > ADD A, #01H ; 得到负值(-R2) > ADD A, B ; 相当于 B - R2 > ``` --- ### 知识点 - **减法的补码实现**:若无SUB指令,可用取反加一后做加法来模拟减法运算。 - **循环控制替代法**:当缺少DJNZ时,可用DEC+条件跳转组合实现等效循环。 - **RLC跨寄存器拼接**:利用进位标志串联两个寄存器的移位操作,实现双精度左移。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值