📄 ds18b20c.txt
字号:
//这是关于DS18B20的c读写程序,数据脚P1.0,晶振12MHZ
//采用的是启东单片机开发板AY-MPU89S51E
//进行温度显示,这里我们考虑用四位数码管来显示温度
//显示范围-55.0到+99.5度,显示精度为0.5度
//关于程序中的延时请参考ds18b20的读写时序
#include <reg52.h>
#define uchar unsigned char
uchar tempint,tempdf; //温度整数部分和小数部分
sbit TMDAT = P1^0; //根据实实际情况设定
sbit ld7=P1^7; //初始化成功标志led
sbit ld6=P1^6; //负温度标志led
sbit point=P0^7; //小数点显示
uchar f; //负温度标志
code unsigned char ledmap[]={
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF};
//7段数码管0~9数字的共阳显示代码和负号位代码(最后一位)
void set_ds18b20(); //初始化DS18B20子程序
void get_temperature(); //获得温度子程序
void read_ds18b20(); //读DS18B20子程序
void write_ds18b20(uchar command);//向DS18B20写1字节子程序
void delayms(uchar count); //延时count毫秒子程序
void disp_temp(); //显示温度子程序
void main()
{
SP=0x60; //设置堆栈指针
while(1)
{
get_temperature(); //获得温度
if(tempdf>=8)
{ //0.5度精度显示
tempdf=5;
}
else
{
tempdf=0;
}
disp_temp(); //显示温度
}
}
void set_ds18b20()
{
while(1)
{
uchar delay,flag;
flag=0;
TMDAT=1;
delay=1;
while(--delay);
TMDAT=0; //数据线置低电平
delay=250;
while(--delay); //低电平保持500us
TMDAT=1; //数据线置高电平
delay=30;
while(--delay); //高电平保持60us
while(TMDAT==0) //判断DS18B20是否发出低电平信号
{
delay=210; //DS18B20响应,延时420us
while(--delay);
if(TMDAT) //DS18B20发出高电平初始化成功,返回
{
flag=1; //DS18B20初始化成功标志
ld7=0; //初始化成功LED标志
break;
}
}
if(flag) //初始化成功,再延时480us,时序要求
{
delay=240;
while(--delay);
break;
}
}
}
void get_temperature() //温度转换、获得温度子程序
{
set_ds18b20(); //初始化DS18B20
write_ds18b20(0xcc); //发跳过ROM匹配命令
write_ds18b20(0x44); //发温度转换命令
disp_temp(); //显示温度,等待AD转换
set_ds18b20();
write_ds18b20(0xcc); //发跳过ROM匹配命令
write_ds18b20(0xbe); //发出读温度命令
read_ds18b20(); //将读出的温度数据保存到tempint和tempdf处
}
void read_ds18b20()
{
uchar delay,i,j,k,temp,temph,templ;
j=2; //读2位字节数据
do
{
for(i=8;i>0;i--) //一个字节分8位读取
{
temp>>=1; //读取1位右移1位
TMDAT=0; //数据线置低电平
delay=1;
while(--delay);
TMDAT=1; //数据线置高电平
delay=4;
while(--delay); //延时8us
if(TMDAT) //读取1位数据
temp|=0x80;
delay=25; //读取1位数据后延时50us
while(--delay);
}
if(j==2) //读取的第一字节存templ
templ=temp;
else
temph=temp; //读取的第二字节存temph
}while(--j);
f=0;
if((temph & 0xf8)!=0x00) //若温度为负的处理,对二进制补码的处理
{
f=1; //为负温度f置1
ld6=0;
temph=~temph;
templ=~templ;
k=templ+1;
templ=k;
if(k>255)
{
temph++;
}
}
tempdf=templ & 0x0f; //将读取的数据转换成温度值,整数部分存tempint,小数部分存tempdf
templ>>=4;
temph<<=4;
tempint=temph|templ;
}
void write_ds18b20(uchar command)
{
uchar delay,i;
for(i=8;i>0;i--) //将一字节数据一位一位写入
{
TMDAT=0; //数据线置低电平
delay=6; //延时12us
while(--delay);
TMDAT=command&0x01; //将数据放置在数据线上
delay=25; //延时50us
while(--delay);
command=command>>1; //准备发送下一位数据
TMDAT=1; //发送完一位数据,数据线置高电平
}
}
void disp_temp()
{
uchar tempinth,tempintl,cnt;
tempinth=tempint/10; //整数高半字节
tempintl=tempint%10; //整数低半字节
cnt=200; //循环显示200次
while(--cnt)
{
while(f==1)
{
P0=ledmap[10];
if(tempinth==0)
{
P2=0xef;
delayms(1);
goto loop;
}
else
{P2=0xdf;}
}
delayms(1);
P0=ledmap[tempinth];
P2=0xef; //开十位
delayms(1);
loop:P0=ledmap[tempintl];
P2=0xf7; //开个位
point=0; //小数点显示
delayms(1);
P0=ledmap[tempdf];
P2=0xfb; //开十分位
delayms(1);
}
}
void delayms(uchar count) //延时count ms子程序
{
uchar i,j;
do
{
for(i=5;i>0;i--)
for(j=98;j>0;j--);
}while(--count);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -