找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5596|回复: 4
打印 上一主题 下一主题
收起左侧

新手求助有多路三个ds18b20不用单总线的方法怎么做?

[复制链接]
跳转到指定楼层
楼主
最近在做单片机课设 ds18b20多路温度计老师要求我们不要用单总线的方法
代码贴出来如下:
#include<reg52.h>
#include<intrins.h>
#define bool int
#define true 1
#define false 0
#define uchar unsigned char
#define uint unsigned int
bool flag=true;
uchar code table[]={0xc0,0xf9,//共阳数码管普通编码表
0xa4,0xb0,0x99,
0x92,0x82,0xf8,
0x80,0x90};
uchar code table_1[]={0x40,0x79,//共阳数码管带小数编码表
0x24,0x30,0x19,
0x12,0x02,0x78,
0x00,0x10
};
sbit reset=P2^4; //定义复位键 按下复位键之后才可以按其余三个键来选择温度
sbit key1=P2^5; //定义三个独立按键来选择用哪一个ds18b20
sbit key2=P2^6;
sbit key3=P2^7;


sbit DQ1=P1^0; //位定义三个io口接ds18b20
sbit DQ2=P1^1;
sbit DQ3=P1^2;
/*************数码管显示延时程序*********************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*****************ds18b20精确延时程序***********/
/******************延时20us********************/
void time20(void)
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=16;a>0;a--);
}
/******************延时60us********************/
void time60(void)
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=48;a>0;a--);
}


/****************延时500us********************/
void time500(void)
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
/*************初始化程序*********************/
void Init_DS18B20_1()
{


DQ1= 1;
time20();
DQ1= 0;
time500();
DQ1= 1;
time60();
}
/************** DS18B20读函数,每次读16位,可以读出温度寄存器的数值********************/
uchar read_1(void)
{
int i=0;
uchar u=0;
for (i=0;i<16;i++)
{
DQ1=0;
u>>=1;
DQ1=1;
if(DQ1) u|=0x8000;
time20();
}
return (u);
}
/*******************DS18B20写函数,写指令给芯片,每次写八位*************/
void write_1(unsigned char ku)
{
int i=0;
for (i=0;i<8;i++)
{
DQ1=0;
DQ1=ku&0x01;
delay(3);
DQ1=1;
ku>>=1;
}
}
/*******************读取显示函数 返回的是16位的温度数据读取并显示到数码管上***************************/
void Read_and_display_Temperature_1()
{
int num=0;
int aa,bb,cc,dd;
float tm=0;
uchar tp;
write_1(0xcc);//跳过序列号 (0xcc)
write_1(0x44);//启动温度转换 (0x44)
Init_DS18B20_1();//初始化ds18b20
write_1(0xcc);//跳过序列号(0xcc)
write_1(0xbe);//开始读取温度寄存器(指令0xbe)
tp=read_1();//调用函数读取温度寄存器
delay(60);
if((tp&0xf800)==0xf800)//判断正负数 if成立为负数
{
tp=~tp+1;//将tp取反再+1
tm=tp*0.0625;//得到无符号的真实温度值
num=(uint)(tm*10);//将得到的温度乘以10 以便得到小数后一位的数据
aa=num/1000;//得到温度百位
bb=num%1000/100; //得到温度十位
cc=num%1000%100/10; //得到温度个位
dd=num%1000%100%10; //得到温度小数后一位
while(flag)
{
/*位选 将第一个数码管点亮*/
P2=0Xfe;
/*段选 使第一个数码管显示负号*/
P0=0xbf;
/*延时*/
delay(6);
P2=0xfd;
P0=table[bb];
delay(6);
P2=0xfb;
P0=table_1[cc];
delay(6);
P2=0xf7;
P0=table[dd];
if (reset==0)
{
delay(6);
if(reset==0){flag = false;} //退出温度显示死循环
}
}
flag=true;//将标志位复原
}
else
{
tm=tp*0.0625;//得到无符号的真实温度值
num=(uint)(tm*10);//将得到的温度乘以10 以便得到小数后一位的数据
aa=num/1000;//得到温度百位
bb=num%1000/100; //得到温度十位
cc=num%1000%100/10; //得到温度个位
dd=num%1000%100%10; //得到温度小数后一位
while(flag)
{
/*位选 将第一个数码管点亮*/
P2=0xfe;
/*段选 */
P0=table[aa];
/*延时*/
delay(6);
P2=0xfd;
P0=table[bb];
delay(6);
P2=0xfb;
P0=table_1[cc];
delay(6);
P2=0xf7;
P0=table[dd];
if (reset==0)
{
delay(6);
if(reset==0){flag = false;} //退出温度显示死循环
}
}
flag=true;//将标志位复原
}
}
void main()
{
while(1)
{
if(key1==0) //第一个按键按下选择第一个ds18b20
{
delay(5);
if(key1==0)//防抖动
{
Read_and_display_Temperature_1();
}
}
}
代码编译没错
仿真和下载到单片机中都没效果
还有就是新手写的程序太复杂
最想问的是有三个ds18b20 难道我得把程序写三遍吗
请论坛的大神帮帮我这个新手





QK~3OBPQH~4[]_4{[$FUF$3.png (27.54 KB, 下载次数: 115)

QK~3OBPQH~4[]_4{[$FUF$3.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:76755 发表于 2015-4-12 16:48 | 只看该作者
管用
回复

使用道具 举报

板凳
ID:73711 发表于 2015-4-12 18:15 | 只看该作者
你好我看了您写的程序   我没找到应答程序    还有延迟时间 要看手册 我用的延迟 就4US的 好好调延迟  用示波器看
回复

使用道具 举报

地板
ID:69408 发表于 2015-4-13 09:33 | 只看该作者
换个方法,我这个可以参考看看,应该可以用的!http://www.51hei.com/bbs/dpj-31460-1.html

评分

参与人数 1黑币 +35 收起 理由
admin + 35 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

5#
ID:69408 发表于 2015-4-13 09:36 | 只看该作者
换个方法,直接显示3路,我这个应该可以参考使用!http://www.51hei.com/bbs/dpj-31460-1.html

评分

参与人数 1黑币 +35 收起 理由
admin + 35 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表