数字温度计程序清单 汇编
数字温度计程序

#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit d1=P2^0;sbit d2=P2^1;sbit d3=P2^2;sbit d4=P2^3;sbit key1=P3^0;sbit key2=P3^1;sbit key3=P3^2;sbit beep=P3^4;sbit DS=P1^2;sbit ACC_7=ACC^7;uint count=1000,alarm=300;uchar shu;uchar shi,fen,ri,yue,nian,xq,miao,ss; uint temp; // 温度变量uchar flag;uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uchar code tab1[]=//小数点点亮{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=120;y>0;y--);}void dsreset()//发复位{uint i;DS=0;i=103;while(i>0)i--;DS=1;i=4;while(i>0)i--;}uchar tmpread() //读取一字节{uchar j,k,dat;uint i;for(j=1;j<=8;j++){DS=0;i++; //延时DS=1;i++;i++;k=DS;i=8;while(i>0)i--;dat=(k<<7)|(dat>>1);//读出的数据最低位在最前面存一个字节在DAT 里}return(dat);}void tmpwritebyte(uchar dat) //写一个字节{uint i;uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb) //写 1{DS=0;i++;i++;DS=1;i=8;while(i>0)i--;}else{DS=0; //写 0i=8;while(i>0)i--;DS=1;i++;i++;}}}void tmpchange() //DS18B20温度变换{dsreset();delay(1);tmpwritebyte(0xcc); //跳过读取内存romtmpwritebyte(0x44); //开始转换}uint tmp() //读取温度{float tt;uchar a,b;dsreset();delay(1);tmpwritebyte(0xcc);tmpwritebyte(0xbe);a=tmpread(); //a为低字节8位b=tmpread(); //b为高字节8位temp=b; //temp为温度值UINT 16bittemp<<=8; //两个字节组合到一起temp=temp|a;if(b>127){flag=1;ss=flag;temp=~temp+1;}tt=temp*0.0625; // temp/16 则是温度的真实值tt.7位整数,4位小数temp=tt*10+0.5; // 扩大十倍取出了第一位小数return(temp);}void displayTemp(uint temp) //显示温度程序{uchar ge,shi,bai,qian,ser;d1=0;d1=0;d3=0;d4=0;dsreset();ser=temp/10; //分离出三位要显示的数字SBUF=ser;qian=temp/1000;bai=temp/100%10; // 百位数字shi=temp/10%10; // 十位数字ge=temp%10; // 个位数字if(flag==1){flag=0;P0=0xbf;d1=1;delay(2);d1=0;}if(qian!=0){P0=tab[qian];d1=1;delay(2);d1=0;}else{P0=0xff;d1=1;delay(2);d1=0;}if(temp>99){P0=tab[bai];d2=1;delay(2);d2=0;}P0=tab1[shi];d3=1;delay(2);d3=0;P0=tab[ge];d4=1;delay(2);d4=0;}uint keyscan(){if(key1==0){delay(5);if(key1==0){while(!key1);shu++;}}if(key2==0){delay(5);if(key2==0){while(!key2);count=count+10;if(shu==2){alarm+=10;}}}if(key3==0){delay(5);if(key3==0){while(!key3);count=count-10;if(shu==2){alarm-=10;}}}return(count);}void main(){beep=0;delay(10);while( 1 ){tmpchange();tmp( );if(shu==0){displayTemp();}keyscan();if(shu==1){displayTemp(count);}if(shu==2){displayTemp(alarm);}if(shu==3){shu=0;}if(temp>count||(temp<alarm)){beep=0;}elsebeep=1;}}。
数字温度计仿真图+源程序

