
亲测,更改端口即可使用。(主要器件:51单片机,ds18b20,lcd显示器)
附有proteus仿真图,及序列号采集程序
/****上限62度 下限-20度****/
#include #define uchar unsigned char #define uint unsigned int sbit ds=P1^1; sbit rs=P1^4; sbit e=P1^6; sbit sp=P1^0; sbit d1=P1^2; sbit d2=P1^3; uchar lcdrom[4][8]={{0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e}, {0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9}, {0x28,0x32,0xc5,0xb8,0x00,0x00,0x00,0xe0}, {0x28,0x33,0xc5,0xb8,0x00,0x00,0x00,0xd7}}; unsigned char code table0[]={"TEMPERARTURE:U "}; unsigned char code table1[]={"01234567ABCDEF"}; int f[4]; int tvalue; float ftvalue; uint warnl=320; uint warnh=992; /****lcd程序****/ void delayms(uint ms)//延时 { uint i,j; for(i=ms;i>0;i--) for(j=110;j>0;j--); } void wrcom(uchar com)//写指令 { delayms(1); rs=0; P3=com; delayms(1); e=1; delayms(1); e=0; } void wrdat(uchar dat)//写数据 { rs=1; e=0; P3=dat; delayms(5); e=1; delayms(5); e=0; } void lcdinit()//初始化lcd { delayms(15); wrcom(0x38);delayms(5); wrcom(0x0c);delayms(5); wrcom(0x06);delayms(5); wrcom(0x01);delayms(5); } void display(uchar *p)//显示 { while(*p!='\\0') { wrdat(*p); p++; delayms(1); } } displayinit()//初始化显示 { lcdinit(); wrcom(0x80); display(table0); } /****ds18b20程序****/ void dsrst()//ds18b20复位 { uint i; ds=0; i=103; while(i>0)i--; ds=1; i=4; while(i>0)i--; } bit dsrd0()//读一位数据 { uint i; bit dat; ds=0;i++; ds=1;i++;i++; dat=ds; i=8;while(i>0)i--; return(dat); } uchar dsrd()//读1个字节数据 { uchar i,j,dat; dat=0; for(i=8;i>0;i--) { j=dsrd0(); dat=(j<<7)|(dat>>1); } return(dat); } void dswr(uchar dat)//写数据 { uint i; uchar j; bit testb; for(j=8;j>0;j--) { testb=dat&0x01; dat=dat>>1; if(testb) { ds=0; i++;i++; ds=1; i=8;while(i>0)i--; } else { ds=0; i=8;while(i>0)i--; ds=1; i++;i++; } } } void tmstart()//初始化ds18b20 { sp=1; d1=1; d2=1; dsrst(); delayms(1); dswr(0xcc); dswr(0x44); } void read_dealtemp()//读取并处理温度 { uchar i,j,t; uchar a,b; for(j=0;j<4;j++) { dsrst(); delayms(1); dswr(0x55); for(i=0;i<8;i++) { dswr(lcdrom[j][i]);//发送位序列号 } dswr(0xbe); a=dsrd(); b=dsrd(); tvalue=b; tvalue<<=8; tvalue=tvalue|a; if(tvalue<0) { d1=1; tvalue=~tvalue+1; wrcom(0xc0); wrdat(0x2d); if(tvalue>warnl) { d2=0; sp=0; } else { d2=1; sp=1; } } else { d2=1; wrcom(0xc0); wrdat(' '); if(tvalue>warnh) { d1=0; sp=0; } else { d1=1; sp=1; } } if(j==0) { wrcom(0x8e); wrdat('2'); } if(j==1) { wrcom(0x8e); wrdat('3'); } if(j==2) { wrcom(0x8e); wrdat('4'); } if(j==3) { wrcom(0x8e); wrdat('5'); } ftvalue=tvalue*0.0625; tvalue=ftvalue*10+0.5; ftvalue=ftvalue+0.05; f[j]=tvalue;//温度扩大十倍,精确到一位小数 tvalue=f[j]; t=tvalue/1000; wrcom(0x80+0x41); wrdat(table1[t]);//显示百位 t=tvalue%1000/100; wrdat(table1[t]);//显示十位 t=tvalue%100/10; wrdat(table1[t]);//显示个位 wrdat(0x2e); //显示小数点儿 t=tvalue%10/1; wrdat(table1[t]);//显示小数位 delayms(5000); } } /****主函数****/ void main() { d1=1; d2=1; sp=1; displayinit();//初始化显示 while(1) { tmstart();//初始化 read_dealtemp();//读取温度 } } /****序列号读取程序****/ #include #define uchar unsigned char #define uint unsigned int sbit DQ = P1^1; //温度传感器信号线 sbit rs = P1^4; //LCD数据/命令选择端(H/L)位声明 sbit lcden = P1^6; //LCD使能信号端位声明 void delay(uint z); //延时函数 void DS18B20_Reset(void); //DQ18B20复位,初始化函数 bit DS18B20_Readbit(void); //读1位数据函数 uchar DS18B20_ReadByte(void); //读1个字节数据函数 void DS18B20_WriteByte(uchar dat); //向DQ18B20写一个字节数据函数 void LCD_WriteCom(uchar com); //1602液晶命令写入函数 void LCD_WriteData(uchar dat); //1602液晶数据写入函数 void LCD_Init(); //LCD初始化函数 void Display18B20Rom(char Rom); //显示18B20序列号函数 /**********************************************/ /* 主函数 */ /**********************************************/ void main() { uchar a,b,c,d,e,f,g,h; LCD_Init(); DS18B20_Reset(); delay(1); DS18B20_WriteByte(0x33); delay(1); a = DS18B20_ReadByte(); b = DS18B20_ReadByte(); c = DS18B20_ReadByte(); d = DS18B20_ReadByte(); e = DS18B20_ReadByte(); f = DS18B20_ReadByte(); g = DS18B20_ReadByte(); h = DS18B20_ReadByte(); LCD_WriteCom(0x80+0x40); Display18B20Rom(h); Display18B20Rom(g); Display18B20Rom(f); Display18B20Rom(e); Display18B20Rom(d); Display18B20Rom(c); Display18B20Rom(b); Display18B20Rom(a); while(1); } /***************************************************/ /* 延时函数:void delay() */ /* 功能:延时函数 */ /***************************************************/ void delay(uint z)//延时函数 { uint x,y; for( x = z; x > 0; x-- ) for( y = 110; y > 0; y-- ); } /***************************************************/ /* DS18B20函数:void DS18B20_Reset() */ /* 功能:复位18B20 */ /***************************************************/ void DS18B20_Reset(void)//DQ18B20复位,初始化函数 { uint i; DQ = 0; i = 103; while( i > 0 ) i--; DQ = 1; i = 4; while( i > 0 ) i--; } /***************************************************/ /* DS18B20函数:void DS18B20_Readbit() */ /* 功能:读1个字节数据函数 */ /***************************************************/ bit DS18B20_Readbit(void) //读1位数据函数 { uint i; bit dat; DQ = 0; i++; //i++起延时作用 DQ = 1; i++; i++; dat = DQ; i = 8; while( i > 0 )i--; return( dat ); } /***************************************************/ /* DS18B20函数:void DS18B20_ReadByte() */ /* 功能:读1个字节数据函数 */ /***************************************************/ uchar DS18B20_ReadByte(void) //读1个字节数据函数 { uchar i,j,dat; dat = 0; for( i = 1; i <= 8; i++ ) { j = DS18B20_Readbit(); dat = ( j << 7 ) | ( dat >> 1 ); } return(dat); } /***************************************************/ /* DS18B20函数:void DS18B20_WriteByte() */ /* 功能:向DQ18B20写一个字节数据函数 */ /***************************************************/ void DS18B20_WriteByte(uchar dat) //向DQ18B20写一个字节数据函数 { uint i; uchar j; bit testb; for( j=1; j<=8; j++) { testb = dat&0x01; dat= dat>>1; if(testb) //写1 { DQ = 0; i++;i++; DQ = 1; i = 8;while(i>0)i--; } else { DQ = 0; //写0 i = 8;while(i>0)i--; DQ = 1; i++;i++; } } } /***********************************************/ /* LCD函数:void LCD_WriteCom() */ /* 功能:向LCD写入命令 */ /***********************************************/ void LCD_WriteCom(uchar com) { rs = 0; P3= com; delay(5); lcden = 0; delay(5); lcden = 1; delay(5); lcden = 0; } /***********************************************/ /* LCD函数:void LCD_WriteData(uchar dat) */ /* 功能:向LCD写入数据 */ /***********************************************/ void LCD_WriteData(uchar dat) { rs = 1; //选择LCD为写入数据状态 lcden = 0; P3= dat; //将待写入数据放到总线上 delay(5); lcden = 1; //给LCD使能端一个脉冲 delay(5); //信号将之前放到总线上 lcden = 0; //的数据写入LCD delay(5); } /***********************************************/ /* LCD函数:void LCD_Init() */ /* 功能:初始化LCD,设定LCD的初始状态 */ /***********************************************/ void LCD_Init() { LCD_WriteCom(0x38); //LCD显示模式设定 delay(15); LCD_WriteCom(0x08); //关闭LCD显示 delay(3); LCD_WriteCom(0x01); //LCD显示清屏 delay(3); LCD_WriteCom(0x06); //设定光标地址指针为自动加1 delay(3); LCD_WriteCom(0x0c); //打开LCD显示,但不显示光标 } /**********************************************/ /* */ /* 显示18B20序列号 */ /* */ /**********************************************/ void Display18B20Rom(char Rom) { uchar h,l; l = Rom & 0x0f; //取低4位 h = Rom & 0xf0; //取高4位 h >>= 4; if( ( h >= 0x00 )&&( h <= 0x09 ) ) LCD_WriteData(h+0x30); //取ASCII码 else LCD_WriteData(h+0x37); //取ASCII码 if( ( l >= 0x00 )&&( l <= 0x09 ) ) LCD_WriteData(l+0x30); //取ASCII码 else LCD_WriteData(l+0x37); //取ASCII码 }
