ds18b20温度传感器驱动编写

协议

DS18B20的一线工作协议流程是:初始化→ROM操作指令→存储器操作指令→数据传输,其工作时序包括:初始化时序、写时序、读时序。
在这里插入图片描述
在这里插入图片描述
黑色部分表示单片机操作,蓝色部分表示18b20操作,每次主机操作完成之后等待18b20状态时,必须要释放总线,比如将IO设置为高阻态什么的。否则18B20没法把状态写到线上。

过程1、2是初始化过程,每次读取都要初始化,否则18b20处于待机状态,无法成功读取。过程1:拉低信号线480-700us,使它复位,然后释放总线15-60us,18b20会拉低总线60-240us,然后它释放总线。所以初始化成功的一个标志就是能否读到18b20这个先低后高的操作时序。

与之对应的代码,其实是按照时序图编写的:
注意观察dq,
DQ=0;TempDelay(80);拉低信号线480-700us,使它复位,对应时序图上黑色线一开始为0.
DQ=1; TempDelay(5);释放总线15-60us,对应时序图上黑色线变成1.
然后如果18b20拉低总线,说明初始化成功

   if(DQ==0)flag=1;       //detect 18b20 successelseflag=0;       //detect 18b20 fail

复位的整体代码:

void ds_reset(void)//复位函数
{DQ=1;_nop_();        //1usDQ=0;TempDelay(80);  //当总线停留在低电平超过480us,总线上所以器件都将被复位,这里//延时约530us总线停留在低电平超过480μs,总线上的所有器件都//将被复位。延时的数据取决于芯片 _nop_(); DQ=1;           //产生复位脉冲后,微处理器释放总线,让总线处于空闲状态,原因查//18b20中文资料TempDelay(5);  //释放总线后,以便从机18b20通过拉低总线来指示其是否在线,//存在检测高电平时间:15~60us, 所以延时44us,进行1-wire presence //detect(单线存在检测)_nop_();_nop_();_nop_();if(DQ==0)flag=1;       //detect 18b20 successelseflag=0;       //detect 18b20 failTempDelay(20);    //存在检测低电平时间:60~240us,所以延时约140us_nop_();_nop_();DQ=1;          //再次拉高总线,让总线处于空闲状态
/**/
}

过程3、4是写1bit数据过程。过程3是写0 ,过程4是写1。过程3:拉低总线60us,然后抬高总线5us,完成。过程4:拉低总线5us,然后抬高总线60us,完成。
过程5、6是读1bit过程。过程5是读0,过程6是读1。过程5、6:拉低总线5us,然后释放总线,读取总线,如果为0,则读入0,如果为1,则读入1。

由于我主要研究的是怎么把数据导出来,所以主要看:发送温度转换命令和获得温度这两个函数:

发送温度转换命令
------------------------------------------*/void tem_change()
{ds_reset(); delay(1);              //约2msds_write_byte(0xcc);ds_write_byte(0x44);
}/*----------------------------------------
获得温度:
------------------------------------------*/
uint get_temperature()
{float wendu;uchar a,b;ds_reset();delay(1);              //约2msds_write_byte(0xcc);ds_write_byte(0xbe);a=ds_read_byte();b=ds_read_byte();temp=b;temp<<=8;temp=temp|a;wendu=temp*0.0625;     //温度读取temp=wendu*10+0.5;return temp;
}

让DS18B20进行一次温度转换的具体操作如下:
  1、主机先做个复位操作;
  2、主机再写跳过ROM的操作(CCH)命令;
  3、然后主机接着写转换温度的操作指令,后面释放总线至少1秒,让DS18B20完成转换操作。需要注意的是每个命令字节在写的时候都是低字节先写,例如CCH的二进制为11001100,在写到总线上时要从低位开始写,写的顺序是“0、0、1、1、0、0、1、1”。

上面让DS18B20进行一次温度转换就涉及到 ds_write_byte()写操作