源程序#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intucharyear,mon,day,xinqi;ucharsecond,minute,hour;ucharReadValue;uchardown,count;uchar flag; // 加减标志位char newsec,newmin,newhour; //重写数据用的秒,分,时char newyear,newmon,newday,newxinqi;uchar q;//---------------------ucharbai,shi,ge,fen,miao;#define t_cont 0.0625#define conever 0x44#define config 0x5f#define read 0xbe#define write 0x4e#define jmp 0xcc#define copy 0x48#define recall 0xb8sbitfmq=P2^3;sbitrs = P2^0;sbitrw = P2^1;sbit e = P2^2;sbit K1=P3^4;sbit K2=P3^5;sbit K3=P3^6;sbit K4=P3^7;sbit DATA=P1^0; //位定义1302芯片的接口sbit SCLK=P1^1; //位定义1302芯片的接口sbit RST =P1^4; //位定义1302芯片的接口bit t_sign;bit flag1;sbit a=ACC^0;sbitdq=P1^5;float temp=0;//----------------------------------------//函数声明//----------------------------------------void delayus(uint n);void delayms(uint k);void mingling(uchar com);void Write1302(uchardat);uchar Read1302(void);void WriteSet1302(ucharCmd,uchardat);uchar ReadSet1302(ucharCmd);void Int1302(void);void readtime(void);void display(void);void Setdisplay(void);void menu(void);void inmenu(void);void max();void min();void funcinc();void turn_sub(ucharnewval,ucharnewaddr); void scanquit();void funcquit();//--------------------------------------------------------//函数功能:us延时//-------------------------------------------------------- void delayus(uint n){uchar i;for(i=0;i<n;i++);}void delayms(uint k){uchar i;for(i=0;i<k;i++)delayus(100);}void delaya(uint m){while(m--);}void init_1820(){uchar i=1;while(flag1==0){dq=1;delaya(8);dq=0;delaya(52);dq=1;delaya(2);while(1){i=dq;if(i==0){flag1=1;delaya(10);break;}}}flag1=0;}/*************向1820发送字节************/ void byte_1820(uchardat){uchar i=0;for(i=0;i<8;i++){dq=0;ACC=dat&0x01;dq=a;delaya(5);dq=1;dat>>=1;}}/**************读1820的数据*************/ uchar read_1820(void){uchari,indat;indat=0;for(i=0;i<8;i++){dq=0;indat>>=1;dq=1;if(dq) indat|=0x80;delaya(4);}return(indat);}/************获取TEM*****************/ void readtem(){uint y;uchar td=0;uchartg=0;uchar k;init_1820();byte_1820(jmp);byte_1820(conever);init_1820();byte_1820(jmp);byte_1820(read);td=read_1820();tg=read_1820();k=tg&0x08;if(k==0x08){t_sign=1;tg=tg&0x07;temp=(tg*256+td)*t_cont;temp=(-temp*100+52800);}else {t_sign=0;tg=tg&0x07;temp=(tg*256+td)*t_cont;temp=temp*100;}bai=(uint)temp/10000;y=(uint)temp%10000;shi=y/1000;y=(uint)y%1000;ge=y/100;y=(uint)y%100;fen=y/10;miao=(uint)y%10;}//----------------------------------------------------------------------//函数功能:向1302写一个字节数据//----------------------------------------------------------------------void Write1302(uchardat){uchar i;SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备delayus(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续写8个二进制位数据{DATA=dat&0x01; //取出dat的第0位数据写入1302delayus(2); //稍微等待,使硬件做好准备SCLK=1; //上升沿写入数据delayus(2); //稍微等待,使硬件做好准备SCLK=0; //重新拉低SCLK,形成脉冲dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位}}//-----------------------------------------------------------------------//函数功能:从1302读一个字节数据//-----------------------------------------------------------------------uchar Read1302(void){uchari,dat;delayus(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续读8个二进制位数据{dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位if(DATA==1) //如果读出的数据是1dat|=0x80; //将1取出,写在dat的最高位SCLK=1; //将SCLK置于高电平,为下降沿读出delayus(2); //稍微等待SCLK=0; //拉低SCLK,形成脉冲下降沿delayus(2); //稍微等待}return dat; //将读出的数据返回}//-----------------------------------------------------------------------//函数功能:根据命令字,向1302写一个字节数据//-----------------------------------------------------------------------void WriteSet1302(ucharCmd,uchardat){RST=0; //禁止数据传递SCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输delayus(2); //稍微等待,使硬件做好准备Write1302(Cmd); //写入命令字Write1302(dat); //写数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递}//----------------------------------------------------------------------//函数功能:根据命令字,从1302读取一个字节数据//----------------------------------------------------------------------uchar ReadSet1302(ucharCmd){uchardat;RST=0; //拉低RSTSCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输Write1302(Cmd); //写入命令字dat=Read1302(); //读出数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递return dat; //将读出的数据返回}//----------------------------------------------------------------------//读取1302内部时间到second,minute,hour;//----------------------------------------------------------------------void readtime(void){ReadValue = ReadSet1302(0x81); //从秒寄存器读数据second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化ReadValue = ReadSet1302(0x83); //从分寄存器读minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化ReadValue = ReadSet1302(0x85); //从分寄存器读hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化ReadValue = ReadSet1302(0x87); //从分寄存器读day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x89); //从分寄存器读mon=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x8d); //从分寄存器读year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x8b); //从分寄存器读xinqi=(ReadValue&0x0F);}//--------------------------------------------------------------------------------//DS1302的充电设置//--------------------------------------------------------------------------------void Int1302(void){second=ReadSet1302(0x81);second=((second&0x70)>>4)*10+(second&0x0f);WriteSet1302(0x8e,0x00); //允许写入1302WriteSet1302(0x90,0xa9); //打开充电二极管WriteSet1302(0x80,(((second&0x7f)/10)<<4)|(second%10)); //保存当前秒并允许ds1302工作WriteSet1302(0x8e,0x10); //禁止写入1302}//----------------------------------------------------//调时菜单进入//----------------------------------------------------void menu(void){if(!K1){delayms(1);if(!K1){down=1;while(K1!=1); //等待按键松开,如果按键不松,while条件成立进行空的死循环count++; //记录menu按下的次数if(count>7)count=1;WriteSet1302(0x8e,0x00); //允许写入1302second=ReadSet1302(0x81);WriteSet1302(0x80,0x80|second); //按下menu键后禁止ds1302工作,把秒写回1302WriteSet1302(0x8e,0x10); //禁止写入1302}}}//----------------------------------------------------------------------//进入菜单,调时程序//----------------------------------------------------------------------void inmenu(void){switch(count){case 1:{max();min();mingling(0xc7);mingling(0x0f);//开显示显示光标scanquit();}break;case 2:{max();min();mingling(0xc4);mingling(0x0f);//开显示显示光标scanquit();}break;case 3:{max();min();mingling(0xc1);mingling(0x0f);//开显示显示光标scanquit();}break;case 4:{max();min();mingling(0x89);mingling(0x0f);//开显示显示光标scanquit();}break;case 5:{max();min();mingling(0x86);mingling(0x0f);//开显示显示光标scanquit();}break;case 6:{max();min();mingling(0x83);mingling(0x0f);//开显示显示光标scanquit();}break;case 7:{max();min();mingling(0x8d);mingling(0x0f);//开显示显示光标scanquit();}break;default:break;}}//---------------------------------------------------//---------------------------------------------------void max() //判断加{if(!K2){delayms(1);if(!K2)while(!K2);flag=1;funcinc();}}void min() //判断减{if(!K3){delayms(1);if(!K3)while(!K3);flag=0;funcinc();}}//----------------------------------------------------void funcinc(){switch(count){case 1:turn_sub(newsec,0x81);second=ReadSet1302(0x81);WriteSet1302(0x80,0x80|second);break;case 2:turn_sub(newmin,0x83);break;case 3:turn_sub(newhour,0x85);break;case 4:turn_sub(newday,0x87);break;case 5:turn_sub(newmon,0x89);break;case 6:turn_sub(newyear,0x8d);break;case 7:turn_sub(newxinqi,0x8b);break;default: break;}}//--------------------------------------------------------------- void turn_sub(ucharnewval,ucharnewaddr){newval=ReadSet1302(newaddr); //读取当前时间newval=((newval&0x70)>>4)*10+(newval&0x0f); //将bcd码转换成十进制if(flag==1)newval++;else newval--;switch(count){case 1: if(newval>59) newval=0;break;case 2: if(newval>59) newval=0;break;case 3: if(newval>23) newval=0;break;case 4: if(newval>31) newval=0;break;case 5: if(newval>12) newval=0;break;case 6: if(newval>99) newval=0;break;case 7: if(newval>6) newval=0;break;default:break;}WriteSet1302(0x8e,0x00); //允许写入1302WriteSet1302((newaddr-1),((newval/10)<<4)|(newval%10)); //将新数据写入寄存器WriteSet1302(0x8e,0x10); //禁止写入1302display(); //将修改后的值显示出来}//-----------------------------------------------------//-----------------------------------------------------void scanquit(){if(!K4){mingling(0x0c);delayms(1);if(!K4)while(!K4);funcquit();}}void funcquit(){mingling(0x0c);count=0;down=0;second=ReadSet1302(0x81);second=((second&0x70)>>4)*10+(second&0x0f);WriteSet1302(0x8e,0x00);WriteSet1302(0x80,(((second&0x7f)/10)<<4)|(second%10)); //保存当前秒并允许ds1302工作WriteSet1302(0x8e,0x10);}//---------------------------------------------------------------------- //显示程序//---------------------------------------------------------------------- //////////////命令/////////////////////void delay(uint m){uinti,j;for(i=0;i<m;i++)for(j=0;j<570;j++);}bit lcd_bz(){bit result;rs=0;rw=1;e=1;_nop_();_nop_();_nop_();_nop_();result=(bit)(P0&0x80);e=0;return(result);}void mingling(uchar com){while(lcd_bz());rs=0;e=0;rw=0;P0=com;e=1;e=0;delay(1);}void lcd_pos(ucharpos){mingling(pos);}//////////////数据/////////////////////void shuju(ucharshu){rs=1;rw=0;e=0;P0=shu;e=1;e=0;delay(1);}////////////初始化//////////////////////void init_1602(void){mingling(0X38);//功能设置delay(1);mingling(0X0c);//显示开关控制delay(1);mingling(0X06);//输入方式设置delay(1);mingling(0X01);//清显示delay(1);}//////////////显示//////////////////void date(void){switch(xinqi){case 0: shuju('S');shuju('u');shuju('n');break;case 1: shuju('M');shuju('o');shuju('n');break;case 2: shuju('T');shuju('u');shuju('e');break;case 3: shuju('W');shuju('e');shuju('d');break;case 4: shuju('T');shuju('h');shuju('u');break;case 5: shuju('F');shuju('r');shuju('i');break;case 6: shuju('S');shuju('a');shuju('t');break;default:break;}}void display(void){readtem();readtime();while(lcd_bz());delay(100);lcd_pos(0x80);shuju('2');shuju('0');shuju(year/10+0x30);lcd_pos(0x83);shuju(year%10+0x30);shuju('/');shuju(mon/10+0x30);shuju(mon%10+0x30);shuju('/'); shuju(day/10+0x30);shuju(day%10+0x30);lcd_pos(0xc0);shuju(hour/10+0x30);shuju(hour%10+0x30);shuju(':'); shuju(minute/10+0x30);shuju(minute%10+0x30);shuju(':'); shuju(second/10+0x30);shuju(second%10+0x30);lcd_pos(0x8c);date();lcd_pos(0xc8);if(t_sign==1){shuju(0x2d);delaya(10);if(bai!=0)shuju(0x20);shuju(shi+0x30);shuju(ge+0x30);shuju(0x2e);shuju(fen+0x30);shuju(miao+0x30);shuju(0xdf);shuju(0x43);}else{shuju(0x20);delaya(10);if(bai!=0)shuju(bai+0x30);else shuju(0x20);shuju(shi+0x30);shuju(ge+0x30);shuju(0x2e);shuju(fen+0x30);shuju(miao+0x30);shuju(0xdf);shuju(0x43);}/********/if((shi>=3&&ge>=3)||(shi<=2&&ge<=9)){fmq=0;}if((shi<=3&&ge<3)||(shi>=2&&ge>9))fmq=1;}//---------------------------------------------------------------------- //函数功能:主函数//---------------------------------------------------------------------- void main(void){Int1302();init_1602();init_1820();down=0;count=0;while(1){menu(); //检测是否调时if(down==1){inmenu(); //进入调时模式}else{while(lcd_bz());display();}}}。
数字温度程序

