这是一个“家庭煤气泄漏报警设计”的汇编程序,想转换成C语言程序。程序如下:
ORG 00H JMP START ;主程序入口地址 ORG 03H JMP INTO ;外中断INTO入口 ORG 0BH JMP ITOP ; 定时器0中断入口 ORG 0100H START: MOV IE,#10000001B ;INT0中断使能 MOV IP,#00000001B ;INT0中断优先 MOV TCON,#00000000B ;设置INT0为电平触发 MOV SCON,#00000000B ;串行口发送,接收标志位请0 MOV SP,#60H ;设堆栈指针 MOV TMOD,#01H ;设置T0为方式1 CALL PT0M0 HERE: AJMP HERE ;自身跳转 PT0M0: MOV TL0,#0CH ;T0中断服务程序,T0重新置初值 MOV TH0,#0FEH SETB TR0 ;启动T0 SETB ET0 ;允许T0中断 SETB EA ;CPU开中断 RET ITOP: MOV TL0,#0CH ;T0中断服务程序,T0置初值 MOV TH0,0FEH CPL P1.0 ;P1.0状态取反 RETI ACALL LED ;调用LED自检子程序 MOV 33H,#00H ;设置中断完成标志为0 MOV DPTR,#0FEFFH ;ADC0809的端口地址 MOVX @DPTR,A ;使BUS为高阻抗,令ADC0809开始转换 WAIT:MOV A,33H ;等待A/D转换完成信号 JNZ INTOK JMP WAIT ;未完成则跳回等待 INTOK: MOV A,32H ;将最新的浓度值存入累加器中,(若A/D未工作,则A=0) JNZ L1 MOV A,30H JMP L2 L1: MOV 30H,31H MOV A,31H ;将新浓度载入累加器 L2: CALL BCD ;调用BCD码调整程序 CALL DISP ;显示当前浓度 CALL ADZERO ;调用零点调整子程序 CALL ALARM ;调用判断报警程序 CALL BCD CALL DISP ;调用显示子程序 CLR A ;清除累加器值 JMP START ;返回 ; 在主程序通过对33H中数值的判断断定A/D是否转换完成 ; 当33H中为1时,转换完成,程序调用调零、报警、显示模块对输入数据进行处理。 ;* * * * * * * * * * * * * * * * * ; LED自检子程序 ;* * * * * * * * * * * * * * * * * LED: CLR P1.4 ;绿灯 CLR P1.5 ;黄灯 CLR P1.6 ;红灯 CALL DELAY2s DELAY2s: MOV R5,#100 DLY1: MOV R6,#100 DLY2: MOV R7,#100 DJNZ R7,$ DJNZ R6,DLY2 DJNZ R5,DLY1 RET SETB P1.4 SETB P1.5 SETB P2.6 RET ;* * * * * * * * * * * * * * * * * ; 调零子程序 ; (初始报警值为50) ;* * * * * * * * * * * * * * * * * ADZERO : CALL DELAY20ms JB P2.2,JMP1 ;判断调零按纽是否按下,没有则跳JMP1 LOOP1: CALL DELAY20ms JNB P2.2,$ ;消除抖动延时 MOV A,40H ;将调零预设值40H送入 CLR C ;清除进位标志 SUBB A,#01H ;调零值减1 JNC LOOP2 ;未借位则跳LOOP2 MOV A,#05H ;有借位则重设调零值为5 LOOP2: MOV 40H,A ;将调零值送回40H保存 MOV A,R3 ;将当前浓度值送入A JZ XEND DEC A ;当前浓度值减1(响应调整变化) XEND1: MOV 30H,A ;送回30H保存 MOV 31H,A ;送回31H保存 CALL BCD CALL DISP JMP LOOP1 XEND: MOV A,#63H JMP XEND1 JMP1: RET ;* * * * * * * * * * * * * * * * * ; 3位串行静态显示子程序 ;* * * * * * * * * * * * * * * * * BCD: MOV 55H,#00H ;存放BCD转换中的百位数 MOV 56H,#00H ;存放BCD转换中的十位数 CLR C ;清楚进位标志为下面的SUBB准备 MOV R2,#00H ;清楚R2 CHAN: SUBB A,#64H ;减100 JC CHAN1 ;不能减,转 INC R1 ;百位值 JMP CHAN ;循环判断百位 CHAN1: ADD A,#64H ;还原百位数 CLR C ;清楚进位标志为下面的SUBB准备 CHAN2: SUBB A,#0AH ;减10 JC CHAN3 ;不够减,跳 INC R2 ;够减十位加1 JMP CHAN2 ;重复减10 CHAN3: ADD A,#0AH ;还原十位数 MOV 61H,R2 ;把十位数放61H MOV 60H,A ;把个位数放60H MOV 62H,R1 ;把百位数放62H RET DISP: MOV R7,#03H MOV R0,#60H LED1: MOV A,@R0 MOV DPTR,#TABLE LED2: MOVC A,@A+DPTR MOV SBUF,A JNB TI,$ CLR TI INC R0 DJNZ R7,LED1 RET DELAY20ms: MOV R5,#40 ;设定20毫秒 D1: MOV R6,#248 DJNZ R6,$ DJNZ R5,D1 RET ;* * * * * * * * * * * * * * * * * ; 报警子程序 ;* * * * * * * * * * * * * * * * * ALARM: MOV A,30H ;将当前浓度值送如累加器 CLR C ;清除进位标志 SUBB A,50H ;与预警值进行判断 JNC GOOD1 ;若无借位,则当前浓度值高于或者等于预警值,跳GOOD1报警 SETB P1.6 ;关闭声光报警 SETB P1.7 CLR P2.3 ;关闭排气阀门 SETB P1.5 ;关闭黄色LED CLR P1.4 ;打开绿色LED(显示正常) RET GOOD1: CLR P1.6 ;打开声光报警(危险报警) CLR P1.7 CLR P2.3 ;打开排气阀门 SETB P1.5 ;关闭黄色LED SETB P1.4 ;关闭绿色LED(显示不正常? RET ;* * * * * * * * * * * * * * * * * ; 中断取值子程序 ;* * * * * * * * * * * * * * * * * INTO: PUSH ACC ;将累加器值压入堆栈保存 PUSH PSW ;将PSW值压入堆栈保存 MOVX A,@DPTR ;将A/D转换好的值送入累加器 MOV 32H,A ;将A/D读得的值存入32H保存 CLR C SUBB A,51H ;判断获得的电压是否小于1V(50) JNC OK1 MOV 32H,#00H ;当前A/D转换的电压小于1V,则A/D转换得的示数为00 JMP EMP1 OK1: MOV A,32H CALL ADJUST ;调用ADJUST将其调整为浓度对应的16进制 CALL ADDD ;调用ADDD将其与调零预设值相加,得到调整后的16进制 MOV 31H,A ;将调整后的值送入31H保存 EMP1: MOV IE,#10000000B ;关闭INT0中断使能,关闭中断 POP PSW ;至堆栈取回PSW值 POP ACC ;至堆栈取回ACC值 MOV 33H,#01H ;中断完成,设置完成标记33H为1 RETI ;* * * * * * * * * * * * * * * * * ; 调整相加子程序 ;* * * * * * * * * * * * * * * * * ADJUST: CLR C SUBB A,#32H ;将A/D转换的值减50再除10乘5可得当前浓度的16进制值 MOV B,#0AH DIV AB MOV B,#05H MUL AB RET ADDD: ADD A,40H TABLE: DB 0C0H,0F9H,0A4H,0B0H,99H DB 92H, 82H, 0F8H,80H, 90H END
|