51单片机+DS18B20测温程序

#include
#include

#define uchar unsigned char
#define uint unsigned int

sbit y0=P3^2;
sbit y1=P3^1;
sbit y2=P3^0;
sbit ds=P3^7;

bit flag; //初始化标志位,flag=1,初始化成功,flag=0,初始化失败
uint temp; //temp为16位的数据,所以用uint,uchar只能用于8位的变量

uchar code table_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void delay(uchar x)
{
uchar a,b;
for(a=x;a>0;a–)
for(b=200;b>0;b–);
}

void delay_us(uint t) //us级延迟函数
{
while(t–);
}

void ds_reset() //复位初始化函数
{
ds=1; //将单总线拉高,为初始化准备
delay_us(5); //延时30多us
ds=0; //将电平拉低,当低电平保持480us~960us时,就成为了DS18B20的复位信号
delay_us(80); //大约延时7百多us,当DS18B20收到复位脉冲后的15~60us会发送一个存在脉冲
ds=1; //将总线拉高,为DS18B20发送一个60~240的存在脉冲,即应答脉冲
delay_us(14); //延时154us
if(ds==0) //如果ds0,则说明DS18B20发送了一个存在脉冲,表示DS18B20存在
flag=1; //如果DS应答了,标志flag=1;
else
flag=0; //DS没应答,标志flag=0;复位初始化失败
delay_us(20); //大概200多us
}

bit ds_read_bit() //位读取函数
{
bit dat;
ds=0; //将总线拉低,延时至少1us后,主机开始读数据
nop(); //延时一个机器周期,12M晶振一个机器周期1us
nop(); //延时1us
ds=1; //将总线拉高,释放总线,将总线交给DS18B20控制,此时主机就可以读DS18B20发送出来的数据了
dat=ds; //读取总线状态,即读DS18B20发送到总线上的数据
delay_us(10); //延时70us,一个读时序最少60us,所以最少延时60us才能去执行下一天指令
return dat; //把dat的值返回
}

uchar ds_read_byte() //把读取到的位转换为一个字节
{
uchar i,j,k;
for(i=0;i<8;i++)
{
j=ds_read_bit(); //把读取位函数读到的位赋给j
k=(j<<7)|(k>>1); //把读取到的位左移7位到j的最高位,再与k左移一位的值进行或运算,即将j的最高位赋给k的最高位
}
return k; //返回读到的字节
}

void ds_write_byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
ds=0; //将总线拉为低电平
nop(); //延时1us
ds=dat&0x01; //职保留dat的最低位,若dat=1,则为1,dat=0,则为0
delay_us(6); //延时几十us
ds=1; //不管发送的是0还是1,都要把总线释放
dat=dat>>1; /发送了最低位0位后,将dat右移一位,将第1位挪到第0位,
下一次就可以发送原来第1位上的数据了,循环8次一个字节就发送出了
/
}
delay_us(6); //延时几十us
}

uint read_temperature() //读温度函数
{
uchar a,b; //定义变量a、b,a存高8位,b存低8位
ds_reset(); //DS18B20初始化
ds_write_byte(0xcc); //向DS18B20发送ROM指令,跳过ROM(因为总线上只有一个DS18B20)
ds_write_byte(0xbe); //向DS18B20发送读暂存器指令,依次读取DS18B20发出的字节数据
a=ds_read_byte(); //将读到的低8位放到a
b=ds_read_byte(); //将读到的高8位放到b
temp=b; //用temp把b的值读过来
temp=temp<<8; //将temp左移8位,即将读到的高8位移到高位,腾出temp的低8位
temp=temp|a; //将temp与a进行或运算,这样就将a的值存进了temp的低8位
temp=temp0.062510+0.5; /放了方便写显示函数,所以放大10倍,当成百位,十位,个位,
只需在十位和个位加个小数点就可以了,小时部分加个0.5,如果大于0.5就进1
/
return temp;
}

void display(uint temp) //数码管显示函数
{
y0=0;
y1=1;
y2=1;
P1=table_du[temp/100];
delay(10);
y0=1;
y1=0;
y2=1;
P1=table_du[temp%100/10]|0x80; //0x80的作用是加个小数点
delay(10);
y0=1;
y1=1;
y2=0;
P1=table_du[temp%100%10];
delay(10);
}

void main()
{
// y0=1; //打开第1个数码管位选
// y1=1; //打开第2个数码管位选
// y2=1; //打开第3个数码管位选
while(1)
{
ds_reset(); ////DS18B20初始化函数
ds_write_byte(0xcc); //向DS18B20写入命令,跳过ROM
ds_write_byte(0x44); //向DS18B20写入命令,进行温度转换
display(read_temperature()); //将读取到的温度值在数码管上显示出来,read_temperature()代表的是temp的返回值
}
}

你可能感兴趣的:(51单片机,C语言)