数字温度计程序清单S1OK EQU 5FHTEMPUTER EQU 39HTEMPH EQU 5EHTEMPL EQU 5DHMS50EQU 5CHSIGN EQU 5BHS1 BIT P1.0S2 BIT P1.1S3 BIT P1.2S4 BIT P1.3ORG 0000HLJMP MAINORG 000BHLJMP TOITORG 0030HMAIN: MOV SP, #60HMOV TMOD, #01HMOV TH0, #3CHMOV TL0, #0B0HSETB ET0SETB TR0SETB EAMOV TEMPH, #30MOV TEMPL, #9MOV TEMPUTER, #15 ;温度最始值MOV S1OK, #00HMOV SIGN, #00HMOV 38H, #0BHMOV 37H, #0CHMOV 36H, #0BHACALL DISPACALL T1S; ***************************************** ; 主程序START: JB S1, NET1ACALL T12MSJB S1, NET1JNB S1, $INC SIGNMOV A, SIGNCJNE A, #1, TIAOACALL TIAOTLTIAO:CJNE A, #2, NET1MOV SIGN, #0ACALL TIAOTH; ***************************************** NET1: MOV A, S1OKCJNE A, #1, STARTMOV A, TEMPUTERSUBB A, TEMPHJNB ACC.7, ALEMMOV A, TEMPUTERSUBB A, TEMPLJB ACC.7, ALEMSETB P2.1ACALL WENDUACALL DISPMOV S1OK, #00HAJMP STARTALEM: MOV 36H, #0CHMOV 37H, #0CHMOV 38H, #0CHCLR P2.1ACALL DISPACALL T1SLCALL WENDULCALL DISPMOV S1OK, #00HSJMP START;***************************************** TIAOTL:MOV 50H, TEMPUTERMOV 37H, TEMPLACALL BIN_BCDACALL DISPACALL T12MSACALL T12MSACALL T12MSACALL T12MSMOV 36H, #0AHMOV 37H, #0AHMOV 38H, #0AHACALL DISPACALL T12MSACALL T12MSACALL T12MSACALL T12MSJB S2, ADD1ACALL T12MSJB S2, ADD1JNB S2, $INC TEMPLMOV A, TEMPLCJNE A, #100, ADD1MOV TEMPL, #0ADD1: JB S3, ADD2ACALL T12MSJB S3, ADD2JNB S3, $DEC TEMPLMOV A, TEMPLCJNE A, #00 , ADD2MOV TEMPL,#100ADD2: JB S4, TIAOTLACALL T12MSJB S4, TIAOTLJNB S4, $MOV TEMPUTER, 50HLJMP START; 高位调整; ***************************************** TIAOTH:MOV 50H, TEMPUTERMOV 37H, TEMPHACALL BIN_BCDACALL DISPACALL T12MSACALL T12MSACALL T12MSACALL T12MSMOV 36H, #0AHMOV 37H, #0AHMOV38H, #0AHACALL DISPACALL T12MSACALL T12MSACALL T12MSACALL T12MSJB S2, ADD11ACALL T12MSJB S2, ADD11JNB S2, $INC TEMPHMOV A, TEMPHCJNE A, #100, ADD11MOV TEMPH, #0ADD11: JB S3, ADD22ACALL T12MSJB S3, ADD22JNB S3, $DEC TEMPHMOV A, TEMPHCJNE A, #00 , ADD22MOV TEMPH,#100ADD22: JB S4, TIAOTHACALL T12MSJB S4, TIAOTHJNB S4, $MOV TEMPUTER, 50HLJMP START; 一秒定时中段; ***************************************** TOIT: PUSH PSWPUSH ACCMOV TH0, #3CHMOV TL0, #0B0HINC MS50MOV A, MS50CJNE A, #14H, RETURNMOV S1OK, #1MOV MS50, #00HRETURN:POP ACCPOP PSWRETI; ***************************************** ;温度总子程序; ***************************************** wendu: ACALL INIT_1820ACALL RE_CONFIGACALL GET_TEMPERACALL TEMPER_COVRET; ***************************************** ;DS18B20初始化程序; ***************************************** INIT_1820:SETB P2.0NOPCLR P2.0MOV R0,#06BHMOV R1,#03HTSR1:DJNZ R0,TSR1 ; 延时MOV R0,#6BHDJNZ R1,TSR1SETB P2.0NOPNOPNOPMOV R0,#25HTSR2:JNB P2.0,TSR3DJNZ R0,TSR2LJMP TSR4 ; 延时TSR3:SETB 20H.1 ; 置标志位,表示DS1820存在LJMP TSR5TSR4:CLR 20H.1 ; 清标志位,表示DS1820不存在LJMP TSR7TSR5:MOV R0,#06BHMOV R1,#03HTSR6:DJNZ R0,TSR6 ; 延时MOV R0,#6BHDJNZ R1,TSR6TSR7:SETB P2.0RET; *****************************************; 重新写DS18B20暂存存储器设定值; *****************************************RE_CONFIG:JB 20H.1,RE_CONFIG1 ; 若DS18B20存在,转RE_CONFIG1RETRE_CONFIG1:MOV A,#0CCH ; 发SKIP ROM命令LCALL WRITE_1820MOV A,#4EH ; 发写暂存存储器命令LCALL WRITE_1820MOV A,#00H ; TH(报警上限)中写入00HLCALL WRITE_1820MOV A,#00H ; TL(报警下限)中写入00HLCALL WRITE_1820MOV A,#1FH ; 选择9位温度分辨率LCALL WRITE_1820RET; *****************************************; 读出转换后的温度值; *****************************************GET_TEMPER:SETB P2.0 ; 定时入口LCALL INIT_1820JB 20H.1,TSS2RET ; 若DS18B20不存在则返回TSS2:MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#44H ; 发出温度转换命令LCALL WRITE_1820LCALL INIT_1820MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#0BEH ; 发出读温度命令LCALL WRITE_1820LCALL READ_18200MOV 37H,A ; 将读出的温度数据保存RET; *****************************************; 写DS18B20的程序; *****************************************WRITE_1820:MOV R2,#8CLR CWR1:CLR P2.0NOPNOPNOPNOPRRC AMOV P2.0,CMOV R3,#35DJNZ R3,$SETB P2.0NOPDJNZ R2,WR12SETB P2.0RET; *****************************************; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据; ***************************************** READ_18200:MOV R4,#2 ; 将温度高位和低位DS18B20中读RE00:MOV R2,#8RE01:CLR CSETB P2.0NOPNOPCLR P2.0NOPNOPNOPSETB P2.0NOPNOPMOV C,P2.0MOV R3,#35RE20:DJNZ R3,RE20RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET; *****************************************; 将从DS18B20中读出的温度数据进行转换; ***************************************** TEMPER_COV:MOV A,#0F0HANL A,36H ; 舍去温度低位中小数点SWAP AMOV 37H,AMOV A,36HJNB ACC.3,TEMPER_COV1 ; 四舍五入去温度值INC 37HTEMPER_COV1:MOV A,35HANL A,#07HSWAP AADD A,37HMOV 37H,A ; 保存变换后的温度数据LCALL BIN_BCDDISP: SETB RS0MOV R0, #36HMOV R7, #3LOOPP:MOV A, @R0MOV DPTR, #TABMOVC A, @A+DPTRMOV SBUF, AJNB TI, $CLR TIINC R0DJNZ R7, LOOPPCLR RS0RETTAB: DB 11H, 0D7H, 32H, 92H, 0D4H, 98H, 18H, 0D1H, 10H, 90H ,0FFH, 070H, 0FEH; 延时子程序T12MS: SETB RS1MOV R7, #18HTM: MOV R6, #0FFHTM6: DJNZ R6, TM6DJNZ R7, TMCLR RS1RET; 开机延时程序T1S: SETB RS1MOV R6, #3LSP:ACALL T12MSDJNZ R6, LSPCLR RS1RETEND3。
C51单片机数字温度计汇编程序及说明书

