我尝试了并行三个温度传感器 但是温度一直显示不对,然后试了下只编程一个 也是27.9不知道为什么 然后我自己做的按钮,编程好像也有点问题,求会做的教我,追加悬赏80
/*******************************************
函数名称:DS18B20_Reset
功 能:对DS18B20进行复位初始化操作
参 数:无
返回值 :初始化状态标志:0--失败,1--成功
********************************************/
uchar DS18B20_Reset(void)
{
uchar Error=0;
P1DIR = 0xff;
_DINT();
P1OUT = 0x00;
DelayNus(500);
P1OUT = 0xff;
DelayNus(55);
P1DIR = 0x00;
_NOP();
if(P1IN == 0x00)
{
Error = 1; //初始化成功
}
else
{
Error = 0; //初始化失败
}
P1DIR = 0xff; //设置为输出,并MCU给出高电平
P1OUT = 0xff;
_EINT();
DelayNus(400);
return Error;
}
//总线读取一个数据位
uchar DS18B20_ReadDQ(void)
{
uchar DQ_S=0;
P1OUT = 0x00; //8个DQ 线全部设置为低电平
DelayNus(6);
P1OUT = 0xff;
DelayNus(8);
P1DIR = 0x00; //准备读取
_NOP(); //延时待总线准备好数据
DQ_S = P1IN; //一次性读取8条DQ线的数据状态
DelayNus(45);
P1DIR = 0xff;
P1OUT = 0xff; //恢复端口电平
DelayNus(10); //延时
return DQ_S; //返回读取的值
}
//写数据
void DS18B20_WriteByte(uchar Com)
{
uchar i;
_DINT();
for(i=0;i {
P1DIR = 0xff;
P1OUT = 0x00;
DelayNus(6);
if (Com&0x01)
{
P1OUT = 0xff;
}
else
{
P1OUT = 0x00;
}
Com = Com>>1;
DelayNus(50);
P1OUT = 0xff;
DelayNus(10);
}
_EINT();
}
// 录入两位数据
void DS18B20_Read2Byte(void)
{
uint i;
for(i=0;i<16;i++)
{
Read_buf_8ch[i]=DS18B20_ReadDQ();
}
}
//启动温度转换
void DS18B20_Conver(void)
{
DS18B20_WriteByte(0xcc);
DS18B20_WriteByte(0x44);
}
//读取温度值
void DS18B20_ReadTemp(void)
{
uchar i;
char j,k;
uchar Mask;
do
{
i = DS18B20_Reset();
}
while(i);
DS18B20_Conver();
DelayNus(60000);
do
{
i = DS18B20_Reset();
}
while(i);
DS18B20_WriteByte(0xcc);
DS18B20_WriteByte(0xbe);
DS18B20_Read2Byte();
for(j=16;j>0;j--)
{
Mask=0x01;
for(k=0;k<3;k++)
{
uiData[k] = uiData[k]<<1;
if(Read_buf_8ch[j-1]&Mask) uiData[k]++;
Mask = Mask<<1;
}
}
}
//将十一位二进制数转换成六位整形数据
void Disp_Numb(uint temper)
{
uchar i;
for(i = 0;i < 6;i++) dN[i] = 0;
if(temper & BIT0)
{
dN[0] = 5;
dN[1] = 2;
dN[2] = 6;
}
if(temper&BIT1)
{
dN[1] += 5;
dN[2] += 2;
dN[3] += 1;
}
if(temper & BIT2)
{
dN[2] += 5;
dN[3] += 2;
if(dN[2] >= 10)
{
dN[2] -= 10;
dN[3] += 1;
}
}
if(temper&BIT3)
{
dN[3] += 5;
}
if(temper & BIT4)
{
dN[4] += 1;
}
if(temper & BIT5)
{
dN[4] += 2;
}
if(temper & BIT6)
{
dN[4] += 4;
}
if(temper & BIT7)
{
dN[4] += 8;
if(dN[4] >= 10)
{
dN[4] -= 10;
dN[5] += 1;
}
}
if(temper & BIT8)
{
dN[4] += 6;
dN[5] += 1;
if(dN[4] >= 10)
{
dN[4] -= 10;
dN[5] += 1;
}
}
if(temper & BIT9)
{
dN[4] += 2;
dN[5] += 3;
if(dN[4] >= 10)
{
dN[4] -= 10;
dN[5] += 1;
}
}
if(temper & BITA)
{
dN[4] += 4;
dN[5] += 6;
if(dN[4] >= 10)
{
dN[4] -= 10;
dN[5] += 1;
}
if(dN[5] >= 10)
{
dN[5] -= 10;
}
}
}
//显示当前温度
void Disp_TEM(void)
{
char Bai,Shi,Ge; //定义变量
Disp_Numb(Cur_TMP1);
Bai=dN[5];
Shi=dN[4];
Ge =dN[3];
Disp_EN(1,6,table1[Bai]);
Disp_EN(1,7,table1[Shi]);
Disp_EN(1,8,table1[11]);
Disp_EN(1,9,table1[Ge]);
DelayNus(100);
Disp_Numb(Cur_TMP2);
Bai=dN[5];
Shi=dN[4];
Ge =dN[3];
Disp_EN(2,6,table1[Bai]);
Disp_EN(2,7,table1[Shi]);
Disp_EN(2,8,table1[11]);
Disp_EN(2,9,table1[Ge]);
DelayNus(100);
Disp_Numb(Cur_TMP3);
Bai=dN[5];
Shi=dN[4];
Ge =dN[3];
Disp_EN(3,8,table1[Bai]);
Disp_EN(3,9,table1[Shi]);
Disp_EN(3,10,table1[11]);
Disp_EN(3,11,table1[Ge]);
DelayNus(100);
}
//按键检测
uchar Keyscan()
{
uchar temp,key;
P2DIR=0x00;
temp=P2IN;
if (temp==0x01)
{
DelayNus(10);
if (temp==0x01) key=1;
}
if (temp==0x02)
{
DelayNus(10);
if (temp==0x02) key=2;
}
if (temp==0x04)
{
DelayNus(10);
if (temp==0x03) key=3;
}
else
{
DelayNus(10);
}
return key;
}
//主程序
int main(void)
{
WDTCTL=WDTPW+WDTHOLD;
BCSCTL1 &= ~XT2OFF;
_EINT();//打开全局中断
TACTL |= TASSEL_2 + ID_3;
Ini_Lcd();
while(1)
{
GDWZ();
DS18B20_ReadTemp();
Cur_TMP1=uiData[0];
Cur_TMP2=uiData[1];
Cur_TMP3=uiData[2];
Disp_TEM();
key_number=Keyscan();
if (key_number==1)
{
if(Cur_TMP1<=10)
{
P3DIR = 0x05;
P3OUT = BIT0+BIT2;
Disp_HZ(4,4,table2[8]);
Disp_HZ(4,5,table2[10]);
}
if(Cur_TMP1>10&&Cur_TMP1<20)
{
P3DIR = 0x01;
P3OUT = BIT0;
Disp_HZ(4,4,table2[11]);
Disp_HZ(4,5,table2[12]);
}
else
{
P3DIR = 0x03;
P3OUT = BIT0+BIT1;
Disp_HZ(4,4,table2[8]);
Disp_HZ(4,5,table2[9]);
}
}
if(key_number==2)
{
if(Cur_TMP1<=20)
{
P3DIR = 0x05;
P3OUT = BIT0+BIT2;
Disp_HZ(4,4,table2[8]);
Disp_HZ(4,5,table2[10]);
}
if(Cur_TMP1>20&&Cur_TMP1<30)
{
P3DIR = 0x01;
P3OUT = BIT0;
Disp_HZ(4,4,table2[11]);
Disp_HZ(4,5,table2[12]);
}
else
{
P3DIR = 0x03;
P3OUT = BIT0+BIT1;
Disp_HZ(4,4,table2[8]);
Disp_HZ(4,5,table2[9]);
}
}
if (key_number==3)
{
if(Cur_TMP1<=30)
{
P3DIR = 0x05;
P3OUT = BIT0+BIT2;
Disp_HZ(4,4,table2[8]);
Disp_HZ(4,5,table2[10]);
}
if(Cur_TMP1>30&&Cur_TMP1<40)
{
P3DIR = 0x01;
P3OUT = BIT0;
Disp_HZ(4,4,table2[11]);
Disp_HZ(4,5,table2[12]);
}
else
{
P3DIR = 0x03;
P3OUT = BIT0+BIT1;
Disp_HZ(4,4,table2[8]);
Disp_HZ(4,5,table2[9]);
}
}
else
{
P3DIR = 0x01;
P3OUT = BIT0;
Disp_HZ(4,4,table2[11]);
Disp_HZ(4,5,table2[12]);
}
Delay_Nms(1000);
Clear_LCD();
}
}
这是我写的18B20底层驱动,你可以参考一下。本来说QQ发给你整个工程的,却被管理员给删除了.....
/*一下是 .H文件*/
#ifndef __DS18B20_H
#define __DS18B20_H
#include
#include
#define uchar unsigned char
#define uint unsigned int
void delay_us(uint t);//us级延迟函数
void DS18B20_reset();//单总线通信的初始化
bit DS18B20_read_bit();//位读取时序
uchar DS18B20_read_byte();//读取一字节的子函数
void DS18B20_write_byte(uchar dat);//位写入时序
//uint read_temperature();//温度读取子函数
uint Read_ID_temperature(uchar x);//寻找ID,温度读取子函数 ( 多个DS18B20时使用 )
#endif
/*一下是.C文件*/
#include
sbit DS18B20=P2^0;
bit flag;
void delay_us(uint t)//us级延迟函数
{
while(t--);
}
void DS18B20_reset()//单总线通信的初始化
{
DS18B20=1;
delay_us(5);//约66us
DS18B20=0;
delay_us(80);//约700+us
DS18B20=1;
delay_us(14);//约150us
if(DS18B20==0)
flag=1;//表示18B20存在
else
flag=0;//表示18B20不存在
delay_us(20);//约200+us
}
bit DS18B20_read_bit()//位读取时序
{
bit dat; //定义 位的变量
DS18B20=0;
nop();
nop();
DS18B20=1;
nop();
dat=DS18B20;
delay_us(10);//约100us
return dat;
}
uchar DS18B20_read_byte()//读取一字节的子函数
{
uchar i,j,k;
for(i=0;i {
j=DS18B20_read_bit();
k=(j>1);
}
return k;
}
void DS18B20_write_byte(uchar dat)//位写入时序
{
uchar i;
for(i=0;i {
DS18B20=0;
_nop_();
DS18B20=dat&0x01;
delay_us(6);//约70us
DS18B20=1;
dat=dat>>1;//右移一位
}
delay_us(6);
}
//uint read_temperature()//温度读取子函数
//{
// uint temp;//定义一个16位变量
// uchar a=0,b=0;
// float TEMP=0;
// DS18B20_reset();//DS18B20 初始化
// DS18B20_write_byte(0xCC); // 跳过读序号列号的操作
// DS18B20_write_byte(0x44); // 启动温度转换
// DS18B20_reset();//DS18B20 初始化
// DS18B20_write_byte(0xcc);//发送ROM操作命令0xcc,跳过Rom命令
// DS18B20_write_byte(0xbe);//发送温度读取命令(读暂存器)0xbe
//
// a=DS18B20_read_byte();//读取低8位
// b=DS18B20_read_byte();//读取高8位
//
// temp=b;
// temp=temp<<8;//左移8位
// temp=temp|a;//就此,temp的值便是温度的16位
// TEMP=temp*0.0625;//[算法],得出实际温度。将二进制数转化为温度的值
// temp=TEMP*10+0.5;//方便显示,放大10倍;进行4舍5入,去掉小数
// return (temp);
//}
uchar code DS18B20_A_ID[8]={0x28,0x15,0xc4,0x40,0x05,0x00,0x00,0x46}; //短引脚18B20
uchar code DS18B20_B_ID[8]={0x28,0x62,0x0B,0xD3,0x06,0x00,0x00,0x9B}; //长引脚18B20
uint Read_ID_temperature(uchar x)//寻找ID,温度读取子函数 ( 多个DS18B20时使用 )
{
uchar i;
uint temp;//定义一个16位变量
uchar a=0,b=0;
float TEMP=0;
DS18B20_reset();//复位18B20
DS18B20_write_byte(0x55); // 寻找ID命令
for(i=0;i<8;i++)//写入64位ROM代码 (要读取温度的ID号)
{
if(x==1)
{
DS18B20_write_byte(DS18B20_A_ID[i]);
}
if(x==2)
{
DS18B20_write_byte(DS18B20_B_ID[i]);
}
}
DS18B20_write_byte(0x44); // 启动温度转换
DS18B20_reset();//复位18B20
DS18B20_write_byte(0x55); // 寻找ID命令
for(i=0;i<8;i++)//写入64位ROM代码 (要读取温度的ID号)
{
if(x==1)
{
DS18B20_write_byte(DS18B20_A_ID[i]);
}
if(x==2)
{
DS18B20_write_byte(DS18B20_B_ID[i]);
}
}
DS18B20_write_byte(0xbe);//发送温度读取命令(读暂存器)0xbe
a=DS18B20_read_byte();//读取低8位
b=DS18B20_read_byte();//读取高8位
temp=b;
temp=temp<<8;//左移8位
temp=temp|a;//就此,temp的值便是温度的16位
TEMP=temp*0.0625;//[算法],得出实际温度。将二进制数转化为温度的值
temp=TEMP*10+0.5;//方便显示,放大10倍;进行4舍5入,去掉小数
return (temp);
}
这是我的proteus图
你是DS18B20的温度不可以改变还是说可以改变DS18B20的温度,但是显示的温度一直不变?我记得当初有些版本proteus中的DS18B20有问题,仿真出不了结果,我现在用的是版本7,DS18B20是可以用的