当前位置:文档之家› 51单片机的多路温度采集系统程序

51单片机的多路温度采集系统程序

51单片机的多路温度采集系统程序ORG 0000HAJMP MAIN;BUF EQU 40H ;显示缓冲区MOTATA EQU 50H ;AD0809数据存放于此WH EQU 48H ;温度上限数据存放区WL EQU 58H ;温度下限数据存放区BUFF1S EQU 38H;BUFF1MS EQU 39H;BUFF5S EQU 3AH;INNAL EQU 3CH;ALARMBUF EQU 33HBUFFH EQU 31H ;八路LED报警信号红灯BUFFL EQU 32H ;八路LED报警信号绿灯BACK EQU 34H ;利用与BUF地址的重复修改路数CHANNEL EQU 35HTEMPBUF EQU 36HREAD_AD BIT 30H ;是否要读写AD0809的标志位DISPIN BIT 31H;SETWARN BIT 32HSOLIDISP BIT 33HENTER BIT P1.2SETH BIT 35HSETL BIT 36HSETIN BIT P1.3ABYTEIN BIT p1.1ORG 0003HAJMP INT_0;ORG 000BHLJMP INT_T0ORG 0100HMAIN: MOV SP, #70H ;设置堆栈位置SETB READ_AD ;初始化标志位SETB EA ;开总中断CLR SETWARN ;清除温度设置标志位SETB SETIN ;当其为0时表示要进行通道数采集LCALL INITWARN ;初始化温度上下限LCALL INIT_2 ;初始化2#工作寄存器区;主循环,启动ADC0809,从第一个通道开始读取LOOP: JNB READ_AD,DIS ;若不读AD0809,则调显示,次标志位也表示1s延时结束;延时已完毕,则计算要显示的温度路数及温度值送缓冲区LCALL WARN ;报警CLR READ_AD ;清楚标志位LCALL READ ;读取一次AD0809LCALL DLY1MS ;此处加1ms的延时,否则数码管会因中断的存在而产生闪动 LCALL ADJUST ;调整显示;在此完成键盘检测及显示任务DIS: LCALL DISPLAY;LCALL KEYCHK ;调键盘检测子程序CJNE A,#0FFH, AKEY ;若有键按下,则跳转LJMP LOOP ;若没有则循环AKEY: LCALL KEYFUNC;CJNE A,#0FFH,CALLRPD ;验证按下的键是否为数字键,若是则处理输入LJMP LOOP ;不为数字键则返回循环CALLRPD: LCALL KEYRPD;SJMP LOOP;;*********初始化2#工作寄存器区************INIT_2: PUSH PSW ;初始化2号工作寄存器区SETB RS1;CLR RS0 ;选择2号工作寄存器区MOV R2, #00H ;存放要显示的路数CLR DISPIN ;初始化路显示标志位;MOV R0, #MOTATA ;R0充当指向MOTATA的指针POP PSW;RET;;*******调整指针*********PADJUST:ONADJUST: DJNZ R2,INADJUST;RET;返回INADJUST: INC R0;SJMP ONADJUST;;*************计算并调整显示缓存区的数据*******ADJUST: PUSH PSW ;保护SETB RS1;CLR RS0 ;选择2号工作寄存器区CJNE R2,#08H,NE08;GE08: MOV R2,#00H;MOV R0,#MOTATA;SJMP LESS08;NE08: JNC GE08;LESS08: JB SETWARN, DISPWARN ;若在设定温度,则也不调整显示JB SOLIDISP, ADJEND ;若为固定显示,则跳过调整JB DISPIN,DLY_5S ;若有键盘值输入,则延时5秒来暂时固定显示INC R0 ;调整R0,使其指向下一个要显示的温度值地址 INC R2 ;调整R2mov channel,r2;SJMP ADJEND;DLY_5S: DJNZ BUFF5S,ADJEND;CLR DISPIN;LJMP ADJENDDISPWARN: JB SETH,DISHIGH ;若在调整上限值则跳转到上限温度显示JB SETL,DISLOW ;若在调整下限值则跳转到下限温度显示SJMP ADJEND ;若不在调整则显示输入路数的当前检测温度值DISLOW: MOV R0,#WL ;将指针调整到温度上限存放区SJMP ADAPT ;跳转到指针调整处DISHIGH:MOV R0,#WH ;将指针调整到温度下限存放区ADAPT: MOV R2,CHANNEL ;调整R2的值为通道数LCALL PADJUST ;指针指向R2 ADJEND: LCALL LOADTEMP ;将当前指针指向数据放到缓冲区POP PSW;RET;;**************** 将当前指针指向数据放到缓冲区******** LOADTEMP: LCALL COMPUTE ;调用COMPUTE得到要显示的当前温度值MOV R1,#BUF;MOV A,channel;MOV @R1,A ;将路数送入显示缓冲区INC R1 ;调整到要显示温度值的缓冲区JB SETH,DISPH ;若设定温度上限,则显示HJB SETL,DISPL ;若设定温度下限,则显示LMov a,#10h ;消隐SJMP DISP2DISPH: MOV A,#11HSJMP DISP2DISPL: MOV A,#12HDISP2: mov @r1,a;INC R1;MOV A,R5;ANL A,#0FH;MOV @R1,A ; 最低位 INC R1;MOV A,R5;ANL A,#0F0H;SWAP A;MOV @R1,A ;次低位 ,应当在此处添加小数点INC R1;MOV A,R4;ANL A,#0FH;MOV @R1,A ;次高位 INC R1;MOV A,R4;ANL A,#0F0H;SWAP A;MOV @R1,A ;最高位RET;;*************读取一次0809的内容***********READ: MOV R6,#08H ;用中断的方式读取一次AD0809MOV R0,#MOTATA ;0号工作寄存器区MOV DPTR,#0FFFEH ;A0作为地址MOV A,#00H ;表示先检测第一个通道MOV INNAL,A ;将检测的路数保存MOVX @DPTR,A ;开启ADC0809 SETB EX0 ;开外部中断0RET ;若已读取完毕,则返回;**********************显示子程序************;要显示的数据入口为BUF(6位);1号工作寄存器区DISPLAY: PUSH PSW ;压栈保护SETB RS0;CLR RS1 ;切换工作寄存器区到 1MOV R0,#BUFMOV R7,#06HMOV R1,#01HNEXTDIS: MOV A,@R0MOV DPTR,#TABLEMOVC A,@A+DPTR ;取段码CJNE R7,#03H,NODIP ;显示小数点ANL A,#07FHNODIP: MOV DPTR,#0FFDCHMOVX @DPTR,A ;送段码MOV DPTR,#0FFDDHMOV A,R1MOVX @DPTR,A ;送位码RL AMOV R1,ALCALL DLY1MSINC R0 ;调整显示DJNZ R7,NEXTDIS;POP PSW;RET;**************************延时1ms****************************DLY1MS: MOV BUFF1MS,#0F9HDJNZ BUFF1MS,$RET;*************************按键检查子程序******************** KEYCHK:MOV A,#00H ;查看是否有键按下MOV DPTR,#0FFDDHMOVX @DPTR,AMOV DPTR,#0FFDEHMOVX A,@DPTRCPL AANL A,#0FHJNZ TEST ;若有键按下则检测,无则返回。

MOV A,#0FFHRETTEST: LCALL KEYTESTLCALL DISPLAYLCALL KEYTESTCJNE A,BACK,NOKEYDWAIT: LCALL DISPLAY;MOV A,#00H ;等待键抬起MOV DPTR,#0FFDDHMOVX @DPTR,AMOV DPTR,#0FFDEHMOVX A,@DPTRCPL AANL A,#0FHJNZ WAIT ;若键未抬起,则继续等待MOV A,BACK ;将检测到的键值送给ASJMP CHKENDNOKEYD: MOV A,#0FFHCHKEND: RET;**********************按键检测子程序******************** KEYTEST: MOV R0,#0FEHMOV R1,#00HMOV R2,#08HNEXTL: MOV A,R0MOV DPTR,#0FFDDHMOVX @DPTR,AMOV DPTR,#0FFDEHMOVX A,@DPTRCPL AANL A,#0FHJNZ KEYDWN ;看按下的键是否在当前列DJNZ R2,GOSCAN ;看是否扫描完毕,若没有则调整继续扫描SJMP TSTEND ;若扫描完毕,则返回。

GOSCAN: MOV A,R0RL AMOV R0,AINC R1SJMP NEXTLKEYDWN: MOV R3,#00HLL0: RRC AJC LL1INC R3SJMP LL0LL1: MOV A,R3MOV B,AMUL ABADD A,R1 ;A中返回的为按下的键的代码RETTSTEND: MOV A,#0FFHRET;***********延时1s*******************DLY_1S: MOV TMOD,#01H;SETB ET0;MOV TH0,#0F0H ;10msMOV TL0,#0D8H;MOV buff1s,#100;SETB TR0;RET;;*********定时器T0中断服务程序**********INT_T0:CLR TR0 ;关计数器DJNZ buff1s ;NEXT_10MS;若不到1s继续SETB READ_AD;若到了,则置标志位cpl p1.0;clr et0;SJMP T0_END;NEXT_10MS: MOV TMOD,#01HMOV TH0,#0F0H ;定时10msMOV TL0,#0D8HSETB TR0T0_END: RETI;*************计算子程序,完成一路计算**************** COMPUTE: MOV A,@R0;MOV B,#04H ;测得的温度数乘以4MUL AB;MOV R6,B;MOV R7,A;LCALL HB2 ;调用子程序转化为压缩BCD码,R4,R5为出口RET;HB2: CLR ;BCD码初始化MOV R4,AMOV R5,AMOV R3,#10H ;转换双字节十六进制整数HB3: MOV A,R7 ;从高端移出待转换数的一位到CY中RLC AMOV R7,AMOV A,R6RLC AMOV R6,AMOV A,R5 ;BCD码带进位自身相加,相当于乘2ADDC A,R5DA A ;十进制调整MOV R5,AMOV A,R4ADDC A,R4DA AMOV R4,ADJNZ R3,HB3 ;处理完16bitRET;;********报警子程序*********WARN: MOV R0,#MOTATA ;R0指向MOTATAMOV R1,#WH ; R1指向WHMOV R7,#08H ;R7为循环次数WLOOP:MOV A,@R0MOV ALARMBUF,@R1 ;与指令相适应的必要中转CJNE A,ALARMBUF,REDGEHIGH: CLR C ;红灯信号LJMP NEXTREDRED : JNC GEHIGH ;读入数值比预设大SETB CNEXTRED:MOV A,BUFFHRLC A ;压入红灯信号MOV BUFFH,AMOV A,R1 ;调整R1指向WLADD A,#10HMOV R1,AMOV ALARMBUF,@R1MOV A,@R0CJNE A,ALARMBUF,GREENLSLOW: CLR C ;绿灯信号LJMP NEXTGRNGREEN: JC LSLOW ;读入数值比预设小SETB CNEXTGRN:MOV A,BUFFLRLC AMOV BUFFL,AMOV A,R1SUBB A,#10HMOV R1,AINC R1INC R0DJNZ R7,WLOOPMOV A,BUFFH ;将红灯报警信息送出MOV DPTR,#0FBFFH ;红灯信号对应地址p2.2MOVX @DPTR,AMOV A,BUFFL ;将绿灯报警信息送出MOV DPTR,#0F7FFH ;绿灯信号对应地址p2.3MOVX @DPTR,ARET;************键位调整程序************KEYFUNC: MOV DPTR,#KEYTABLEANL A,#0FH ;消除键位干扰MOVC A,@A+DPTR ;调整跳转位置CJNE A,#0AH,K1MOV A,#0FFHSETB SETINSETB SETH ;表示要设定温度报警上限值 CLR SETLRET;K1: CJNE A,#04H,K2MOV A,#0FFHSETB SETINSETB SETL ;表示要设定温度报警下限值 CLR SETHRETK2: CJNE A,#0FH,K3MOV A,#0FFHJB SETWARN,ENDISPSETB SETWARNCLR ABYTEINCLR SETHCLR SETLCLR ENTERRETENDISP: CLR SETWARN;CLR SETH;CLR SETL;RET;K3: CJNE A,#0EH,K4MOV A,#0FFHJB SOLIDISP,ENSOLID;SETB SOLIDISPRETENSOLID: CLR SOLIDISPRETK4: CJNE A,#0CH,K5MOV A,#0FFH;CLR SETIN;CLR SETH;CLR SETL;RET;K5: CJNE A,#0DH,K6MOV A,#0FFHSETB ENTERRET;K6: RETKEYTABLE: db 07h,04h,08h,05h,09h,06,0Ah; 0, 1 ,2 ,3 ,4 ,5 ,6db 04h,01h,00h,02h,0Fh,03h,0Eh,0Ch,0Dh; 7 ,8 ,9 ,10 ,11,12, 13, 14 ,15;*********实现对各个设定键的响应**********KEYRPD: JB SETWARN,WARNSET ;根据SOLIDISP的值调显示PUSH PSW;SETB RS1;CLR RS0 ;选择2号工作寄存器区MOV R0,#MOTATA;MOV CHANNEL,A ;将读入的值放入通道缓冲MOV R2,A;MOV BACK,A;MOV BUF,A;LCALL PADJUST ;调整R0,使其指向R2通道的温度值 SETB DISPIN ;5s计时的标志位MOV BUFF5S,#05H ;初始化5s计时MOV R2,CHANNEL;POP PSW;RET ;调整完毕,返回WARNSET:JNB SETIN,INSET ;若未设定通道,先进行设定LJMP SETTEMP ;若已设定则跳转到温度设定处INSET: MOV CHANNEL,ARETSETTEMP:JB SETH,HIGHSET ;设定温度警告上限JB SETL,LOWSET ;设定温度警告下限RETHIGHSET: LCALL READTEMPMOV R0,#WH ;调整R0使其指向温度上限存储区LJMP STORESETLOWSET: LCALL READTEMPMOV R0,#WL ; 调整R0使其指向温度下限存储区STORESET:MOV A ,TEMPBUF;LCALL COMPACT ;将输入的数转化为16进制数存储(未改变R0)MOV R2,CHANNEL ;送入要调整到的位置LCALL PADJUST ;调用调整子程序MOV @R0 ,A ; 将温度值送到相应的位置RETREADTEMP: JB ABYTEIN,READLOW;若已经有一位读入则读取低位READHIGH: SWAP A;MOV TEMPBUF,A;SETB ABYTEIN;RET;READLOW: ORL A,TEMPBUF;MOV TEMPBUF,A;CLR ABYTEIN;RET;;**********将输入温度值转化为16进制数********** COMPACT: MOV R2,A;ANL A,#0FH ;分离出十进制数的低位SWAP A;MOV R3,A;MOV A,R2;ANL A,#0F0H ;分离出十进制数的高位SWAP A;MOV R2,A;LCALL BH2 ;将双字节BCD码转化为十六进制整数MOV A,R2 ;将R2R3中的数除以4CLR C;RRC A;MOV R2,A;MOV A,R3;RRC A;MOV R3,AMOV A,R2;RRC A;MOV A,R3RRC A ;转换完毕A中为要得到的16进制数RET;;*********双字节BCD码整数转换成双字节十六进制整数********* BH2: MOV A,R3 ;将低字节转换成十六进制LCALL BCDHMOV R3,AMOV A,R2 ;将高字节转换成十六进制LCALL BCDHMOV B,#100 ;扩大一百倍MUL ABADD A,R3 ;和低字节按十六进制相加MOV R3,ACLR AADDC A,BMOV R2,ARET;*******单字节BCD码整数转换成单字节十六进制整数BCDH: MOV B,#10H ;分离十位和个位DIV ABMOV R4,B ;暂存个位MOV B,#10 ;将十位转换成十六进制MUL ABADD A,R4 ;按十六进制加上个位RET;********初始化WH和WL********INITWARN: MOV R0,#WH;MOV A,#0AFH;MOV R7,#08H;INITHIGH: MOV @R0,A;DJNZ R7,HIGHINC;SJMP ENDHIGH;HIGHINC: INC R0;SJMP INITHIGH;ENDHIGH: MOV R0,#WL;MOV A,#04BH;MOV R7,#08H;INITLOW: MOV @R0,A;DJNZ R7,LOWINC;SJMP ENDLOW;LOWINC: INC R0;SJMP INITLOW;ENDLOW: RET;;***********外部中断0的服务程序**********;完成一个循环的数据读取INT_0: CLR EX0 ; 若转换完毕关中断MOV DPTR,#0FFFEH;MOVX A,@DPTR ;读取转换完毕后的数MOV @R0,A ;将转换完毕的数保存DJNZ R6,READNEXT;若未读取完毕则调整后继续LCALL DLY_1S;SJMP EX0_END;READNEXT: INC R0;INC INNAL;MOV A,INNAL;MOVX @DPTR,A ;再次启动AD0809SETB EX0 ;开外部中断0EX0_END: RETI;TABLE: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8HDB 80H,90H,88H,83H,0C6H,0A1H,86H,8EHDB 0FFH,089H,0C7H;END。

相关主题