㈠ 求用51单片机与DS18B20测温的C程序。完整的。
/*************** writer:shopping.w ******************/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}
sbit DQ = P3^3;
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
uchar code Temp_Disp_Title[]={"Current Temp : "};
uchar Current_Temp_Display_Buffer[]={" TEMP: "};
uchar code Temperature_Char[8] =
{
0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00
};
uchar code df_Table[]=
{
0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9
};
uchar CurrentT = 0;
uchar Temp_Value[]={0x00,0x00};
uchar Display_Digit[]={0,0,0,0};
bit DS18B20_IS_OK = 1;
void DelayXus(uint x)
{
uchar i;
while(x--)
{
for(i=0;i<200;i++);
}
}
bit LCD_Busy_Check()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN=0;
return result;
}
void Write_LCD_Command(uchar cmd)
{
while(LCD_Busy_Check());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
void Write_LCD_Data(uchar dat)
{
while(LCD_Busy_Check());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
void LCD_Initialise()
{
Write_LCD_Command(0x01);
DelayXus(5);
Write_LCD_Command(0x38);
DelayXus(5);
Write_LCD_Command(0x0c);
DelayXus(5);
Write_LCD_Command(0x06);
DelayXus(5);
}
void Set_LCD_POS(uchar pos)
{
Write_LCD_Command(pos|0x80);
}
void Delay(uint x)
{
while(--x);
}
uchar Init_DS18B20()
{
uchar status;
DQ = 1;
Delay(8);
DQ = 0;
Delay(90);
DQ = 1;
Delay(8);
DQ = 1;
return status;
}
uchar ReadOneByte()
{
uchar i,dat=0;
DQ = 1;
_nop_();
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
_nop_();
_nop_();
if(DQ)
dat |= 0X80;
Delay(30);
DQ = 1;
}
return dat;
}
void WriteOneByte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat& 0x01;
Delay(5);
DQ = 1;
dat >>= 1;
}
}
void Read_Temperature()
{
if(Init_DS18B20()==1)
DS18B20_IS_OK=0;
else
{
WriteOneByte(0xcc);
WriteOneByte(0x44);
Init_DS18B20();
WriteOneByte(0xcc);
WriteOneByte(0xbe);
Temp_Value[0] = ReadOneByte();
Temp_Value[1] = ReadOneByte();
DS18B20_IS_OK=1;
}
}
void Display_Temperature()
{
uchar i;
uchar t = 150, ng = 0;
if((Temp_Value[1]&0xf8)==0xf8)
{
Temp_Value[1] = ~Temp_Value[1];
Temp_Value[0] = ~Temp_Value[0]+1;
if(Temp_Value[0]==0x00)
Temp_Value[1]++;
ng = 1;
}
Display_Digit[0] = df_Table[Temp_Value[0]&0x0f];
CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4);
Display_Digit[3] = CurrentT/100;
Display_Digit[2] = CurrentT%100/10;
Display_Digit[1] = CurrentT%10;
Current_Temp_Display_Buffer[11] = Display_Digit[0] + '0';
Current_Temp_Display_Buffer[10] = '.';
Current_Temp_Display_Buffer[9] = Display_Digit[1] + '0';
Current_Temp_Display_Buffer[8] = Display_Digit[2] + '0';
Current_Temp_Display_Buffer[7] = Display_Digit[3] + '0';
if(Display_Digit[3] == 0)
Current_Temp_Display_Buffer[7] = ' ';
if(Display_Digit[2] == 0&&Display_Digit[3]==0)
Current_Temp_Display_Buffer[8] = ' ';
if(ng)
{
if(Current_Temp_Display_Buffer[8] == ' ')
Current_Temp_Display_Buffer[8] = '-';
else if(Current_Temp_Display_Buffer[7] == ' ')
Current_Temp_Display_Buffer[7] = '-';
else
Current_Temp_Display_Buffer[6] = '-';
}
Set_LCD_POS(0x00);
for(i=0;i<16;i++)
{
Write_LCD_Data(Temp_Disp_Title[i]);
}
Set_LCD_POS(0x40);
for(i=0;i<16;i++)
{
Write_LCD_Data(Current_Temp_Display_Buffer[i]);
}
Set_LCD_POS(0x4d);
Write_LCD_Data(0x00);
Set_LCD_POS(0x4e);
Write_LCD_Data('C');
}
void main()
{
LCD_Initialise();
Read_Temperature();
Delay(50000);
Delay(50000);
while(1)
{
Read_Temperature();
if(DS18B20_IS_OK)
Display_Temperature();
DelayXus(100);
}
}
以上程序来自《单片机C语言程序设计实训100例基于8051+Proteus仿真》
㈡ 51单片机两个I/O口分别接ds18b20程序
//DS从机程序
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define SLAVE 0x01
#define BN 6
sbit LCD_RS = P2^5; /*定义LCD控制端口*/
sbit LCD_RW = P2^6;
sbit LCD_EN = P2^7;
sbit DS1=P1^0;
sbit DS2=P1^1;
sbit key3=P3^5;
sbit tem=P3^3;
sbit win=P3^4;
sbit key1=P3^6;
sbit key2=P3^7;
uint temp1,temp2,tempH,tempL; // variable of temperature
uchar flag1,aa,we;
uchar A1,A2,A3,A4,B1,B2,B3,B4; // sign of the result positive or negative
uchar dis1[16]={76,45,84,'0','0','.','0',32,32,72,45,84,'0','0','.','0'};
uchar dis2[16]={48,49,32,'0','0','.','0',32,32,48,50,32,'0','0','.','0'};
uchar code tab[] = {'0','1','2','3','4','5','6','7','8','9'};
uchar trbuf[6];
bit tready;
bit rready;
void str(void);
void sre(void);
void delay(int ms)
{
int i;
while(ms--)
{
for(i = 0; i< 250; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/*******************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/*******************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0&0x80);
LCD_EN = 0;
return result;
}
/*******************************************************************/
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/* */
/*******************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/* */
/*******************************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/* 设定显示位置 */
/* */
/*******************************************************************/
void lcd_pos(uchar pos)
{
lcd_wcmd(pos|0x80); //数据指针=80+地址变量
}
/*******************************************************************/
/* */
/* LCD初始化设定 */
/* */
/*******************************************************************/
void lcd_init()
{
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x0c); //显示开,关光标
delay(5);
lcd_wcmd(0x06); //移动光标
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
lcd_wcmd(0x06); //向右移动光标
delay(5);
}
/*******************************************************************/
/* */
/* 闪动子程序 */
/* */
/*******************************************************************/
void flash()
{
delay(600); //控制停留时间
lcd_wcmd(0x08); //关闭显示
delay(200); //延时
lcd_wcmd(0x0c); //开显示
delay(200); //延时
lcd_wcmd(0x08); //关闭显示
delay(200); //延时
lcd_wcmd(0x0c); //开显示
delay(200);
}
/*void delay(uint count) //delay
{
uint i;
while(count)
{
i=100;
while(i>0)
i--;
count--;
}
} */
///////功能:串口初始化,波特率9600,方式1///////
void Init(void)
{
TMOD=0x20;
TL1=0xfd;
TH1=0xfd;
PCON=0x00;
TR1=1;
SCON=0xf0;
ES=1;
EA=1;
}
void dsreset(uchar DS) //send reset and initialization command 18B20复位,初始化函数
{
uint i;
if(DS==1)
{
DS1=0;
i=103;
while(i>0)i--;
DS1=1;
i=4;
while(i>0)i--;
}
if(DS==2)
{
DS2=0;
i=103;
while(i>0)i--;
DS2=1;
i=4;
while(i>0)i--;
}
}
bit tmpreadbit(uchar DS) //read a bit 读DS2 1位数据函数
{
uint i;
bit dat;
if(DS==1)
{
DS1=0;i++; //i++ for delay
DS1=1;i++;i++;
dat=DS1;
i=8;while(i>0)i--;
}
if(DS==2)
{
DS2=0;i++; //i++ for delay
DS2=1;i++;i++;
dat=DS2;
i=8;while(i>0)i--;
}
return (dat);
}
uchar tmpread(uchar DS) //read a byte date 读1字节函数
{
uchar i,j,dat;
dat=0;
if(DS==1)
{
for(i=1;i<=8;i++)
{
j=tmpreadbit(1);
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
}
if(DS==2)
{
for(i=1;i<=8;i++)
{
j=tmpreadbit(2);
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
}
return(dat);
}
void tmpwritebyte(uchar dat,uchar DS) //write a byte to ds18b20 向1820写一个字节数据函数
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(DS==1)
{
if(testb) //write 1
{
DS1=0;
i++;i++;
DS1=1;
i=8;while(i>0)i--;
}
else
{
DS1=0; //write 0
i=8;while(i>0)i--;
DS1=1;
i++;i++;
}
}
if(DS==2)
{
if(testb) //write 1
{
DS2=0;
i++;i++;
DS2=1;
i=8;while(i>0)i--;
}
else
{
DS2=0; //write 0
i=8;while(i>0)i--;
DS2=1;
i++;i++;
}
}
}
}
void tmpchange(uchar DS) //DS18B20 begin change 开始获取数据并转换
{
if(DS==1)
{
dsreset(1);
delay(1);
tmpwritebyte(0xcc,1); // address all drivers on bus 写跳过读ROM指令
tmpwritebyte(0x44,1);
} // initiates a single temperature conversion 写温度转换指令
if(DS==2)
{
dsreset(2);
delay(1);
tmpwritebyte(0xcc,2); // address all drivers on bus 写跳过读ROM指令
tmpwritebyte(0x44,2);
} // initiates a single temperature conversion 写温度转换指令
}
uint tmp1(void) //get the temperature 读取寄存器中存储的温度数据
{
float tt;
uchar a,b;
dsreset(1);
delay(1);
tmpwritebyte(0xcc,1);
tmpwritebyte(0xbe,1);
a=tmpread(1); //读低8位
b=tmpread(1); //读高8位
temp1=b;
temp1<<=8; //two byte compose a int variable 两个字节组合为1个字
temp1=temp1|a;
tt=temp1*0.0625; //温度在寄存器中是12位,分辨率是0.0625
temp1=tt*10+0.5; //乘10表示小数点后只取1位,加0.5是四折五入
//temp1=temp1+5; //误差补偿
return temp1;
}
uint tmp2( void) //get the temperature 读取寄存器中存储的温度数据
{
float tt;
uchar a,b;
dsreset(2);
delay(1);
tmpwritebyte(0xcc,2);
tmpwritebyte(0xbe,2);
a=tmpread(2); //读低8位
b=tmpread(2); //读高8位
temp2=b;
temp2<<=8; //two byte compose a int variable 两个字节组合为1个字
temp2=temp2|a;
tt=temp2*0.0625; //温度在寄存器中是12位,分辨率是0.0625
temp2=tt*10+0.5; //乘10表示小数点后只取1位,加0.5是四折五入
//temp2=temp2+5; //误差补偿
return temp2;
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
uchar display(uint temp1,uint temp2) //显示程序
{
uchar i;
A1=temp1/100;
A2=temp1%100/10;
A3=temp1%100%10;
B1=temp2/100;
B2=temp2%100/10;
B3=temp2%100%10;
trbuf[0]=A1;
trbuf[1]=A2;
trbuf[2]=A3;
trbuf[3]=B1;
trbuf[4]=B2;
trbuf[5]=B3;
dis1[3]=tab[tempL*10/100];
dis1[4]=tab[tempL*10%100/10];
dis1[6]=tab[tempL*10%100%10];
dis1[12]=tab[tempH*10/100];
dis1[13]=tab[tempH*10%100/10];
dis1[15]=tab[tempH*10%100%10];
dis2[3]=tab[A1];
dis2[4]=tab[A2];
dis2[6]=tab[A3];
dis2[12]=tab[B1];
dis2[13]=tab[B2];
dis2[15]=tab[B3];
delay(1);
lcd_pos(0); //设置显示位置为第一行的第1个字符
delay(2);
for(i=0;i<16;i++)
{
lcd_wdat(dis1[i]);
}
delay(2);
lcd_pos(0x40);
delay(2);
for(i=0;i<16;i++)
{
lcd_wdat(dis2[i]);
}
return (A1,A2,A3,B1,B2,B3);
}
void TemC()
{
if(temp1<=(tempL*10)||temp2<=(tempL*10)) tem=0;
else tem=1;
if (temp1>=(tempH*10)||temp2>=(tempH*10)) win=0;
else win=1;
}
uchar chan()
{
if(key1==0)
{
tempL++;
while(key1==0);
if(tempL>35)
tempL=0;
}
if(key2==0)
{
tempH++;
while(key2==0);
if(tempH>35)
tempH=0;
}
return (tempH,tempL);
}
/******************************************************************************/
void main()
{ //uchar a;
//uchar i;
delay(10);
lcd_init();
Init();
tempH=35;
tempL=15;
while(1)
{
tmpchange(1);
tmpchange(2);
tmp1();
tmp2();
chan();
TemC();
display(temp1,temp2);
tready=1;
rready=1;
}
}
void ssio(void)interrupt 4
{
uchar a;
RI=0;
ES=0;
if(SBUF!=SLAVE)
{
ES=1;
goto reti;
}
SM2=0;
SBUF=SLAVE;
while(TI!=1);
TI=0;
while(RI!=1);
RI=0;
if(RB8==1)
{
SM2=1;
ES=1;
goto reti;
}
a=SBUF;
if(a==0x02)
{
if(tready==1)
SBUF=0x02;
else
SBUF=0x00;
while(TI!=1);
TI=0;
str();
goto reti;
}
else
{
SBUF=0x08;
while(TI!=1);
TI=0;
SM2=1;
ES=1;
}
reti:RI=0;
SM2=1;
ES=1;
}
void str(void)
{
uchar i;
tready=0;
while(1)
{
tmpchange(1);
tmpchange(2);
tmp1();
tmp2();
chan();
TemC();
display(temp1,temp2);
for(i=0;i<BN;i++)
{
SBUF=trbuf[i];
while(TI!=1);
TI=0;
}
while(RI!=1);
RI=0;
if(RB8==1)goto loop;
}
loop:SM2=1;
ES=1;
}
㈢ 真的很急!基于51单片机的DS18B20 温度测控系统 C语言程序
#include<reg52.h> #include<math.h>
#include<INTRINS.H>
#define uchar unsigned char
#define uint unsigned int;
/******************************************************************/
/* 定义端口 */
/******************************************************************/
sbit seg1=P2^0;
sbit seg2=P2^1;
sbit seg3=P2^2;
sbit DQ=P1^7;//ds18b20 端口
sfr dataled=0x80;//显示数据端口
/******************************************************************/
/* 全局变量 */
/******************************************************************/
uint temp;
uchar flag_get,count,num,minute,second;
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//7段数码管段码表共阳
uchar str[6];
/******************************************************************/
/* 函数声明 */
/******************************************************************/
void delay1(uchar MS);
unsigned int ReadTemperature(void);
void Init_DS18B20(void);
unsigned char ReadOneChar(void);
void WriteOneChar(unsigned char dat);
void delay(unsigned int i);
/******************************************************************/
/* 主函数 */
/******************************************************************/
main()
{
unsigned char TempH,TempL;
TMOD|=0x01;//定时器设置
TH0=0xef;
TL0=0xf0;
IE=0x82;
TR0=1;
P2=0x00;
count=0;
while(1)
{
str[5]=0x39; //显示C符号
str[1]=tab[TempH/100]; //十位温度
str[2]=tab[(TempH%100)/10]; //十位温度
str[3]=tab[(TempH%100)%10]|0x80; //个位温度,带小数点
str[4]=tab[TempL];
if(flag_get==1) //定时读取当前温度
{
temp=ReadTemperature();
if(temp&0x8000)
{
str[0]=0x40;//负号标志
temp=~temp; // 取反加1
temp +=1;
}
else
str[0]=0;
TempH=temp>>4;
TempL=temp&0x0F;
TempL=TempL*6/10;//小数近似处理
flag_get=0;
}
}
}
/******************************************************************/
/* 定时器中断 */
/******************************************************************/
void tim(void) interrupt 1 using 1//中断,用于数码管扫描和温度检测间隔
{
TH0=0xef;//定时器重装值
TL0=0xf0;
num++;
if (num==50)
{num=0;
flag_get=1;//标志位有效
second++;
if(second>=60)
{second=0;
minute++;
}
}
count++;
if(count==1)
{P2=0;
dataled=str[0];}//数码管扫描
if(count==2)
{P2=1;
dataled=str[1];}
if(count==3)
{ P2=2;
dataled=str[2];
}
if(count==4)
{ P2=3;
dataled=str[3];
}
if(count==5)
{ P2=4;
dataled=str[4];
}
if(count==6)
{ P2=5;
dataled=str[5];
count=0;}
}
/******************************************************************/
/* 延时函数 */
/******************************************************************/
void delay(unsigned int i)//延时函数
{
while(i--);
}
/******************************************************************/
/* 初始化 */
/******************************************************************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay(10);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(5);
}
/******************************************************************/
/* 读一个字节 */
/******************************************************************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay(5);
}
return(dat);
}
/******************************************************************/
/* 写一个字节 */
/******************************************************************/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
delay(5);
}
/******************************************************************/
/* 读取温度 */
/******************************************************************/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned int b=0;
unsigned int t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay(200);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //低位
b=ReadOneChar(); //高位
b<<=8;
t=a+b;
return(t);
}
//LZ,这是测温并且用数码管显示程序,报警可以自己另行添加!主要程序就是这些!
()
继
㈣ 51单片机与DS18B20程序
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P2^2; //数据口define interface
sbit la = P2^6; //数码管段选
sbit wela = P2^7; //数码管位选
uint temp; //温度值 variable of temperature
//不带小数点
unsigned char code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//带小数点
unsigned char code table1[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
/*************精确延时函数*****************/
void delay(unsigned char i)
{
while(--i);
}
/******************************************
此延时函数针对的是12Mhz的晶振
delay(0):延时518us 误差:518-2*256=6
delay(1):延时7us (原帖写"5us"是错的)
delay(10):延时25us 误差:25-20=5
delay(20):延时45us 误差:45-40=5
delay(100):延时205us 误差:205-200=5
delay(200):延时405us 误差:405-400=5
*******************************************/
/*****************DS18B20******************/
void Init_Ds18b20(void) //DS18B20初始化send reset and initialization command
{
DQ = 1; //DQ复位,不要也可行。
delay(1); //稍做延时
DQ = 0; //单片机拉低总线
delay(250); //精确延时,维持至少480us
DQ = 1; //释放总线,即拉高了总线
delay(100); //此处延时有足够,确保能让DS18B20发出存在脉冲。
}
uchar Read_One_Byte() //读取一个字节的数据read a byte date
//读数据时,数据以字节的最低有效位先从总线移出
{
uchar i = 0;
uchar dat = 0;
for(i=8;i>0;i--)
{
DQ = 0; //将总线拉低,要在1us之后释放总线
//单片机要在此下降沿后的15us内读数据才会有效。
_nop_(); //至少维持了1us,表示读时序开始
dat >>= 1; //让从总线上读到的位数据,依次从高位移动到低位。
DQ = 1; //释放总线,此后DS18B20会控制总线,把数据传输到总线上
delay(1); //延时7us,此处参照推荐的读时序图,尽量把控制器采样时间放到读时序后的15us内的最后部分
if(DQ) //控制器进行采样
{
dat |= 0x80; //若总线为1,即DQ为1,那就把dat的最高位置1;若为0,则不进行处理,保持为0
}
delay(10); //此延时不能少,确保读时序的长度60us。
}
return (dat);
}
void Write_One_Byte(uchar dat)
{
uchar i = 0;
for(i=8;i>0;i--)
{
DQ = 0; //拉低总线
_nop_(); //至少维持了1us,表示写时序(包括写0时序或写1时序)开始
DQ = dat&0x01; //从字节的最低位开始传输
//指令dat的最低位赋予给总线,必须在拉低总线后的15us内,
//因为15us后DS18B20会对总线采样。
delay(10); //必须让写时序持续至少60us
DQ = 1; //写完后,必须释放总线,
dat >>= 1;
delay(1);
}
}
uint Get_Tmp() //获取温度get the temperature
{
float tt;
uchar a,b;
Init_Ds18b20(); //初始化
Write_One_Byte(0xcc); //忽略ROM指令
Write_One_Byte(0x44); //温度转换指令
Init_Ds18b20(); //初始化
Write_One_Byte(0xcc); //忽略ROM指令
Write_One_Byte(0xbe); //读暂存器指令
a = Read_One_Byte(); //读取到的第一个字节为温度LSB
b = Read_One_Byte(); //读取到的第一个字节为温度MSB
temp = b; //先把高八位有效数据赋于temp
temp <<= 8; //把以上8位数据从temp低八位移到高八位
temp = temp|a; //两字节合成一个整型变量
tt = temp*0.0625; //得到真实十进制温度值
//因为DS18B20可以精确到0.0625度
//所以读回数据的最低位代表的是0.0625度
temp = tt*10+0.5; //放大十倍
//这样做的目的将小数点后第一位也转换为可显示数字
//同时进行一个四舍五入操作。
return temp;
}
/****************数码码动态显示函数**************/
void Display(uint temp) //显示程序
{
uchar A1,A2,A3;
A1 = temp/100; //百位
A2 = temp%100/10; //十位
A3 = temp%10; //个位
la = 0;
P0 = table[A1]; //显示百位
la = 1; //打开段选,对应74573的锁存位,高电平不锁存
la = 0;
wela = 0;
P0 = 0x7e;
wela = 1; //打开位选
wela = 0;
delay(0);
la = 0;
P0 = table1[A2]; //显示十位,使用的是有小数点的数组(因为temp值扩大了10倍,虽然是十位,实际为个位)
la = 1;
la = 0;
wela = 0;
P0 = 0x7d;
wela = 1;
wela = 0;
delay(0);
P0 = table[A3]; //显示个位
la = 1;
la = 0;
P0 = 0x7b;
wela = 1;
wela = 0;
delay(0);
}
void main()
{
while(1)
{
Display(Get_Tmp());
}
}
㈤ 单片机51用DS18B20采集温度的程序和图
#include <intrins.h>
#include "delay.h"
sbit DS18B20 = P0^4;
bit isExternPower;
bit Init_DS18B20(void)
{
bit RstFlag;
bit EA_Save = EA;
RstFlag = 0;
DS18B20 = 0;
delay_us(500); //拉低总线至少480us完成复位
EA = 0;
DS18B20=1;
delay_us(60); //释放总线15us-60us后读取应答电平
if (DS18B20==0) RstFlag = 1;
EA = EA_Save;
delay_us(440);
return RstFlag;
}
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
bit EA_Save = EA;
DS18B20=1;
delay_us(1);
for (i=8; i>0; i--)
{
EA = 0;
DS18B20 = 0; //拉低总线启动操作
delay_us(10); //总线拉低后15us内置数据电平
DS18B20 = dat&0x01;
delay_us(50); //总线拉低后60us内释放总线
DS18B20 = 1;
EA = EA_Save;
dat>>=1;
delay_us(3); //写时隙间隔>1us
}
}
unsigned char Read_DS18B20(void)
{
unsigned char i=0;
unsigned char dat = 0;
bit EA_Save = EA;
DS18B20=1;
delay_us(1);
for (i=8; i>0; i--)
{
EA = 0;
DS18B20 = 0; //拉低总线启动操作
delay_us(5);
DS18B20 = 1; //拉低总线至少1us后释放总线
delay_us(5); //等待总线稳定
dat >>= 1;
if(DS18B20)
{
dat+=0x80; //在拉低总线的15us内读总线电平
}
EA = EA_Save;
delay_us(50); //总的读时隙要在60us以上
}
return(dat);
}
float get_temperature()
{
unsigned char a=0;
unsigned char b=0;
int temperature;
float temp = 0.1;
if(Init_DS18B20())
{
Write_DS18B20(0xcc); //跳过ROM
Write_DS18B20(0xbe); //读温度寄存器
a=Read_DS18B20(); //读低8位
b=Read_DS18B20(); //读高8位
temperature = b<<8;
temperature |= a;
temp = temperature * 0.0625;
}
if(Init_DS18B20())
{
Write_DS18B20(0xcc); //跳过ROM
Write_DS18B20(0x44); //启动转换
}
return temp;
}
㈥ 51单片机温度传感器ds18b20、lcd1602液晶C程序
/*
必要操作:连接传感器DS18B20到U6
*/
#pragma db code
#include<AT89X52.H>
#include "INTRINS.H"
#define BUSY1 (DQ1==0) //定义busy信号
sbit LED_0=P1^0; //定义数码管控制脚为P1口的0-3脚
sbit LED_1=P1^1;
sbit LED_2=P1^2;
sbit LED_3=P1^3;
sbit DQ1=P3^5; //定义18B20单总线引脚
void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4);//声明显示函数
void ds_reset_1(void); //声明18B20复位函数
void wr_ds18_1(char dat); //声明18B20写入函数
void time_delay(unsigned char time);//声明延时函数
int get_temp_1(void); //声明18B20读入温度函数
void delay(unsigned int x); //声明延时函数
void read_ROM(void); //声明18B20读ROM函数
int get_temp_d(void); //声明获取温度函数
void ds_init(void); //声明18B20初始化函数
void ds_getT(void); //声明18B20获得温度显示值函数
/*定义数码管段码=====0-9=====A-G=====*/
unsigned char a[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//共阳极数码管的段码0 1 2 3 4 5 6 7 8 9 A B C D E F
/****************以下定义各种变量********************/
unsigned char ResultSignal;
int ResultTemperatureLH,ResultTemperatureLL,ResultTemperatureH;
unsigned char ROM[8];
unsigned char idata TMP;
unsigned char idata TMP_d;
unsigned char f;
unsigned char rd_ds18_1();
unsigned int TemH,TemL; //温度的整数部分和小数部分
unsigned int count; //定义小数计算部分
void main()
{
ds_init(); //18B20初始化
while(1)
{
ds_getT(); //使用该函数获得温度,整数部分存储到TemH,小数部分存储到count的低8位
display((TemH/10)%10,TemH%10,((count/10)%10),(count%10));
//温度发送到数码管显示
}
}
/***************18B20初始化函数***********************/
void ds_init(void)
{
unsigned int k=0;
ds_reset_1();
ds_reset_1(); //reset
wr_ds18_1(0xcc); //skip rom
_nop_();
wr_ds18_1(0x7f);
ds_reset_1();
wr_ds18_1(0xcc);
_nop_();
wr_ds18_1(0x44);
for(k=0;k<11000;k++)
time_delay(255);
ds_reset_1();
}
void ds_getT(void)
{
wr_ds18_1(0xcc);
wr_ds18_1(0xbe);
TemH=get_temp_1();
TemL=get_temp_d();
TemH&=0x00ff;
TemL&=0x00ff;
count=(TemH*256+TemL)*6.25;
}
/***************延时程序,单位us,大于10us*************/
void time_delay(unsigned char time)
{
time=time-10;
time=time/6;
while(time!=0)time--;
}
/*****************************************************/
/* reset ds18b20 */
/*****************************************************/
void ds_reset_1(void)
{
unsigned char idata count=0;
DQ1=0;
time_delay(240);
time_delay(240);
DQ1=1;
return;
}
void check_pre_1(void)
{
while(DQ1);
while(~DQ1);
time_delay(30);
}
void read_ROM(void)
{
int n;
ds_reset_1();
check_pre_1();
wr_ds18_1(0x33);
for(n=0;n<8;n++){ROM[n]=rd_ds18_1();}
}
/*****************************************************/
/* Read a bit from 1820 位读取 */
/*****************************************************/
bit tmrbit_1(void)
{
idata char i=0;
bit dat;
DQ1=0;_nop_();
DQ1=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
dat = DQ1;
time_delay(50);
return dat;
}
/*****************************************************/
/* read a bety from ds18b20 字节读取 */
/*****************************************************/
unsigned char rd_ds18_1()
{
unsigned char idata i,j,dat=0;
for(i=1;i<=8;i++)
{
j=tmrbit_1();
dat=(j<<(i-1))|dat;
}
return dat;
}
/*****************************************************/
/* write a bety from ds18b20 写字节 */
/****************************************************/
void wr_ds18_1(char dat)
{
signed char idata i=0;
unsigned char idata j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat & 0x01;
dat = dat>>1;
if(testb)
{
DQ1=0;
_nop_();
_nop_();
DQ1=1;
time_delay(60);
}
else
{
DQ1=0;
time_delay(50);
DQ1=1;
_nop_();
_nop_();
}
}
}
int get_temp_1(void)
{
unsigned char idata a=0,b=0;
unsigned char idata i;
EA=0;
ds_reset_1();
check_pre_1();
wr_ds18_1(0xcc);
wr_ds18_1(0x44);
while(BUSY1);
ds_reset_1();
check_pre_1();
wr_ds18_1(0xcc);
wr_ds18_1(0xbe);
a=rd_ds18_1();
b=rd_ds18_1();
i=b; /*若b为1则为负温 */
i=(i>>4);
if(i==0)
{
f=0;
TMP=((a>>4)|(b<<4));
a=(a&0x0f);
if (a>8)
{
TMP=(TMP+1);
}
}
else
{
f=1;
a=a>>4;
b=b<<4;
TMP=(a|b);
TMP=~TMP;
TMP=(TMP+1);
}
EA=1;
return(TMP);
}
int get_temp_d(void)
{
unsigned char idata a=0,b=0;
unsigned char idata i,m;
EA=0;
ds_reset_1();//复位
check_pre_1();
wr_ds18_1(0xcc);
wr_ds18_1(0x44);
while(BUSY1);
ds_reset_1();
check_pre_1();
wr_ds18_1(0xcc);
wr_ds18_1(0xbe);
a=rd_ds18_1();
b=rd_ds18_1();
i=b; /*若b为1则为负温 */
i=(i>>4);
if(i==0)
{
f=0;
TMP=((a>>4)|(b<<4));
a=(a&0x0f);
TMP_d=a;
}
else
{
f=1;
a=~a;
a=(a+1);
b=~b;
b=(b+1);
m=a;
a=a>>4;
b=b<<4;
TMP=(a|b);
m=(m&0x0f);
TMP_d=m;
}
EA=1;
return(TMP_d);
}void delay(unsigned int x)
{
unsigned int i;
for(i=0;i<x;i++);
}
void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4)
{
P0=a[d1];
LED_0=0;
delay(100);
LED_0=1;
P0=a[d2] & 0x7f;
LED_1=0;
delay(100);
LED_1=1;
P0=a[d3];
LED_2=0;
delay(100);
LED_2=1;
P0=a[d4];
LED_3=0;
delay(100);
LED_3=1;
}
㈦ 51单片机,LCD1602显示单线接三个DS18B20的C语言编程
给你四个DS1B820的程序(单总线实现的)。LCD1602显示,但是没有报警哦。
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
sbit RS=P3^5; //定义LCD端口
sbit RW=P3^6;
sbit E=P3^7;
sbit DQ=P3^4; //定义单总线端口
uchar LCD_3,LCD_2,LCD_1,LCD_0;
uchar ds18b20_romA[8]={0x8e,0x00,0x00,0x00,0xb8,0xc5,0x30,0x28};
//四个DS18B20的64位ROM地址
uchar ds18b20_romB[8]={0x52,0x00,0x00,0x00,0xb8,0xc5,0x34,0x28};
uchar ds18b20_romC[8]={0x65,0x00,0x00,0x00,0xb8,0xc5,0x35,0x28};
uchar ds18b20_romD[8]={0x3c,0x00,0x00,0x00,0xb8,0xc5,0x37,0x28};
uchar code LCDData[] ="0123456789";
//************************************
//延时程序
//************************************
void delay(unsigned int N)
{
unsigned int i;
for(i=0;i<N;i++);
}
//************************************
//LCD1602测忙
//************************************
void check_busy(void)
{
while(1)
{
P1=0xff;
E=0;
_nop_();
RS=0;
_nop_();
_nop_();
RW=1;
_nop_();
_nop_();
E=1;
_nop_();
_nop_();
_nop_();
_nop_();
if((P1&0x80)==0)
{
break;
}
E=0;
}
}
//************************************
//LCD1602写命令
//************************************
void write_command(uchar tempdata)
{
E=0;
_nop_();
_nop_();
RS=0;
_nop_();
_nop_();
RW=0;
P1=tempdata;
_nop_();
_nop_();
E=1;
_nop_();
_nop_();
E=0;
_nop_();
check_busy();
}
//************************************
//LCD1602写数据
//************************************
void write_data(uchar tempdata)
{
E=0;
_nop_();
_nop_();
RS=1;
_nop_();
_nop_();
RW=0;
P1=tempdata;
_nop_();
_nop_();
E=1;
_nop_();
_nop_();
E=0;
_nop_();
check_busy();
}
//************************************
//初始化LCD1602
//************************************
void init_lcd1602()
{
write_command(0x01); //清除屏幕
write_command(0x38); //功能设定(8位,2行,5*7点阵式)
write_command(0x0c); //显示器ON,光标OFF,闪烁OFF
write_command(0x06);//地址加1
}
//************************************
//初始化ds18b20
//************************************
bit resetpulse(void)
{
DQ=0;
delay(40); //延时500us
DQ=1;
delay(4); //延时60us
return(DQ); //读取P1.0的状态
}
void ds18b20_init(void)
{
while(1)
{
if(!resetpulse()) //收到ds18b20的应答信号
{
DQ=1;
delay(40); //延时240us
break;
}
else
resetpulse(); //否则再发复位信号
}
}
//************************************
//读ds18b20一位
//************************************
uchar read_bit(void)
{
DQ=0;
_nop_();
_nop_();
DQ=1;
delay(2);
return(DQ);
}
//************************************
//读ds18b20一个字节
//************************************
uchar read_byte(void)
{
uchar i,m,receive_data;
m=1;
receive_data=0;
for(i=0;i<8;i++)
{
if(read_bit())
{
receive_data=receive_data+(m<<i);
}
delay(7);
}
return(receive_data);
}
//************************************
//向ds18b20写一位
//************************************
void write_bit(uchar bitval)
{
DQ=0;
if(bitval==1)
DQ=1;
delay(5);
DQ=1;
}
//************************************
//向DS18B20写一个字节命令
//************************************
void write_byte(uchar val)
{
uchar i,temp;
for(i=0;i<8;i++)
{
temp=val>>i;
temp=temp&0x01;
write_bit(temp);
delay(5);
}
}
//*************************************
//64位的ROM序列号匹配
//*************************************
bit match_rom(uchar *rom)
{
uchar i;
ds18b20_init();
write_byte(0x55);
for(i=8;i>0;i--)
{
write_byte(*(rom+i-1));
}
return 1;
}
void main(void)
{
uchar temp_data_l,temp_data_h;
init_lcd1602();
while(1)
{
ds18b20_init();
write_byte(0xcc);
write_byte(0x44); //启动温度转换
delay(700);
match_rom(ds18b20_romA); //匹配第一路
write_byte(0xbe); //读温度
temp_data_l= read_byte(); //温度低8位
temp_data_h = read_byte(); //温度高8位
convert_T(temp_data_h,temp_data_l);
first_line[2]=LCD_3; //温度转换后的各位
first_line[3]=LCD_2; //分别存入显示缓存数组中
first_line[4]=LCD_1;
first_line[6]=LCD_0;
match_rom(ds18b20_romB); //匹配第二路
write_byte(0xbe); //读温度
temp_data_l= read_byte(); //温度低8位
temp_data_h = read_byte(); //温度高8位
convert_T(temp_data_h,temp_data_l);
first_line[10]=LCD_3; //温度转换后的各位
first_line[11]=LCD_2; //分别存入显示缓存数组中
first_line[12]=LCD_1;
first_line[14]=LCD_0;
display();
match_rom(ds18b20_romC); //匹配第三路
write_byte(0xbe); //读温度
temp_data_l= read_byte(); //温度低8位
temp_data_h = read_byte(); //温度高8位
convert_T(temp_data_h,temp_data_l);
second_line[2]=LCD_3; //温度转换后的各位
second_line[3]=LCD_2; //分别存入显示缓存数组中
second_line[4]=LCD_1;
second_line[6]=LCD_0;
match_rom(ds18b20_romD); //匹配第四路
write_byte(0xbe); //读温度
temp_data_l= read_byte(); //温度低8位
temp_data_h = read_byte(); //温度高8位
convert_T(temp_data_h,temp_data_l);
second_line[10]=LCD_3; //温度转换后的各位
second_line[11]=LCD_2; //分别存入显示缓存数组中
second_line[12]=LCD_1;
second_line[14]=LCD_0;
display();
}
}
㈧ 求一个51单片机 用DS18B20芯片实现 的温控程序
基于AT89S51单片机的数字温度测量及显示系统设计
程序
DI EQU P3.3
DO EQU P3.4
CLK EQU P3.5
CS EQU P3.6 ; LCD端口定义
D2RS EQU P2.7
D2RW EQU P2.6
D2E EQU P2.5
KEYPORT EQU P1 ; DS18B20端口定义
TEMPER_L EQU 36H
TEMPER_H EQU 35H
TEMPER_NUM EQU 38H
FLAG1 BIT 00H
DQ BIT P2.4
ORG 0000H
LJMP MAIN
ORG 0003H
JMP INT00
ORG 0038H
MAIN: MOV SP,#60H
SETB P2.0
SETB P2.1
SETB P2.2
SETB EA
SETB EX0
SETB P2.0
SEETB P2.1
SETB P2.2
MOV R0,#01H ;清屏并置地址计数器AC为0
LCALL DIS_CMD _WRT
MOV R0,#38H ;8位数据接口,双行显示,5*7点阵
LCALL DIS_CMD _WRT
CALL DIS_CUR_OFF
MOV 42H,#20
MOV 43H,#32
XIAN: LCALL GET_TEMPER
LCALL DISP
LCALL DELAY43MS
MOV A,TEMPER_NUM
SUBB A,42H
JC ZZZL
MOV A,TEMPER_NUM
SUBB A,43H
JNC ZZZ2
SETB P2.0
SETB P2.1
SETB P2.2
JMP XIAN
ZZZL: CLR P2.0
CLR P2.2
JMP XIAN
ZZZ2: CLR P2.0
CLR P2.1
JMP XIAN
INT0: ;扫描键盘程序
LCALL ASK
SAO: CLR 01H
LCALL KEY
JNB 01H,SAO
CJNE A,#10,PAN
LCALL ANSW
RETI
PAN: CJNE A,#12,SAO
RETI ;显示函数部分,可供调用
DIS_CUR_OFF: MOV R0,#0CH
LCALL DIS_CMD_WRT
RET
DIS_CUR_ON: MOV R0,#0EH
LCALL DIS_CMD_WRT
RET
CHK_BUSY_FLG: MOV P0,#0FFH
CLR D2RS
NOP
NOP
NOP
LCALL DISPLAY_RD
JB ACC.7,CHK_BUSY_FLG
RET
CLEAR_DIS: MOV R0,#01H
LCALL DIS_CMD_WRT
RET
DIS_CMD_WRT: LCALL CHK_BUSY_FLG
MOV P0,R0
CLR D2RS
NOP
NOP
NOP
LCALL DISPLAY_WRT
RET
DIS_DATA_WRT: LCALL CHK_BUSY_FLG
CJNE A,#10H,DIS_DAT_WRT1
MOV P0,#0C0H ;1100,00000行起始地址为40
CLR D2RS
NOP
NOP
NOP
LCALL DISPLAY_WRT
DIS_DAT_WRT1: MOV P0,R0
SETB D2RS
NOP
NOP
NOP
LCALL DISPLAY_WRT
RET
DISPLAY_WRT: CLR D2RW
NOP
NOP
NOP
SETB D2E
NOP
NOP
NOP
CLR D2E
NOP
NOP
NOP
RET
DISPLAY_RD: SETB D2RW
NOP
NOP
NOP
SETB D2E
NOP
NOP
NOP
MOV A,P0
NOP
NOP
NOP
CLR D2E
NOP
NOP
NOP
RET
DIS_DATA_RD: LCALL CHK_BUSY_FLG
MOV P0,#0FFH
SETB D2RS
LCALL DISPLAY_RD
RET ;键盘程序,出口:A为按键值 01H:0无键按下 1 有键按下
KEY: MOV KEYPORT,#0FH
MOV A,KEYPOR
CJNE A,#0FH,KEYDOWN
MOV A,#0FFH
RET
KEYDOWN: LCALL DELAY43MS
MOV KEYPORT,#0FH
MOV A,KEYPORT
CJNE A,#0FH,KEYDOWN_YES
MOV A,#0FFH
RET
KEYDOWN _YES: MOV B,A
MOV KEYPORT,#0F0H
MOV A,KEYPORT
ORL A,B
PUSH 30H
MOV 30H,A
MOV R3,#10H
MOV DPTR,#KEYVALUE
NEXT_KEY: MOV A,R3
MOVC A,@a+dptr
CJNE A,30h,NEXTKEYVALUE
DEC R3
POP 30H
WAITKEY_F: MOV KEYPORT,#0FH
MOV A,KEYPORT
CJNE A,#0FH, WAITKEY_F
MOV A,R3
SETB 01H
RET
NEXTKEYVALUE: DJNZ R3,NEXT_KEY
DEC R3
POP 30H
WAITKEY_FREE: MOV KEYPORT,#0FH
MOV A,KEYPORT
CJNE A,#0FH, WAITKEY_FREE
MOV A,R3
SETB 01H
RET
KEYVALUE: DB 0FFH,7EH,7DH,7BH,77H,0BEH,0BDH,0BBH,0B7H,0DEH,0DDH,0DBH,0D7H,0EEH,0EDH,0EBH,0E7H
DELAY43MS: PUSH A
MOV A,R3
PUSH A
MOV A,R2
PUSH A
MOV R3,#43
DELAY: MOV R2,#0FAH
LOOP: NOP ;内层循环为1MS
NOP
DJNZ R2,LOOP
DJNZ R3, DELAY
POP A
MOV R2,A
POP A
MOV R3,A
POP A
RET ;确认是否修改温度设定
ASK: MOV R0,#01H ;清屏并置地址计数器AC为0
LCALL DIS_CMD_WRT
MOV 40H,#0
ZDZ: MOV DPTR,#LINE
MOV A,40H
MOVC A,@A+DPTR
MOV R0,A
LCALL DIS_DATA_WRT
INC 40H
MOV A,40H
MOVC A,@A+DPTR
CJNE A,#00H,ZDZ
RET
LINE: DB " ARE YOU SURE
CHANGE T(Y/N)?",00H
ANSW: MOV R6,42H
MOV R7,43H
MOV R0,#01H
LCALL DIS_CMD_WRT
MOV R0,#44H
CALL DIS_DATA_WRT
MOV R0,#6FH
CALL DIS_DATA_WRT
MOV R0,#77H
CALL DIS_DATA_WRT
MOV R0,#6EH
CALL DIS_DATA_WRT
MOV R0,#3AH
CALL DIS_DATA_WRT
MOV 40H,#0
CLR 00H
JMP SAO1
GAI: MOV R0,#0FEH
CALL DIS_DATA_WRT
MOV R0,#55H
CALL DIS_DATA_WRT
MOV R0,#70H
CALL DIS_DATA_WRT
MOV R0,#3AH
CALL DIS_DATA_WRT
MOV 40H,#0
SAO1: CLR 01H
LCALL KEY
JNB 01H,SAO1
MOV R1,A
MOV B,#10
DIV AB
JZ NEXT2
MOV A,A1
CJNE A,#11,XU
JB 00H,DOWN
MOV 42H,40H
CPL 00H
JMP GAI
DOWN: MOV 43H,40H
RETI
XU: CJNE A,#12,SAO1
MOV 42H,R6
MOV 43H,R7
RETI
NEXT2: MOV A,R1
ADD A,#30H
MOV R0,A
LCALL DIS_DATA_WRT
MOV A,R1
XCH A,40H
MOV B,#10
MUL AB
NOP
CLR DQ
CLR C
WR1: CLR DQ
MOV R3,#6
DJNZ R3,$
RR R4,#2 R1,#36H ; 低位存入36H(TEMPER_L),高位存入35H(TEMPER_
NOP
NOP
SETB DQ
MOV R3,#7
DJNZ R3,$
MOV C,DQ
MOV R3,#23
DJNZ R3,$
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET ; 将从DS18B20中读出的温度数据进行转换
TEMPER_COV: MOV A,#0f0H
ANL A,TEMPER_L ; 舍去温度低位中小数点后的四位温度数值
SWAP A
MOV TEMPER_NUM,A
MOV A,TEMPER_L
JNB ACC.3,TEMPER_COV1 ; 四舍五入去温度值
INC TEMPER_NUM
TEMPER_COV1:MOV A,TEMPER_H
ANL A,#07H
SWAP A
ORL A,TEMPER_NUM
MOV TEMPER_NUM,A ; 保存变换后的温度数据
RET ;AD0832:
SETB DI
SETB DO
SETB CLK
CLR CS
NOP
SETB CS
CLR CLK
CLR CS
CALL DELAY1
SETB DI
SETB CLK
NOP
CLR CLK
SETB DI
SETB CLK
NOP
CLR CLK
CLR DI
SETB CLK
NOP
CLR CLK
NOP
SETB CLK
NOP
CLR CLK
NOP
SETB CLK
MOV C,DO
CLR CLK
RLC A;7
SETB CLK
MOV C,DO
CLR CLK
RLC A 6
SETB CLK
MOV C,DO
CLR CLK
RLC A ;5
SETB CLK
MOV C,DO
CLR CLK
RLC A ;4
SETB CLK
MOV C,DO
CLR CLK
RLC A ;3
SETB CLK
MOV C,DO
CLR CLK
RLC A ;2
SETB CLK
MOV C,DO
CLR CLK
RLC A ;1
SETB CLK
MOV C,DO
CLR CLK
RLC A ;0
SETB CLK
NOP
CLR CLK ;1
NOP
SETB CLK
NOP
CLR CLK ;2
NOP
SETB CLK
NOP
CLR CLK ;3
NOP
SETB CLK
NOP
CLK ;4
NOP
SETB CLK
NOP
CLR CLK ;5
NOP
SETB CLK
NOP
CLR CLK ;6
NOP
SETB CLK
NOP
CLR CLK ;7
NOP
SETB CLK
NOP
CLR CLK
NOP
SETB CLK
NOP
CLR CLK
NOP
CALL DELAY1
SETB CS
RET
DELAY1: MOV R7,#10
DELAY2: NOP
NOP
DJNZ R7,DELAY2
RET
㈨ 给个51单片机单线挂载多个ds18b20温度计的程序
//安装目录下的EXE文件打开后可在电脑上显示当前温度值
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2; //define interface
uint temp; // variable of temperature
uchar flag1; // sign of the result positive or negative
sbit la=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef};
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
///////功能:串口初始化,波特率9600,方式1///////
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
void dsreset(void) //send reset and initialization command
{
uint i;
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit
{
uint i;
bit dat;
DS=0;i++; //i++ for delay
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //read a byte date
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //DS18B20 begin change
{
dsreset();
delay(1);
tmpwritebyte(0xcc); // address all drivers on bus
tmpwritebyte(0x44); // initiates a single temperature conversion
}
uint tmp() //get the temperature
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread();
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a;
tt=temp*0.0625;
temp=tt*10+0.5;
return temp;
}
void readrom() //read the serial
{
uchar sn1,sn2;
dsreset();
delay(1);
tmpwritebyte(0x33);
sn1=tmpread();
sn2=tmpread();
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
void display(uint temp) //显示程序
{
uchar A1,A2,A2t,A3,ser;
ser=temp/10;
SBUF=ser;
A1=temp/100;
A2t=temp%100;
A2=A2t/10;
A3=A2t%10;
la=0;
P0=table[A1]; //显示百位
la=1;
la=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(1);
la=0;
P0=table1[A2]; //显示十位
la=1;
la=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(1);
P0=table[A3]; //显示个位
la=1;
la=0;
P0=0x7b;
wela=1;
wela=0;
delay(1);
}
void main()
{
uchar a;
Init_Com();
do
{
tmpchange();
// delay(200);
for(a=10;a>0;a--)
{ display(tmp());
}
} while(1);
}
㈩ 基于51单片机的DS18B20程序(数码管显示)
#include <reg51.h>
#include"18b20.c"
sbit DQ =P1^0; //定义通信端口
unsigned char tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0, 1, 2 3 4 5 6 7 8 9
void delay(unsigned int i);//延时函数
Init_DS18B20(void); //初始化函数
ReadOneChar(void); //读一个字节
WriteOneChar(unsigned char dat); //写一个字节
ReadTemperature(void); //读取温度
void display(unsigned char i); //温度显示函数
unsigned char c=0,x=0;
//****主程序温度显示函数**********
void display(unsigned char i){
P0=tab[i/10];
P2=0x04;
delay(100);
P0=tab[i%10];
P2=0x02;
delay(100);
P0=tab[x];
P2=0x01;
delay(100);
}
void main(void){
unsigned char temp;
while(1){ //主循环
temp=ReadTemperature();
display(temp);
}
}