1绪论1.1选题背景随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便也是不可否定的,其中数字温度计就是一个典型的例子,但人们对它的要求越来越高,要为现代人工作、科研、生活提供更好的更方便的设施就需要从单片机技术入手,一切向着数字化控制,智能化控制方向发展。
温度测量在物理实验、医疗卫生、食品生产等领域,尤其在热学试验(如:物体的比热容、汽化热、热功当量、压强温度系数等教学实验)中,有特别重要的意义。
现在所使用的温度计通常都是精度为1℃和0.1℃的水银、煤油或酒精温度计。
这些温度计的刻度间隔通常都很密,不容易准确分辨,读数困难,而且他们的热容量还比较大,达到热平衡所需的时间较长,因此很难读准,并且使用非常不方便。
本设计所介绍的数字温度计与传统的温度计相比,具有读数方便,测温范围广,测温准确等优点,其输出温度采用数字显示,主要用于对测温比较准确的场所,或科研实验室使用。
因此本课题就尝试通过编程与芯片的结合来解决传统数字温度计的弊端,设计出新型数字温度计。
1.2课题现状分析及研究意义温度传感器的发展现状:温度传感器使用范围广,数量多,居各种传感器之首,其发展大致经历了以下3个阶段:①传统的分立式温度传感器(含敏感元件)——热电偶传感器,主要是能够进行非电量和电量之间转换。
②模拟集成温度传感器/控制器。
集成传感器是采用硅半导体集成工艺制成的,因此亦称硅传感器或单片集成温度传感器。
③智能温度传感器。
它是微电子技术、计算机技术和自动测试技术(ATE_)的结晶。
智能温度传感器内部包含温度传感器、A/D传感器、信号处理器、存储器(或寄存器)和接口电路。
本课题的研究可以应用领域生产、生活等很多领域。
对于家用电器从洗衣机、微波炉到音响等等到处都可以用到温度控制器来方便大家的日常生活。
开发此产品后也可方便应用安装在小至家庭大到工厂车间,小至一个芯片大到一个机械设备。
例如在家庭客厅卧室等必要地方显示室温,可防止家里食物是否变质及早采取措施。
数字温度汇编程序

