|
最近在做单片机课设 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 难道我得把程序写三遍吗
请论坛的大神帮帮我这个新手
|
|