数字温度计程序清单 汇编
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
数字温度计程序
#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[]={ //纵向字节倒序。
数字温度计设计汇编源程序
;================================================================ ;DS18B20温度计;采用4位LED共阳显示器显示测温值,显示精度0.1℃,测温范围-55~+125℃;用AT89C51单片机,12MHz晶振;DS1302时钟芯片实现日历年月日时分秒的显示;============================常数定义============================= TIMEL EQU 0E0H ;20ms,定时器0时间常数TIMEH EQU 0B1HSECOND EQU 30HMINUTE EQU 31HHOUR EQU 32HDAY EQU 33HMONTH EQU 34HWEEK EQU 35HYEAR EQU 36HTEMPHEAD EQU 38HTEMP_UPPER EQU 2AHTEMP_LOWER EQU 2BH;==========================工作内存定义============================ BITST DATA 20HTIME1SOK BIT BITST.1TEMPL DATA 26HTEMPH DATA 27HTEMPHC DATA 28HTEMPLC DATA 29H;============================= 引脚定义=========================== TEMPDIN B IT P3.7ALARMDIN BIT P1.6RST BIT P1.2CLK BIT P1.1IO BIT P1.0;============================= 中断向量区========================= ORG 0000HLJMP STARTORG 000BHLJMP T0IT;=============================系统初始化========================== ORG 0100HSTART: MOV SP,#60HCLSMEM: MOV R0,#20HMOV R1,#60HCLSMEM1: MOV @R0,#00HINC R0DJNZ R1,CLSMEM1MOV TMOD,#00010001B ;定时器0工作方式1(16BIT)MOV TH0,#TIMEHMOV TL0,#TIMEL ;20msMOV SECOND,#00HMOV MINUTE,#00HMOV HOUR,#14HMOV DAY,#17HMOV MONTH,#01HMOV WEEK,#01HMOV YEAR,#13HMOV TEMP_UPPER,#0AHMOV TEMP_LOWER,#8AHSETB ET0SETB EAMOV PSW,#00H;================================================================= ;============================= 主程序============================= ;=================================================================LCALL SETDS1302START1: LCALL R EAD_TEMP ;读出温度值子程序LCALL CONVTEMP ;温度BCD码计算处理子程序LCALL REFBCD ;显示区BCD码温度值刷新子程序LCALL GETDS1302SETB TR0LCALL ALARM_JUDGEJNB F0,MAINLCALL ALARM_BEEPMAIN: LCALL DISP_TEMP ;调用显示子程序LCALL DISPLAY_TIMEJNB TIME1SOK,MAINCLR TIME1SOK ;测温每1s一次MAIN1: LCALL DISP_TEMP ;调用显示子程序LCALL DISPLAY_DA TEJNB TIME1SOK,MAIN1CLR TIME1SOK ;测温每1s一次LJMP START1;====================== 定时器0中断服务程序=======================T0IT: PUSH PSWMOV PSW,#10HMOV TH0,#TIMEHMOV TL0,#TIMELINC R7CJNE R7,#50,T0IT1MOV R7,#00HSETB TIME1SOK ;1s定时到标志T0IT1: POP PSWRETI;================================================================= ;============================= 子程序区=========================== ;=================================================================;=============================初始化DS18B20======================= INITDS1820:SETB TEMPDINNOPNOPCLR TEMPDINMOV R6,#0A0HDJNZ R6,$MOV R6,#0A0HDJNZ R6,$SETB TEMPDINMOV R6,#32HDJNZ R6,$MOV R6,#3CHLOOP1820: MOV C,TEMPDINJC INITDS1820OUTDJNZ R6,LOOP1820MOV R6,#064HDJNZ R6,$SJMP INITDS1820INITDS1820OUT: SETB TEMPDINRET;====== 读DS18B20的程序,从DS18B20中读出一个字节的数据============= READDS1820: MOV R7,#08HSETB TEMPDINNOPNOPREADDS1820LOOP: CLR TEMPDINNOPNOPNOPSETB TEMPDINMOV R6,#07H ;DELAY 15usDJNZ R6,$MOV C,TEMPDINMOV R6,#3CH ;DELAY 120usDJNZ R6,$RRC ASETB TEMPDINDJNZ R7,READDS1820LOOPMOV R6,#3CH ;DELAY 120 usDJNZ R6,$RET;======== 写DS18B20的程序,从DS18B20中写一个字节的数据============= WRITEDS1820: MOV R7,#08HSETB TEMPDINNOPNOPWRITEDS1820LOP: CLR TEMPDINMOV R6,#07H ;DELAY 15usDJNZ R6,$RRC AMOV TEMPDIN,CMOV R6,#34H ;DELAY 104usDJNZ R6,$SETB TEMPDINDJNZ R7,WRITEDS1820LOPRET;========================= READ TEMP =========================== READ_TEMP: LCALL INITDS1820MOV A,#0CCHLCALL WRITEDS1820 ;SKIP ROMMOV R6,#34H ;DELAY 104usDJNZ R6,$MOV A,#44HLCALL WRITEDS1820 ;START CONVERSIONMOV R6,#34H ;DELAY 104DJNZ R6,$READTEMP1: LCALL INITDS1820MOV A,#0CCHLCALL WRITEDS1820 ;SKIP ROMMOV R6,#34H ;DELAY 104usDJNZ R6,$MOV A,#0BEHLCALL WRITEDS1820 ;SCRATCHPADMOV R6,#34H ;DELAY 104usDJNZ R6,$MOV R5,#09HMOV R0,#TEMPHEADMOV B,#00HREADTEMP2: LCALL READDS1820MOV @R0,AINC R0DJNZ R5,READTEMP2MOV A,TEMPHEAD+0MOV TEMPL,AMOV A,TEMPHEAD+1MOV TEMPH,AREADTEMPOUT: RET;================== 处理温度BCD码子程序========================== CONVTEMP: MOV A,TEMPHANL A,#80HJZ TEMPC1CLR CMOV A,TEMPLCPL AADD A,#01HMOV TEMPL,AMOV A,TEMPH ;-CPL AADDC A,#00HMOV TEMPH,A ;TEMPHC HI=符号位MOV TEMPHC,#0BHSJMP TEMPC11TEMPC1: MOV TEMPHC,#0AH ;+TEMPC11: MOV A,TEMPHCSWAP AMOV TEMPHC,AMOV A,TEMPLANL A,#0FH ;乘0.0625MOV DPTR,#TEMPDOTTABMOVC A,@A+DPTRMOV TEMPLC,A ;TEMPLC LOW=小数部分BCDMOV A,TEMPL ;整数部分ANL A,#0F0HSWAP AMOV TEMPL,AMOV A,TEMPHANL A,#0FHSWAP AORL A,TEMPLLCALL HEX2BCD1MOV TEMPL,AANL A,#0F0HSWAP AORL A,TEMPHC ;TEMPHC LOW=十位数BCDMOV TEMPHC,AMOV A,TEMPLANL A,#0FHSWAP A ;TEMPLC HI=个位数BCDORL A,TEMPLCMOV TEMPLC,AMOV A,R7JZ TEMPC12ANL A,#0FHSWAP AMOV R7,AMOV A,TEMPHC ;TEMPLC HI=百位数BCDANL A,#0FHORL A,R7MOV TEMPHC,ATEMPC12: RET;========================= 小数部分码表=========================== TEMPDOTTAB: DB 00H,01H,01H,02H,03H,03H,04H,04H,05H,06HDB 06H,07H,08H,08H,09H,09H;====================== 刷新BCD码温度值子程序=============== REFBCD: MOV A,TEMPLCANL A,#0FHMOV 70H,AMOV A,TEMPLCSWAP AANL A,#0FHMOV 71H,AMOV A,TEMPHCANL A,#0FHMOV 72H,AMOV A,TEMPHCSWAP AANL A,#0FHMOV 73H,AMOV A,TEMPHCANL A,#0F0HCJNE A,#010H,REFBCD0SJMP REFBCD2REFBCD0: MOV A,TEMPHCANL A,#0FHJNZ REFBCD2 ;十位数是0MOV A,TEMPHCSWAP AANL A,#0FHMOV 73H,#0AH ;符号位不显示MOV 72H,A ;十位数显示符号REFBCD2: RET;======================= 即时温度显示子程序===============================;显示数据在70H~73H单元内,用4位LED共阳数码管显示,P0口输出段码数据,;P3口做扫描控制,每个LED数码管亮1ms时间再逐位循环。
数字温度计论文 C语言+汇编语言
前言温度的测量对人类日常生活、工业生产、气象预报、物资仓储等都起着极其重要的作用,因此研究温度的测量方法和装置具有重要的意义。
近年来,温度检测领域发展迅速,并且随着数字技术的发展,温度的测控芯片也相应的登上历史的舞台,能够在工业、农业等各个领域中广泛使用。
温度的测量的关键之处是温度传感器,其往往决定着一个温度检测系统的性能。
传统的温度检测以热敏电阻和AD590为温度敏感元件。
热敏电阻虽成本低,但需信号处理电路,电路复杂,可靠性较低,测温准确度及抗干扰能力也有一定的不足。
近年来,传感器正处于传统型向新型传感器转型的发展阶段。
新型的温度传感器的特点是微型化、数字化、智能化、多功能化、系统化、网络化,它提高了抗干扰能力和可靠性,而且使系统结构更简洁,维护方便,缩小了空间。
单片机具有集成度高、功能强、体积小、价格低、抗干扰能力等优于一般CPU的优点,因此往往采用单片机作为数字控制器取代模拟控制器。
温度控制系统在国内各行各业的应用虽然已经十分广泛,但从国内生产的温度控制器来讲,总体发展水平仍然不高,同日本、美国、德国等先进国家相比,仍然有着较大的差距。
成熟的温控产品主要以“点位”控制及常规的PID控制器为主,它们只能适应一般温度系统控制,而用于较高控制场合的智能化、自适应控制仪表,国内技术还不十分成熟,形成商品化并广泛应用的控制仪表较少。
随着我国经济的发展及加入WTO,我国政府及企业对此都非常重视,对相关企业资源进行了重组,相继建立了一些国家、企业的研发中心,开展创新性研究,使我国仪表工业得到了迅速的发展。
[关键字]AT89C52、DS28B20温度传感器目录正文 (1)1 设计目的及意义 (1)1.1 设计意义 (1)1.2设计目的 (1)2 目标与总体方案 (1)2.1设计目标 (1)2.2设计总体方案 (2)3 设计方法与内容 (2)3.1 系统组成 (2)3.2 AT89C52简介 (3)3.3 DS18B20温度传感器简介 (7)4 程序流程设计 (12)4.1 主程序 (12)4.2 DS18B20 复位子程序 (13)4.3 读温度子程序 (13)4.4 写DS18B20命令子程序 (14)4.5 数据处理子程序 (14)结论 (15)参考文献 (15)附录一 (16)附录二 (19)正文1 设计目的及意义1.1 设计意义随着新技术的不断开发与应用,近年来单片机发展十分迅速,一个以微机应用为主的新技术革命浪潮正在蓬勃兴起,单片机的应用已经渗透到电力、冶金、化工、建材、机械、食品、石油等各个行业。