读取RAM的温度数据,同样,这个操作也要按照三个步骤:
  1、主机发出复位操作并接受DS18B20的应答(存在)脉冲;
  2、主机发出跳过对ROM操作的命令(CCH);
  3、主机发出读取RAM的命令(BEH),随后主机依次读取DS18B20发出的从第0-第8,共九个字节的数据。如果只想读取温度数据,那在读完第0和第1个数据后就不再理会后面DS18B20发出的数据即可,同样读取数据也是低位在前.
  
获得温度的时候,又涉及到了ds_read_byte();读操作

结构

在这里插入图片描述
在这里插入图片描述
由上图可知,读温度时要读两次,一个是低8位,一个是高8位。最后要合到一块。

  ds_write_byte(0xcc);ds_write_byte(0xbe);a=ds_read_byte();b=ds_read_byte();temp=b;temp<<=8;temp=temp|a;

测温原理
在这里插入图片描述
低温度系数振荡器温度影响小,用于产生固定频率信号送计数器1;
高温度系数振荡频率随温度变化,产生信号脉冲送计数器2;
计数器1和温度寄存器被预置在 -55℃对应的基数值;
计数器1对低温度系数振荡器产生的脉冲进行减法计数;
当计数器1预置减到0时,温度寄存器加1,计数器1预置重新装入;
计数器1重新对低温度系数振荡器计数;
如此循环,直到计数器2计数到0时,停止对温度寄存器累加,此时温度寄存器中的数值即为所测温度。
高温度系数振荡器相当于T/ f 转换器,将被测温度转换成频率信号f ;
当门打开时对低温度系数振荡器计数;
计数门的开启时间有高温度系数振荡器决定。

指令

18B20内部自带5个ROM指令、6条专用指令ROM指令; Read ROM(33h), 读ROM
Match ROM(55h),  比较
Skip ROM(CCh),    跳过ROM
Search ROM(F0h), 搜索、查找
Alarm ROM(ECh), 报警专用指令;Write Scratchpad[便签式](4Eh),  写便签RAM
Read Scratchpad(BEh),                    读数据
Copy Scratchpad(48h),                     复制
Convert T(44h),                                 启动转换
Recall E2(B8h),                                 搜索、调用 
Read Power Supply(B4h),             读电源电压

代码:

