专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
51单片机
这两天写的一个程序 3个点的18B20采集温度,采用 搜索ROM的方法 读取温度
2020-02-02 09:30
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
51单片机
21603
35
35
本人新手,把程序贴出来 希望大家给指出一些错误和不足,先谢谢大家
写完后总感觉程序代码有些繁琐,但自己又说不上来是哪里,大家给看看哈.....
-----------
里面的ROM算法借鉴采用的是-- 黑龙江大学 刘全义同学----的代码,在此声明
代码:
点击此处下载
ourdev_577281.rar(文件大小:65K)
(原文件名:ROM搜索版.rar)
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
34条回答
lcw_swust
1楼-- · 2020-02-06 20:55
从DS18B20的英文手册里可以看到关于search rom指令的例子,大概就是:复位->写SEARCH ROM指令->读两个位->写一个位->读下两位->写下一个位......->写第64位
其中,"读两个位"对于单个18B20来说是先返回ROM的第一个位,再返回该位的补码;如果有多个18B20,由于"线与"逻辑,如果有一个18B20返回0,那么数据线上得到的数据就为0;所以可能有四种情况:
读第一位 读第二位
0 0 :多个18B20的ROM第一位不一样
0 1 :ROM第一位为0
1 0 :ROM第一位为1
1 1 :未连接18B20
"写一个位"对于18B20来说,只有该位与自身的ROM位相等才会保持连接,否则对后面的读或写都忽略了.
所以,对于读出的两个位都为0的地方就要分别写0写1来区分不同的18B20了.
程序已经在楼主给的资料里了
//搜索ROM函数
bit Search_Rom()
{
uchar r1=0,r2=0,m=0,n=0;
uchar l=0;//栈长度
uchar stack_node_pos[MAXNUM+1]={0}; //保存最后差异值位置 与栈顶值比较
uchar node_pos=0; //产生差异值时的位置
uchar rom[64]={0};//一次搜索中的位数
uchar s=0;
l=0;
num_18b20=0; //搜索前清0器件数目
do
{
Reset_18b20();
WriteByte(0xf0);
for(m=0;m<8;m++)
{ s=0;
for(n=0;n<8;n++)
{
s>>=1;
r1=read_bit();//当前位
r2=read_bit();//补码
if(r1==0&&r2==1)
{
write_bits(0);
rom[(m*8+n)]=0;
}
else
if(r1==1&&r2==0)
{
s=s|0x80;
write_bits(1);
rom[(m*8+n)]=1;
}
else
if(r1==0&&r2==0) //有多个从机产生了差异值
{
node_pos=m*8+n+1; //记录产生差异值的位置
//差异值与最后一次差异值位置比较
if(node_pos>stack_node_pos[l]) //新路径 新的差异值
{
write_bits(0); //选择发送0
rom[(m*8+n)]=0; //记录
stack_node_pos[++l]=node_pos; //记录新的差异值位置
}
else if(node_pos<stack_node_pos[l]) //老路径
{
s=s|((rom[(m*8+n)]&0x01)<<7); //发送保存上一次的位
write_bits(rom[(m*8+n)]);
}
else if(node_pos==stack_node_pos[l]) //最后一次差异值的位置
{ //最后一次分叉选择 发1 删除改栈
s=s|0x80;
write_bits(1);
rom[(m*8+n)]=1;
l=l-1; //从栈里删除该值
}
}
else
{ //无从机连接 退出返回0
return 0;
}
}
ROM_ID[num_18b20][m]=s; //循环8次保存一字节
}
num_18b20=num_18b20+1;
}while(stack_node_pos[l]!=0&&num_18b20<MAXNUM);
return 1;
}
加载中...
dengxingling8
2楼-- · 2020-02-06 22:58
借鉴一下啊
加载中...
wctmdgcd
3楼-- · 2020-02-07 01:18
这个必须有。
加载中...
wpnx
4楼-- · 2020-02-07 05:31
mark
加载中...
上一页
1
2
3
4
5
6
一周热门
更多
>
相关问题
【东软载波ESF0654 PDS开发板活动】开箱
1 个回答
东软载波ESF0654 PDS开发板外部中断
1 个回答
东软载波ESF0654 PDS开发板高级控制定时器AD16C4T
1 个回答
用串口调试助手为什么只能在hex模式接收发送而在文本模式不行
9 个回答
触摸芯片SC02B/SC04B在地砖灯的设计方案
1 个回答
东软载波ESF0654 PDS开发板串口USART0代码分享
1 个回答
普通32位单片机使用linux的应用代码
5 个回答
东软载波ESF0654 PDS开发板AT24C04的调试
9 个回答
相关文章
51单片机与蓝牙模块连接
0个评论
51单片机的硬件结构
0个评论
基于51单片机的无线遥控器制作
0个评论
51单片机 AD转换
0个评论
51单片机数码管递增显示
0个评论
如何实现对单片机寄存器的访问
0个评论
基于51单片机的指纹密码锁
0个评论
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
51单片机
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
其中,"读两个位"对于单个18B20来说是先返回ROM的第一个位,再返回该位的补码;如果有多个18B20,由于"线与"逻辑,如果有一个18B20返回0,那么数据线上得到的数据就为0;所以可能有四种情况:
读第一位 读第二位
0 0 :多个18B20的ROM第一位不一样
0 1 :ROM第一位为0
1 0 :ROM第一位为1
1 1 :未连接18B20
"写一个位"对于18B20来说,只有该位与自身的ROM位相等才会保持连接,否则对后面的读或写都忽略了.
所以,对于读出的两个位都为0的地方就要分别写0写1来区分不同的18B20了.
程序已经在楼主给的资料里了
//搜索ROM函数
bit Search_Rom()
{
uchar r1=0,r2=0,m=0,n=0;
uchar l=0;//栈长度
uchar stack_node_pos[MAXNUM+1]={0}; //保存最后差异值位置 与栈顶值比较
uchar node_pos=0; //产生差异值时的位置
uchar rom[64]={0};//一次搜索中的位数
uchar s=0;
l=0;
num_18b20=0; //搜索前清0器件数目
do
{
Reset_18b20();
WriteByte(0xf0);
for(m=0;m<8;m++)
{ s=0;
for(n=0;n<8;n++)
{
s>>=1;
r1=read_bit();//当前位
r2=read_bit();//补码
if(r1==0&&r2==1)
{
write_bits(0);
rom[(m*8+n)]=0;
}
else
if(r1==1&&r2==0)
{
s=s|0x80;
write_bits(1);
rom[(m*8+n)]=1;
}
else
if(r1==0&&r2==0) //有多个从机产生了差异值
{
node_pos=m*8+n+1; //记录产生差异值的位置
//差异值与最后一次差异值位置比较
if(node_pos>stack_node_pos[l]) //新路径 新的差异值
{
write_bits(0); //选择发送0
rom[(m*8+n)]=0; //记录
stack_node_pos[++l]=node_pos; //记录新的差异值位置
}
else if(node_pos<stack_node_pos[l]) //老路径
{
s=s|((rom[(m*8+n)]&0x01)<<7); //发送保存上一次的位
write_bits(rom[(m*8+n)]);
}
else if(node_pos==stack_node_pos[l]) //最后一次差异值的位置
{ //最后一次分叉选择 发1 删除改栈
s=s|0x80;
write_bits(1);
rom[(m*8+n)]=1;
l=l-1; //从栈里删除该值
}
}
else
{ //无从机连接 退出返回0
return 0;
}
}
ROM_ID[num_18b20][m]=s; //循环8次保存一字节
}
num_18b20=num_18b20+1;
}while(stack_node_pos[l]!=0&&num_18b20<MAXNUM);
return 1;
}
一周热门 更多>