设为首页
收藏本站
开启辅助访问
切换到宽版
充值积分
登录
立即注册
论坛
BBS
工程师导航
电子学堂
服务器下载
视频教程汇总
软件汇总
老吴B站
封装搜索
论坛小店
任务升级
在线电子书
搜索
搜索
每日签到
视频汇总
PCB展
原理图
PCB培训
安装包
维修图纸
个人中心
科技新闻
新手上路
每日签到
PCB论坛
单片机
充值升级
积分转换
论坛小店
FPGA论坛
封装汇总
链接6
封装搜索
链接2
链接3
链接4
链接5
链接6
本版
用户
芯片制造中的阻挡层沉积技术介绍
接地搭接电缆布局屏蔽!!!
北美液冷生态解码:超微spuermicro,24年营
SK海力士全球首发HBM4-16层堆叠、2.0TB/s
2纳米Nanosheet技术及其以后的选择性层减薄
24小时热门
(抢先版)Cadence Allegro17.4羊皮卷
7天热门
Allegro超强最全模仿PADS快捷键实现Z切换层
2025劳动节快速入门特训班开始报名了。
PADS和ALLEGRO 零基础-6层板课堂录像申请免费学
充电板PCB原理图+USBLC6-2SC6+STM32F103ZET6
机械臂驱动板,个人PCB设计分享指点
求助,allegro如何添加过孔
800W逆变-EM78156原理图PCB共享
--------采集器-模块
--- MPH100电源板
逆天PCB论坛
»
论坛
›
资源区
›
项目开源
›
51单片机DS18B20温度读取
返回列表
发新帖
51单片机DS18B20温度读取
[复制链接]
1008
|
3
|
2021-8-26 10:40:35
|
显示全部楼层
|
阅读模式
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要
登录
才可以下载或查看,没有账号?
立即注册
×
[paragraph]
S18B20是温度传感器,读写数据有一定的时序:
1、写操作
(1) 数据线先置低电平“0”。
(2) 延时确定的时间为15微秒。
(3) 按从低位到高位的顺序发送字节(一次只发送一位)。
(4) 延时时间为45微秒。
(5) 将数据线拉到高电平。
(6) 重复上(1)到(6)的操作直到所有的字节全部发送完为止。
(7) 最后将数据线拉高。
2、读操作
(1)将数据线拉高“1”。
(2)延时2微秒。
(3)将数据线拉低“0”。
(4)延时3微秒。
(5)将数据线拉高“1”。
(6)延时5微秒。
(7)读数据线的状态得到1个状态位,并进行数据处理。
(8)延时60微秒。
3、例程
//温度传感器:DS18B20
//显示方式:LED
#include 《reg51.h》
#define uchar unsigned char
sbit keyup=P1^0;
sbit keydn=P1^1;
sbit keymd=P1^2;
sbit out=P3^7; //接控制继电器
sbit DQ = P3^4; //接温度传感器18B20
uchar t[2],number=0,*pt; //温度值
uchar TempBuffer1[4]={0,0,0,0};
uchar Tmax=18,Tmin=8;
uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xfe,0xf7};
uchar dismod=0,xiaodou1=0,xiaodou2=0,currtemp;
bit flag;
void t0isr() interrupt 1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
switch(number)
{
case 0:
P2=0x08;
P0=distab[TempBuffer1[0]];
break;
case 1:
P2=0x04;
P0=distab[TempBuffer1[1]];
break;
case 2:
P2=0x02;
P0=distab[TempBuffer1[2]]&0x7f;
break;
case 3:
P2=0x01;
P0=distab[TempBuffer1[3]];
break;
default:
break;
}
number++;
if(number》3)number=0;
}
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20初始化函数**********************/
void Init_DS18B20(void)
{
bit x=0;
do{
DQ=1;
delay_18B20(8);
DQ = 0; //单片机将DQ拉低
delay_18B20(90); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18B20(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败,继续初始化
}while(x);
delay_18B20(20);
}
/***********ds18b20读一个字节**************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i》0;i--)
{
DQ = 0; // 给脉冲信号
dat》》=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b20写一个字节****************/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i》0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat》》=1;
}
}
/**************读取ds18b20当前温度************/
unsigned char *ReadTemperature(unsigned char rs)
{
unsigned char tt[2];
delay_18B20(80);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
delay_18B20(80);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度
tt[0]=ReadOneChar(); //读取温度值低位
tt[1]=ReadOneChar(); //读取温度值高位
return(tt);
}
void covert1(void) //将温度转换为LED显示的数据
{
uchar x=0x00,y=0x00;
t[0]=*pt;
pt++;
t[1]=*pt;
if(t[1]&0x080) //判断正负温度
{
TempBuffer1[0]=0x0c; //c代表负
t[1]=~t[1]; /*下面几句把负数的补码*/
t[0]=~t[0]; /*换算成绝对值*********/
x=t[0]+1;
t[0]=x;
if(x==0x00)t[1]++;
}
else TempBuffer1[0]=0x0a; //A代表正
t[1]《《=4; //将高字节左移4位
t[1]=t[1]&0xf0;
x=t[0]; //将t[0]暂存到X,因为取小数部分还要用到它
x》》=4; //右移4位
x=x&0x0f; //和前面两句就是取出t[0]的高四位
y=t[1]|x; //将高低字节的有效值的整数部分拼成一个字节
TempBuffer1[1]=(y%100)/10;
TempBuffer1[2]=(y%100)%10;
t[0]=t[0]&0x0f; //小数部分
TempBuffer1[3]=t[0]*10/16;
//以下程序段消去随机误检查造成的误判,只有连续12次检测到温度超出限制才切换加热装置
if(currtemp》Tmin)xiaodou1=0;
if(y《Tmin)
{
xiaodou1++;
currtemp=y;
xiaodou2=0;
}
if(xiaodou1》12)
{
out=0;
flag=1;
xiaodou1=0;
}
if(currtemp《Tmax)xiaodou2=0;
if(y》Tmax)
{
xiaodou2++;
currtemp=y;
xiaodou1=0;
}
if(xiaodou2》12)
{
out=1;
flag=0;
xiaodou2=0;
}
out=flag;
}
void convert(char tmp)
{
uchar a;
if(tmp《0)
{
TempBuffer1[0]=0x0c;
a=~tmp+1;
}
else
{
TempBuffer1[0]=0x0a;
a=tmp;
}
TempBuffer1[1]=(a%100)/10;
TempBuffer1[2]=(a%100)%10;
}
void keyscan( )
{
uchar keyin;
keyin=P1&0x07;
if(keyin==0x07)return;
else if(keymd==0)
{
dismod++;
dismod%=3;
while(keymd==0);
switch(dismod)
{
case 1:
convert(Tmax);
TempBuffer1[3]=0x11;
break;
case 2:
convert(Tmin);
TempBuffer1[3]=0x12;
break;
default:
break;
}
}
else if((keyup==0)&&(dismod==1))
{
Tmax++;
convert(Tmax);
while(keyup==0);
}
else if((keydn==0)&&(dismod==1))
{
Tmax--;
convert(Tmax);
while(keydn==0);
}
else if((keyup==0)&&(dismod==2))
{
Tmin++;
convert(Tmin);
while(keyup==0);
}
else if((keydn==0)&&(dismod==2))
{
Tmin--;
convert(Tmin);
while(keydn==0);
}
xiaodou1=0;
xiaodou2=0;
}
main()
{
TMOD=0x01;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
ET0=1;
EA=1;
out=1;
flag=0;
ReadTemperature(0x3f);
delay_18B20(50000); //延时等待18B20数据稳定
while(1)
{
pt=ReadTemperature(0x7f); //读取温度,温度值存放在一个两个字节的数组中
if(dismod==0)covert1();
keyscan();
delay_18B20(30000);
}
}
ds18b20温度数据怎么换算?
高五位S为符号位,分辨率为0.0625。正温度把16进制数转成10进制即可;负温度把16进制数取反后加1再转成10进制数,第一个是00FA是(15*16+10)*0.0625=15.62度,第二个是0032是(3*16+2)*0.0625=3.125度(负的)
a=read_byte(); //读取温度低八位的数据
b=read_byte(); //读取温度高八位的数据
t =(b*256+a)*25;
return(t》》2)
*25/4=6.25,DS18B20的分辨率是0.0625度,这里是保留了两位小数位,所以0.0625*100=6.25。详细解释一下:t》》2是右移的意思,就是把你的二进制数右移2位。通俗点讲,如果你把十进制数1234右移2位成了12.34变为原来的1/100倍,那把二进制数右移2位就是变为原来的1/4倍,所以25和t》》2是调整精度是25/4倍。
DS18B20温度读取及显示如下:
登录/注册后可看大图
#include《reg51.h》
#define uchar unsigned char
#define uint unsigned int
#define wela P2
#define dula P0
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
sbit DS=P3^7;
void delay6us(uchar z){
while(z--);
}
void delayms(uchar z){
uchari,j;
for(i=0;i《z;i++)
for(j=0;j《160;j++);
}
void init(){
ucharpresence=1;
while(presence){
DS=0;
delay6us(80);//延时480us以上
DS=1;
delay6us(15);
if(DS==0){
presence=0;
while(DS==0);
}
else
presence=1;
}
}
uchar ds_read(){
ucharbyt,bi;
uchari;
for(i=0;i《8;i++){
DS=0;
delay6us(1);
DS=1;
delay6us(1);
bi=DS;
byt=(byt》》1)|(bi《《7);
delay6us(11);
}
returnbyt;
}
void ds_write(uchar ch){
uchari;
for(i=0;i《8;i++){
DS=0;
delay6us(1);
DS=ch&0x01;
delay6us(11);
DS=1;
delay6us(1);
ch》》=1;
}
}
void DSchange(){
DS=1;
init();
ds_write(0xcc);
ds_write(0x44);
}
void DSreadtempcom(){
DS=1;
init();
ds_write(0xcc);
ds_write(0xbe);
}
uint DSreadtemp(){
inttemp=0;
uchartmh,tml;
DSchange();
delayms(1);
DSreadtempcom();
tml=ds_read();
tmh=ds_read();
DS=1;
temp=tmh;
temp《《=8;
temp|=tml;
returntemp;
}
void display(uint wendu){
ucharbai,shi,ge,sfen,bfen,qfen;
uchars,tp,th,tl;
uintxs,flag;
flag=wendu&0x8000;
if(flag!=0)
wendu=~(wendu-1);
th=wendu/256;
tl=wendu%256;
s=tl&0x0f;
xs=0.0625*s*1000;
th《《=4;
tl》》=4;
tp=th|tl;
bai=tp/100;
shi=(tp%100)/10;
ge=tp%10;
sfen=xs/100;
bfen=(xs%100)/10;
qfen=xs%10; //显示的百位十位个位以及小数点后三位
wela=0;
if(flag!=0){
dula=0x40; //显示负号
}else
dula=0x00;
delayms(10);
wela=1;
if(bai!=0){
dula=table[bai];
}else
dula=0x00;
delayms(10);
wela=2;
dula=table[shi];
delayms(10);
wela=3;
dula=table[ge]|0x80; //加小数点
delayms(10);
wela=4;
dula=table[sfen];
delayms(10);
wela=5;
dula=table[bfen];
delayms(10);
wela=6;
dula=table[qfen];
delayms(10);
}
void main(){
uinttemp;
while(1){
temp=DSreadtemp();
display(temp);
}
}
《《《 点击这里展开全文 》》》
回复
使用道具
举报
禁止用系统自带的
Edge浏览器下载资料。否则下载失败浪费积分。
q46651772
|
2021-8-26 11:14:59
|
显示全部楼层
《《《 点击这里展开全文 》》》
回复
使用道具
举报
禁止用系统自带的
Edge浏览器下载资料。否则下载失败浪费积分。
wangtaoyuan
|
2021-8-27 08:59:33
|
显示全部楼层
《《《 点击这里展开全文 》》》
回复
使用道具
举报
wangtaoyuan
|
2021-8-27 09:00:09
|
显示全部楼层
《《《 点击这里展开全文 》》》
回复
使用道具
举报
返回列表
发新帖
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
本版积分规则
发表回复
回帖后跳转到最后一页
浏览过的版块
作品文件展(二级)
终身成就奖
谢谢您为社区发展做出的不可磨灭的贡献!!
1007734076
5
主题
3
回帖
7
积分
一级逆天
一级逆天, 积分 7, 距离下一级还需 93 积分
一级逆天, 积分 7, 距离下一级还需 93 积分
积分
7
加好友
发消息
回复楼主
返回列表
作品文件展(二级)
作品(没截图)(二级)
作品图片展
原理图共享
封装库共享
项目开源
PDF电子书
求资料
网盘资料大杂烩
图文推荐
申请第4节课,谢谢
3 天前
申请第三节课录像
3 天前
5.1 申请第四节课录像
3 天前
申请第二阶段的录像
3 天前
申请allegro第三课培训录像
3 天前
热门排行
1
PADS9.5完整版+破解文件+安装教程 免费下载(2021年更新)
2
PADS 9.5 破解版 破解文件下载,注册文件下载,和谐
3
逆天PCB论坛-服务器大量共享资料
4
PADS 9.5 全中文版本出来了,PADS9.5 完整版免费下载
5
新手必学的原理图
6
pads9.5实战攻略与高速pcb设计.pdf 高清扫描版[完整
7
论坛会员人数20万,发一波福利,500个名额,每人80金币
8
史上最强精品PADS视屏,电子,PDF各种格式教程大全
9
回帖奖励-每人100金币-先到先得-200个名额
10
PADS9.5 视频教程百度网盘高速下载,在线看[精讲]-重新补充