/*--------------------------------------------------------------------------------------------------------------------
初始化:检测总线控制器发出的复位脉冲
和ds18b20的任何通讯都要从初始化开始初始化序列包括一个由总线控制器发出的复位脉冲
和跟在其后由从机发出的存在脉冲。初始化:复位脉冲+存在脉冲具体操作:总线控制器发出(TX)一个复位脉冲 (一个最少保持480μs 的低电平信号),然后释放总线,
进入接收状态(RX)。单线总线由5K 上拉电阻拉到高电平。探测到I/O 引脚上的上升沿后
DS1820 等待15~60μs,然后发出存在脉冲(一个60~240μs 的低电平信号)。-------------------------------------------------------------------------------------------------------------------*/
void ds_reset(void)//复位函数
{DQ=1;_nop_();        //1usDQ=0;TempDelay(80);  //当总线停留在低电平超过480us,总线上所以器件都将被复位,这里//延时约530us总线停留在低电平超过480μs,总线上的所有器件都//将被复位。延时的数据取决于芯片 _nop_(); DQ=1;           //产生复位脉冲后,微处理器释放总线,让总线处于空闲状态,原因查//18b20中文资料TempDelay(5);  //释放总线后,以便从机18b20通过拉低总线来指示其是否在线,//存在检测高电平时间:15~60us, 所以延时44us,进行1-wire presence //detect(单线存在检测)_nop_();_nop_();_nop_();if(DQ==0)flag=1;       //detect 18b20 successelseflag=0;       //detect 18b20 failTempDelay(20);    //存在检测低电平时间:60~240us,所以延时约140us_nop_();_nop_();DQ=1;          //再次拉高总线,让总线处于空闲状态
/**/
}/*----------------------------------------
读/写时间隙:
DS1820 的数据读写是通过时间隙处理
位和命令字来确认信息交换。
------------------------------------------*/
bit  ds_read_bit(void)    //读一位
{bit dat;DQ=0;         //单片机(微处理器)将总线拉低_nop_();       //读时隙起始于微处理器将总线拉低至少1usDQ=1;        //拉低总线后接着释放总线,让从机18b20能够接管总线,输出有效数据_nop_();_nop_();          //小延时一下,读取18b20上的数据 ,因为从ds18b20上输出的数据//在读"时间隙"下降沿出现15us内有效dat=ds;           //主机读从机18b20输出的数据,这些数据在读时隙的下降沿出现//15us内有效 TempDelay(10);    //所有读"时间隙"必须60~120us,这里77usreturn(dat);       //返回有效数据
}
///
uchar ds_read_byte(void ) //读一字节
{uchar value,i,j;
value=0;           //一定别忘了给初值
for(i=0;i<8;i++)
{j=ds_read_bit();value=(j<<7)|(value>>1);   //这一步的说明在一个word文档里面
}
return(value);        //返回一个字节的数据
}//
void ds_write_byte(uchar dat) //写一个字节
{uchar i;bit onebit;        //一定不要忘了,onebit是一位for(i=1;i<=8;i++) {onebit=dat&0x01;dat=dat>>1;
if(onebit)      //写 1
{
DQ=0;
_nop_();    _nop_();      //看时序图,至少延时1us,才产生写"时间隙"  
DQ=1;       //写时间隙开始后的15μs内允许数据线拉到高电平TempDelay(5);  //所有写时间隙必须最少持续60us
}
else         //写 0
{
DQ=0;TempDelay(8); //主机要生成一个写0 时间隙,必须把数据线拉到低电平并保持至少60μs,这里64us
DQ=1;
_nop_();_nop_();
}}
}/***************************************** 
主机(单片机)控制18B20完成温度转换要经过三个步骤:
每一次读写之前都要18B20进行复位操作,复位成功后发送
一条ROM指令,最后发送RAM指令,这样才能对DS18b20进行
预定的操作。
复位要求主CPU将数据线下拉500us,然后释放,当ds18B20
受到信号后等待16~60us,后发出60~240us的存在低脉冲,
主CPU收到此信号表示复位成功
******************************************/ /*----------------------------------------
进行温度转换:
先初始化
然后跳过ROM:跳过64位ROM地址,直接向ds18B20发温度转换命令,适合单片工作
发送温度转换命令
------------------------------------------*/void tem_change()
{ds_reset(); delay(1);              //约2msds_write_byte(0xcc);  //跳过romds_write_byte(0x44); //启动转换
}/*----------------------------------------
获得温度:
------------------------------------------*/
uint get_temperature()
{float wendu;uchar a,b;ds_reset();delay(1);              //约2msds_write_byte(0xcc);ds_write_byte(0xbe);a=ds_read_byte();b=ds_read_byte();temp=b;temp<<=8;temp=temp|a;wendu=temp*0.0625;     //温度读取temp=wendu*10+0.5;return temp;
}
/*----------------------------------------
读ROM   
------------------------------------------*/
void ds_read_rom()                  
{uchar a,b;ds_reset();delay(30);ds_write_byte(0x33);a=ds_read_byte();b=ds_read_byte();
}void main()
{while(1){tem_change();          //12位转换时间最大为750msdisplay( get_temperature());}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/560391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SHT1x/SHT7x数字温湿度传感器驱动编写

结构图 启动传输时序图 SHT10串行通信IO初始化 其中SDA和SCL分别是数据线和时钟线。分别对应单片机的1.1口和1.0口 #define SCL P1_0 //SHT10时钟 #define SDA P1_1 //SHT10数据线由时序图可知&#xff0c;一开始SDA和SCL分别高电平和低电平 /****…

zigbee板子:lcd显示汉字

main函数 #include <ioCC2530.h> #include "LCD.h"void main() {//unsigned char i0; LCD_Init(); //oled 初始化 LCD_CLS(); //屏全亮 LCD_welcome();while(1){} } 首先呢。我们运行这个程序&#xff0c;然后可…

matlab实时采集串口数据并分析串口数据传送格式

下位机 zigbee代码 最近在做基于zigbee的RSSI实时定位系统。这个系统需要我们实时的测量得到每一个位置的rssi值。首先&#xff0c;我需要研究怎么把这个rssi值通过串口传到我们的上位机上。 我们可以看到我们下位机&#xff0c;里面有一个传送数据包的一个东西&#xff0c;在…

matlab guide 打开图像并将图像显示到界面

最近又用到matlab做GUI&#xff0c;之前学的全忘了&#xff0c;还好两年前留了大实验源码。 下面我来通过源码分析一下matlab怎么做GUI。这次我来分析如何通过matlab打开图像并将图像显示到界面。 实验效果 原理 打开菜单编辑器看这个属性&#xff1a; 找到回调 可以看到回调…

matlab guide 将matlab处理过的图片保存

最近又用到matlab做GUI&#xff0c;之前学的全忘了&#xff0c;还好两年前留了大实验源码。 这次我来分析如何将matlab处理过的图片保存。 实验效果 经过灰度转换&#xff0c;图象被处理&#xff0c;并显示到另一个地方。 点击保存 图片被保存 实验原理 查看保存的回调函…

深圳linux测试题库,Linux认证考试题库及答案

Linux认证考试题库及答案1、一个文件的权限是-rw-rw-r--&#xff0c;这个文件所有者的权限是什么()a、read-onlyb、read-writec、write答案 b2、下面哪个值代表多用户启动()a、1b、0c、3d、5答案 c3、下面哪个文件代表系统初始化信息()a、/etc/inittabb、/etc/initc、/etc/proc…

matlab guide 打开excel并对其中数据进行处理

最近又用到matlab做GUI&#xff0c;之前学的全忘了&#xff0c;还好两年前留了大实验源码。 这次我来分析如何通过matlab处理excel数据 实验结果 对excel处理的效果&#xff1a; 实验原理 打开excel回调函数 function openexc_Callback(hObject, eventdata, handles) [fil…

linux 显示文件名写到txt,C++获取某个路径下所有文件的文件名,读写TXT文件到新的文件...

好久没写io操作了&#xff0c;手生了好多&#xff0c;最简单实用的C代码也push上来吧。环境&#xff1a;mac&#xff0c;xcode(注意mac环境下Windows的函数不能用)功能&#xff1a;打开一个文件目录&#xff0c;把所有文件名读取到一个TXT文件中#include #include #include #in…

生成超清分辨率视频,南洋理工开源Upscale-A-Video

大模型在生成高质量图像方面表现出色,但在生成视频任务中&#xff0c;经常会面临视频不连贯、图像模糊、掉帧等问题。 这主要是因为生成式抽样过程中的随机性,会在视频序列中引入无法预测的帧跳动。同时现有方法仅考虑了局部视频片段的时空一致性,无法保证整个长视频的整体连贯…

matlab 文件之间相互调用实例

效果&#xff1a; 找到按钮的回调 function pushbutton1_Callback(hObject, eventdata, handles) cd Deploy Nodes %square_random(100,100,0.03);%布置节点 GPS误差为0 %square_random(1000,300,0.2,30) %GPS误差为30m %C_random([1000,300,300,700],240,0.2); square_regul…

linux+虚拟机上的wdcp,linux虚拟主机服务器wdcp系统教程

满意答案eslct2017.01.29采纳率&#xff1a;47% 等级&#xff1a;9已帮助&#xff1a;1264人linux虚拟主机服务器wdcp系统教程在我们安装了网络服务管理系统wdcp后&#xff0c;可能会有不少疑问还有就是使用过程中出现的问题&#xff0c;下面为大家总结几点比较常见的&#…

matlab guide实现多级界面

matlab如何实现多级界面呢&#xff1f;也就是说&#xff0c;在一个界面点击某个地方&#xff0c;就弹出来另一个界面&#xff0c;在另一个界面还可以再进行操作。 实验结果 实验原理 首先建立两个gui&#xff0c;并且每个gui都进行如下设置&#xff1a; 然后我们找到test.f…

常见积分和导数的推导

导数&#xff1a; 1.yarcsinxyarcsinxyarcsinx的导数&#xff1a; yarcsin⁡x→xsin⁡y→1y′cos⁡y→y′1cos⁡y→y′11−x2\\y\arcsin x\\ \rightarrow x\sin y\\ \rightarrow 1{y}\cos y\\ \rightarrow {y}\frac{1}{\cos y}\\ \rightarrow {y}\frac{1}{\sqrt{1-x^{2}}}yarc…

c语言函数调用排序用插入法,C语言:编写查找和排序函数(二分查找,冒泡排序,选择排序法,插入排序)...

任务代码&#xff1a;二分查找数组的一个数字&#xff1a;(函数法)#include int binarySearch(int a[],int len,int key){int low0,highlen-1,mid;int i-1;//相当于indexwhile(low<high){mid(lowhigh)/2;if(a[mid]key){imid;break;}else if(key>a[mid]){lowmid1;}else{hi…

常用于解决放缩问题的基本不等式及其几何直观证明

考研中遇到放缩问题就需要用到不等式&#xff1a; 一般放缩的地方就是夹逼准则&#xff0c;还有判断多元函数极限是否存在。 基本不等式&#xff1a; (调和均值 ≤ 几何均值 ≤ 算术均值 ≤ 平方均值) 当且仅当ab时等号成立。 基本不等式的几何直观证明&#xff1a; 基本不…

c语言 连接哨兵 redis6,Redis哨兵--缓存服务器

redis哨兵说明:通过缓存服务器可以有效的提升用户的访问效1.注意事项:A:缓存的数据结构应该选用K-V结构,只要K唯一那么结果必然相同B:缓存总的数据不可能一直储存,需要定期将内存数据进行优化,LRU算法....C:缓存的运行数据要求要快,C语言实现... 运行在内存中D:如果缓存运行的数…

复数和复变指数函数和三角函数和欧拉公式关系及几何直观意义

证明欧拉公式 如果这么看自变量&#xff1a;θωt\theta \omega t θωt那么就可以发现欧拉公式的几何意义。 复数的表示形式 通过下面对比可以发现&#xff0c;用复指数表示复数在几何上更直观。 复数的运算 1.加法运算 设z1abi&#xff0c;z2cdi是任意两个复数&#xf…

利用DHT22和Arduino测量温湿度并显示在串口和OLED显示屏上

实验结果 温湿度显示在串口&#xff1a; 温湿度显示在OLED屏幕&#xff1a; 实验代码 #include "U8glib.h" #include "DHT.h"U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE); #define DHTTYPE DHT22 // DHT 22 (AM2302) #define DHTPIN 2 // wh…

Altium Designer20新建项目\导入库\绘制原理图\导入pcb\绘制pcb

1.新建项目 2.新建原理图和PCB 3.新建原理图库和pcb库 4.导入原理图库和pcb库 点击如图所示 然后点击安装&#xff0c;找到需要安装的位置&#xff0c;打开 然后在下拉框里就可以找到&#xff0c;并选择外部的库 5.绘制原理图 在Components里面选择一个库然后找元器件 然…

红魔1android版本能升到多少,红魔5G:实力全开,比快更快

红魔5G&#xff1a;实力全开&#xff0c;比快更快2020-03-20 20:37:090点赞0收藏0评论在当代年轻人的生活里&#xff0c;手游似乎已经成为必不可少的一部分&#xff1a;心情不好来一局、初次见面来一局、闲来无事来一局。各大手机厂商洞察到这一点&#xff0c;纷纷推出针对手游…