数字温度汇编程序概述:数字温度汇编程序是一种用于将温度数据转换为数字形式的计算机程序。
它可以接收各种温度输入,如摄氏度、华氏度或开尔文度,并将其转换为数字格式,以便于存储、处理和分析。
程序设计:数字温度汇编程序的设计主要包括输入模块、转换模块和输出模块。
1. 输入模块:输入模块负责接收用户输入的温度数据。
可以通过命令行参数、文本文件或图形用户界面等方式进行输入。
程序应该能够处理不同单位的温度输入,如摄氏度、华氏度或开尔文度。
2. 转换模块:转换模块负责将输入的温度数据转换为数字格式。
根据输入的单位,程序应该能够进行相应的转换计算。
例如,将摄氏度转换为华氏度的公式为:华氏度 = 摄氏度 * 9/5 + 32。
3. 输出模块:输出模块负责将转换后的数字温度数据进行输出。
可以将结果显示在命令行界面、保存到文本文件或通过网络发送给其他系统。
输出的格式应该清晰易读,并且包含必要的单位信息。
示例代码:下面是一个简单的数字温度汇编程序的示例代码:```assembly; 输入模块input:; 读取用户输入的温度值; 可以通过命令行参数或其他方式获取输入; 转换模块convert:; 判断输入的温度单位,并进行相应的转换计算; 如果输入的是摄氏度,则进行摄氏度到华氏度的转换; 如果输入的是华氏度,则进行华氏度到摄氏度的转换; 如果输入的是开尔文度,则进行开尔文度到摄氏度的转换; 输出模块output:; 将转换后的温度值进行输出; 可以将结果显示在命令行界面或保存到文件```示例数据:假设用户输入的温度为摄氏度,数值为25°C。
程序将进行摄氏度到华氏度的转换,计算结果为77°F。
最后,程序将输出转换后的温度值:77°F。
总结:数字温度汇编程序是一种用于将温度数据转换为数字形式的计算机程序。
它通过输入模块接收用户输入的温度数据,然后通过转换模块将其转换为数字格式,最后通过输出模块将转换后的温度值进行输出。
数字温度计的c语言程序

void Read_Temperature()
{
if(Init_DS18B20( )==1)
DS18B20_IS_OK=0; //DS18B20故障
Temp_Value[1]=ReadOneByte(); //温度高8位
Alarm_Temp_HL[0]=ReadOneByte();
Alarm_Temp_HL[1]=ReadOneByte();
DS18B20_IS_OK=1;
}
}
///设置报警值
void Set_Alarm_Temp_Value()
程序名称:在数码管上显示温度
*************************************************************************/
void Display_Temperture()
{
uchar i;
uchar t=150; //延时值
uint Time0_Count=0;
/*******************************************************************************************************************************/
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
数字温度计C程序

/*在使用这个例子时,要将J11插针短接到2、3两脚,引入温感数据脚到P33*/#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit greenled=P3^1; //定义绿灯的控制端口sbit redled=P3^0; //定义红灯的控制端口sbit DS=P1^0; //定义DS18B20接口sbit speaker=P1^1; //定义蜂鸣器的控制端口sbit k1=P3^2; //定义功能键的控制键sbit k2=P3^3; //定义温度定位键sbit k3=P3^4; //定义温度加的控制键sbit k4=P3^5; //定义蜂鸣器减停止按键float m1=2,n1=10,q1=0; //最高温度显示位H20.0float m2=1,n2=10,q2=0; //最低温度显示位L10.0int temp;int temp1=0; //key1引起的外部中断0char zancun1=1;char zancun2=0;uchar flag1;void display(unsigned char *lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc 为显示的个数void delay();//延时子函数,5个空指令code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, // 0-90xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef, // 10-190x40,// 20 符号位"-"0x39,// 21 符号c0x00,// 22 空表0x76,// 23 高温H0x38};// 24 低温L//共阴数码管显示数的组成是"0-9""0-9有小数点的" "-" "C" "空表" "H " " L" unsigned char l_tmpdate[4]={0,0,0,0};//定义数组变量,int tmp(void);void tmpchange(void);void tmpwritebyte(uchar dat);uchar tmpread(void);bit tmpreadbit(void);void dsreset(void);void delayb(uint count);void main() //主函数{EA=1; //首先开启总中断EX0=1; //开启外部中断0IT0=1; // 设置成下降沿触发方式redled=1;greenled=1;while(1){if(temp1==0)//正常温度显示{while(1){uchar i;int l_tmp;tmpchange(); //温度转换l_tmp=tmp(); //读取温度值if(l_tmp<0) //负数处理{ l_tmpdate[0]=20;l_tmp--;l_tmp--;l_tmp=~l_tmp;l_tmp=l_tmp%1000;l_tmpdate[1]=l_tmp/100;//获取十位if(l_tmpdate[1]==0)l_tmpdate[1]=22;l_tmp=l_tmp%100;l_tmpdate[2]=l_tmp/10;//获取个位再l_tmpdate[2]+=10;//加入小数点,查表可得出有小数点的排在后10位,所以加10l_tmpdate[3]=l_tmp%10;//获取小数第一位}else //正数的处理{l_tmpdate[0]=l_tmp/1000; //显示百位if(l_tmpdate[0]==0)l_tmpdate[0]=22;//判断温度为正温度且没有上百,前面不显示,查表第12是空l_tmp=l_tmp%1000;l_tmpdate[1]=l_tmp/100; //显示十位if(l_tmpdate[0]==22&&l_tmpdate[1]==0) //百位和十位同时为0 则不显示l_tmpdate[1]=22;l_tmp=l_tmp%100;l_tmpdate[2]=l_tmp/10;//获取个位再l_tmpdate[2]+=10;//加入小数点,查表可得出有小数点的排在后10位,所以加10l_tmpdate[3]=l_tmp%10;//获取小数第一位}if(l_tmpdate[1]==22)//对于低温限制为小于10度的处理{if(m1*10+n1+q1*0.1>=(l_tmpdate[1]-22)*10+l_tmpdate[2]+l_tmpdate[3]*0.1&&m2*10+n2+q2*0.1<=(l_tmpdate[1]-22)*10+l_tmpdate[2]+l_tmpdate[3]*0.1){greenled=0;//温度高于最低限和最高限绿灯亮,红灯灭,蜂鸣器不报警redled=1;speaker=1;}else{greenled=1;//温度高于最低限和最高限绿灯灭,红灯亮,蜂鸣器报警redled=0;speaker=zancun2;}}else//对于低温为两位数字的处理{if(m1*10+n1+q1*0.1>=l_tmpdate[1]*10+l_tmpdate[2]+l_tmpdate[3]*0.1&&m2*10+n2+q2*0.1<=l_tmpdate[1]*10+l_tmpdate[2]+l_tmpdate[3]*0.1){greenled=0;///温度高于最低限和最高限绿灯亮,红灯灭,蜂鸣器不报警redled=1;speaker=1;}else{greenled=1;//温度高于最低限和最高限绿灯灭,红灯亮,蜂鸣器报警redled=0;speaker=zancun2;}}if(k4==0){ while(k4==0)//消抖程序{_nop_();}zancun2++;if(zancun2==2){zancun2=0;}}for(i=0;i<100;i++)//循环输出45次,提高亮度仿真时使用100 比较稳定{display(l_tmpdate,4);}if(zancun1==0){ zancun1=1;break;}}}if(temp1==1)//高温设置{ int i,n=0,m=0;l_tmpdate[0]=23;l_tmpdate[1]=m1;l_tmpdate[2]=n1;l_tmpdate[3]=q1;while(1){for(i=0;i<30;i++)//循环输出40次,提高亮度{display(l_tmpdate,4);if(k2==0)//确定调试第几个数码管{n++;if(n>=3)n=0;while(k2==0)//消抖程序{_nop_();}}if(n==0)// 第一位数码管的设置{if(k3==0){while(k3==0)//消抖程序{_nop_();}m1++;if(m1==10) //如果第一位数码管是9,则变为- m1=20;if(m1==21) //如果第一位数码管是-,则变为0 m1=0;l_tmpdate[1]=m1;l_tmpdate[2]=n1;l_tmpdate[3]=q1;}}if(n==1)//第二位数码管的设置{if(k3==0){while(k3==0)//消抖程序{_nop_();}n1++;if(n1>=20)n1=10;l_tmpdate[1]=m1;l_tmpdate[2]=n1;l_tmpdate[3]=q1;}}if(n==2)//第三位数码管的设置{if(k3==0){while(k3==0)//消抖程序{_nop_();}q1++;if(q1>=10)q1=0;l_tmpdate[1]=m1;l_tmpdate[2]=n1;l_tmpdate[3]=q1;}}}if(zancun1==0)// 当从中断程序回来时,可以跳出程序{ zancun1=1;break;}}}if(temp1==2)//低温设置{int i,n=0,m=0;l_tmpdate[0]=24;l_tmpdate[1]=m2;l_tmpdate[2]=n2;l_tmpdate[3]=q2;while(1){for(i=0;i<30;i++)//循环输出40次,提高亮度{display(l_tmpdate,4);if(k2==0)//确定调试第几个数码管{n++;if(n>=3)n=0;while(k2==0)//消抖程序{_nop_();}}if(n==0)// 第一位数码管的设置{if(k3==0){while(k3==0)//消抖程序{_nop_();}m2++;if(m2==10) //如果第一位数码管是9,则变为- m2=20;if(m2==21) //如果第一位数码管是-,则变为0 m2=0;l_tmpdate[1]=m2;l_tmpdate[2]=n2;l_tmpdate[3]=q2;}}if(n==1)//第二位数码管的设置{if(k3==0){while(k3==0)//消抖程序{_nop_();}n2++;if(n2>=20)n2=10;l_tmpdate[1]=m2;l_tmpdate[2]=n2;l_tmpdate[3]=q2;}}if(n==2)//第三位数码管的设置{if(k3==0){while(k3==0)//消抖程序{_nop_();}q2++;if(q2>=10)q2=0;l_tmpdate[1]=m2;l_tmpdate[2]=n2;l_tmpdate[3]=q2;}}}if(zancun1==0){ zancun1=1;break;}}}}}void key_scan1() interrupt 0{temp1++;if(temp1==3)temp1=0;zancun1=0;}void display(unsigned char *lp,unsigned char lc)//显示{unsigned char i; //定义变量P0=0x00; //端口2为输出P2=0xf7; //将P2口的输出1111 0111,对应第一个数码管for(i=0;i<lc;i++){ //循环显示P0=table[lp[i]]; //查表法得到要显示数字的数码段delay();delay();delay();P0=0x00; //清0端口,准备显示下位P2>>=1; //下一位数码管if(i==3) //检测显示完4位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据break;}}void delay(void) //空5个指令{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); }void delayb(uint count) //delay{uint i;while(count){i=200;while(i>0)i--;count--;}}/*。
51单片机程序(数字温度计)

数字温度计1、LCD.c#include <reg51.h>#include<LCD.h>unsigned char code number_X[]={ //宽x高=8x16,纵向字节倒序0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, //00x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00, //10x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00, //20x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00, //30x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00, //40x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00, //50x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00, //60x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00, //70x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00, //80x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, //90x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // .0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00, //-0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //nop 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00, //:0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00};void LCD_WriteCommandE1(unsigned char com) {while(CRADD1 & 0x80);CWADD1 = com;}void LCD_WriteDataE1(unsigned char dat)while(CRADD1 & 0x80);DWADD1 = dat;}void LCD_WriteCommandE2(unsigned char com) {while(CRADD2 & 0x80);CWADD2 = com;}void LCD_WriteDataE2(unsigned char dat){while(CRADD2 & 0x80);DWADD2 = dat;}void LCD_Init(){LCD_WriteCommandE1(0xe2);LCD_WriteCommandE2(0xe2);LCD_WriteCommandE1(0xa4);LCD_WriteCommandE2(0xa4);LCD_WriteCommandE1(0xa9);LCD_WriteCommandE2(0xa9);LCD_WriteCommandE1(0xa0);LCD_WriteCommandE2(0xa0);LCD_WriteCommandE1(0xc0);LCD_WriteCommandE2(0xc0);LCD_WriteCommandE1(0xaf);LCD_WriteCommandE2(0xaf);}void LCD_Clear(void){unsigned char i,j;for(i=0;i<4;i++){LCD_WriteCommandE1(i+0xb8);LCD_WriteCommandE2(i+0xb8);LCD_WriteCommandE1(0x00);LCD_WriteCommandE2(0x00);for(j=0;j<0x50;j++){LCD_WriteDataE1(0x00);LCD_WriteDataE2(0x00);}}void display_cn(unsigned char lin,unsigned int col,unsigned int len,unsigned char *p) {unsigned int seg,i,j;unsigned char a,L,n;switch(lin){case 0: n=0xba;break;case 1: n=0xb8;break;}for(i=0;i<len;i++){for(j=0;j<2;j++){L=col;LCD_WriteCommandE1(n+j);LCD_WriteCommandE2(n+j);for(seg=0;seg<16;seg++){if (L < 61){a = L;LCD_WriteCommandE1(a);LCD_WriteDataE1(*p++);}else{a = L-61;LCD_WriteCommandE2(a);LCD_WriteDataE2(*p++);}L++;}}col=col+16;}}void display_number(unsigned char lin,unsigned int col,unsigned char num){unsigned int seg,i,j;unsigned char a,L,n,k;switch(lin){case 0: n=0xba;break;case 1: n=0xb8;break;}k=num*16;for(j=0;j<2;j++){L=col;LCD_WriteCommandE1(n+j);LCD_WriteCommandE2(n+j);for(seg=0;seg<8;seg++){if (L < 61){a = L;LCD_WriteCommandE1(a);LCD_WriteDataE1(number_X[k++]);}else{a = L-61;LCD_WriteCommandE2(a);LCD_WriteDataE2(number_X[k++]);}L++;}}}void display_unsigned_int(unsigned char lin,unsigned int col,unsigned int dat) {unsigned int seg;unsigned char k[4];k[3]=dat%10;k[2]=((dat/10)%10);k[1]=((dat/100)%10);k[0]=((dat/1000)%10);if(k[0]==0) {k[0]=12;}if((k[0]==12)&&(k[1]==0)){ k[0]=12;k[1]=12;}if((k[0]==12)&&(k[1]==12)&&(k[2]==0)){k[0]=12;k[1]=12;k[2]=12;}for(seg=0;seg<4;seg++){display_number(lin,col,k[seg]);col=col+10;}}void display_signed_int(unsigned char lin,unsigned int col,signed int dat){unsigned int seg;unsigned char k[5],a;k[0]=12;if(dat<0){dat=(~dat)+1;k[0]=11;}k[4]=dat%10;k[3]=((dat/10)%10);k[2]=((dat/100)%10);k[1]=((dat/1000)%10);a=k[0];if(k[1]==0) {k[0]=12;k[1]=a;}if((k[1]==a)&&(k[2]==0)){ k[0]=12;k[1]=12;k[2]=a;}if((k[1]==12)&&(k[2]==a)&&(k[3]==0)){k[0]=12;k[1]=12;k[2]=12;k[3]=a;}for(seg=0;seg<5;seg++){display_number(lin,col,k[seg]);col=col+10;}}void display_unsigned_char(unsigned char lin,unsigned int col,unsigned char dat) {unsigned int seg;unsigned char k[3];k[1]=dat%10;k[0]=((dat/10)%10);for(seg=0;seg<2;seg++){display_number(lin,col,k[seg]);col=col+10;}}2、LCD.h#include <reg51.h>#include <absacc.h>#ifndef __LCD__#define __LCD__#define CWADD1 XBYTE[0x8000]#define DWADD1 XBYTE[0x8001]#define CRADD1 XBYTE[0x8002]#define DRADD1 XBYTE[0x8003]#define CWADD2 XBYTE[0x8004]#define DWADD2 XBYTE[0x8005]#define CRADD2 XBYTE[0x8006]#define DRADD2 XBYTE[0x8007]extern void LCD_Init();extern void display_cn(unsigned char lin,unsigned int col,unsigned int len,unsigned char *p);extern void display_signed_int(unsigned char lin,unsigned int col,signed int dat);extern void display_unsigned_int(unsigned char lin,unsigned int col,unsigned int dat);extern void display_unsigned_char(unsigned char lin,unsigned int col,unsigned char dat);extern void LCD_Clear(void);#endif3、DS18B20.c#include <reg51.h>#include "string.h"#include "intrins.h"#include "DS18B20.h"sbit DQ=P1^0;void delay(unsigned int uSeconds){for(;uSeconds>0;uSeconds--);}unsigned char ow_reset(void){unsigned char xdata presence;DQ = 0;delay(48);DQ = 1;delay(7);presence = DQ;delay(48);return(presence);}unsigned char read_byte(void){unsigned char i;unsigned char value = 0;for (i=8;i>0;i--){value>>=1;DQ = 0; // pull DQ low to start read timeslotDQ = 1; // then rlease DQ_nop_();_nop_();_nop_();_nop_();_nop_(); // read DQ data at 1 to 15us,here delay 6us;if(DQ)value|=0x80;delay(7); // wait for rest of timeslot,72us }return(value);}void write_byte(char val){unsigned char i;for (i=8; i>0; i--) // writes byte, one bit at a time{DQ = 0; // pull DQ low to start timeslotDQ = val&0x01;delay(7); // hold value for remainder of timeslot,here 72us DQ = 1;val=val/2;}delay(5);}float Read_Temperature(void){unsigned char Hdata,Ldata,b;int a;bit flag;float x,y,z;ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0xBE); // Read Scratch Paddelay(100);Ldata=read_byte(); // Low byte firstHdata=read_byte(); // High byte afterow_reset();write_byte(0xCC); //Skip ROMwrite_byte(0x44); // Start Conversiona=Hdata*256+Ldata;x=(float)(Ldata&0x0f);x=x/16;if(a<0)flag=1;else flag=0;b=a>>4;z=(float)(b);if(flag==1){b=~b+1;z=(float)(b);z=0-z;}y=z+x;return y;}4、DS18B20.h#ifndef __DS18B20__#define __DS18B20__extern float Read_Temperature(void); #endif5、main.c#include <reg51.h>#include<LCD.h>#include<main.h>#include "DS18B20.h"void wait(unsigned int x){unsigned int i;i=0;for(i=0;i<x;i++);}void main(void){float F;signed int a;LCD_Init();LCD_Clear();display_cn(0,20,5,szwdj);display_cn(1,0,3,wdz);while(1){F=Read_Temperature( );a=(signed int)F;display_signed_int(1,40,a);wait(5000);}}6、main.h#ifndef MAIN_H__#define MAIN_H__// 中文字模库16x16点阵code unsigned char szwdj[]={ //纵向字节倒序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ACALL T12MS
LCALL INIT_1820
TSR4:CLR 20H.1
MOV A,#0CCH
; 清标志位,表示DS1820不存在
; 跳过ROM匹配
LJMP TSR7
LCALL WRITE_1820
TSR5: MOV R0,#06BH
MOV A,#0BEH
MOV R1,#03H
DJNZ R3,$
; TH(报警上限)中写入00H
SETB P2.0
LCALL WRITE_1820
NOP
MOV A,#00H
DJNZ R2,WR1
; TL(报警下限)中写入00H
SETB P2.0
LCALL WRITE_1820
RET
MOV A,#1FH
**********************************
; 发出读温度命令
TSR6:DJNZ R0,TSR6 ; 延时
LCALL WRITE_1820
MOV R0,#6BH
LCALL READ_18200
DJNZ R1,TSR6
MOV 37H,A
TSR7:SETB P2.0
; 将读出的温度数据保存
RET
RET
;******************************** *****************************
LJMP START ; 高位调整 ;******************************** TIAOTH:MOV 50H, TEMPUTER MOV 37H, TEMPH ACALL BIN_BCD ACALL DISP ACALL T12MS ACALL T12MS ACALL T12MS ACALL T12MS MOV 36H, #0AH MOV 37H, #0AH MOV 38H, #0AH ACALL DISP ACALL T12MS ACALL T12MS ACALL T12MS ACALL T12MS JB S2, ADD11 ACALL T12MS JB S2, ADD11 JNB S2, $ INC TEMPH MOV A, TEMPH CJNE A, #100, ADD11 MOV TEMPH, #0 ADD11: JB S3, ADD22 ACALL T12MS JB S3, ADD22 JNB S3, $ DEC TEMPH MOV A, TEMPH CJNE A, #00 , ADD22 MOV TEMPH,#100 ADD22: JB S4, TIAOTH
CLR C
RET
WR1:CLR P2.0
RE_CONFIG1:
NOP
MOV A,#0CCH
NOP
; 发SKIP ROM命令
NOP
LCALL WRITE_1820
NOP
MOV A,#4EH
RRC A
; 发写暂存存储器命令
MOV P2.0,C
LCALL WRITE_1820
MOV R3,#35
MOV A,#00H
; 重新写DS18B20暂存存储器设定值
; 写DS18B20的程序
********************************* ******************************
RE_CONFIG:JB 20H.1,RE_CONFIG1 WRITE_1820:MOV R2,#8
; 若DS18B20存在,转RE_CONFIG1
SIGN EQU 5BH S1 BIT P1.0 S2 BIT P1.1 S3 BIT P1.2
S4 BIT P1.3 ORG 0000H LJMP MAIN ORG 000BH LJMP TOIT ORG 0030H MAIN: MOV SP, #60H MOV TMOD, #01H MOV TH0, #3CH MOV TL0, #0B0H SETB ET0 SETB TR0 SETB EA MOV TEMPH, #30 MOV TEMPL, #9 MOV TEMPUTER, #15
温度值取补码置“—”标志
计算小数位温度BCD值
计算整数位温度BCD值 结束 置“+”标志 N Y
发DS18B20复位命令 发跳过ROM命令
发温度转换开始命令 结束
图3 温度转换流程图
图4 计算温度流程图
显示数据刷新子程序
显示数据刷新子程序主要是对显示缓冲器中的显示数据进行刷新操 作,当最高显示位为0时将符号显示位移入下一位。程序流程图如图5。
; 选择9位温度分辨率
; 读DS18B20的程序,从DS18B20中读
LCALL WRITE_1820
出两个字节的温度数据
RET
**********************************
;********************************
READ_18200:
; 读出转换后的温度值
MOV R4,#2
*********************************
; 将温度高位和低位DS18B20中读
GET_TEMPER:
RE00:MOV R2,#8
SETB P2.0 ; 定时入口
RE01:CLR C
L1,TSS2
Y 发DS18B20复位命令
发跳过ROM命令 发读取温度命令 读取操作,CRC校验 9字节完? CRC校验正?确?
移入温度暂存器 结束 N N Y 初始化 调用显示子程序 1S到? 初次上电
读出温度值温度计算处理显示数据刷新
发温度转换开始命令 N Y N Y
图1 主程序流程图 图2读温度流程图 开始 温度零下?
MOV S1OK, #1 MOV MS50, #00H RETURN:POP ACC POP PSW RETI ;******************************** ;温度总子程序 ********************************* wendu: ACALL INIT_1820 ACALL RE_CONFIG ACALL GET_TEMPER ACALL TEMPER_COV RET ;******************************** ;DS18B20初始化程序 ********************************* INIT_1820: SETB P2.0 NOP
TAB: DB 11H, 0D7H, 32H, 92H, 0D4H, 98H, 18H, 0D1H, 10H, 90H ,0FFH, 070H, 0FEH
; 延时子程序 T12MS: SETB RS1
JNB ACC.3,TEMPER_COV1 ; 四舍五入去温度值
INC 37H TEMPER_COV1: MOV A,35H
CJNE A, #1, START MOV A, TEMPUTER
SUBB A, TEMPH JNB ACC.7, ALEM MOV A, TEMPUTER SUBB A, TEMPL JB ACC.7, ALEM SETB P2.1 ACALL WENDU ACALL DISP MOV S1OK, #00H AJMP START ALEM: MOV 36H, #0CH MOV 37H, #0CH MOV 38H, #0CH CLR P2.1 ACALL DISP ACALL T1S LCALL WENDU LCALL DISP MOV S1OK, #00H SJMP START
ANL A,#07H SWAP A
ADD A,37H MOV 37H,A ; 保存变换后的温度数 据 LCALL BIN_BCD RET ********************************* ; 将16进制的温度数据转换成压缩 BCD码 ; 38H中放百位,37十位,36个位 ;******************************** BIN_BCD:MOV 39H,37H
MOV 37H, TEMPL ACALL BIN_BCD ACALL DISP ACALL T12MS ACALL T12MS ACALL T12MS ACALL T12MS MOV 36H, #0AH MOV 37H, #0AH MOV 38H, #0AH ACALL DISP ACALL T12MS ACALL T12MS ACALL T12MS ACALL T12MS JB S2, ADD1 ACALL T12MS JB S2, ADD1 JNB S2, $ INC TEMPL MOV A, TEMPL CJNE A, #100, ADD1 MOV TEMPL, #0 JB S4, TIAOTH JNB S4, $ MOV TEMPUTER, 50H LJMP START ; 一秒定时中段 ******************************** TOIT: PUSH PSW PUSH ACC MOV TH0, #3CH MOV TL0, #0B0H INC MS50 MOV A, MS50 CJNE A, #14H, RETURN
MOV 36H,B RET
DISP: SETB RS0 MOV R0, #36H MOV R7, #3
LOOPP:MOV A, @R0 MOV DPTR, #TAB MOVC A, @A+DPTR MOV SBUF, A JNB TI, $ CLR TI INC R0 DJNZ R7, LOOPP CLR RS0 RET
温度数据移入显示寄存器 十位数0? 百位数0? 十位数显示符号百位数不显示 百位数显示数据(不显示符号) 结束 N N Y Y
图5 显示数据刷新流程图
数字温度计程序清单:
S1OK EQU 5FH TEMPUTER EQU 39H
TEMPH EQU 5EH TEMPL EQU 5DH MS50 EQU 5CH