有关于iic以及ds18b20驱动的解读Word格式文档下载.docx
《有关于iic以及ds18b20驱动的解读Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《有关于iic以及ds18b20驱动的解读Word格式文档下载.docx(15页珍藏版)》请在冰豆网上搜索。
SDA才开始由高电平变为低电平,在低电平的这段时间查表就可知,这个起始信号保持的时间至少是4us。
那么我们就可以在写驱动的时候将这两个信号的时间都保持在5us左右。
通过宏定义就能够得到了这个比较精确一点的时间了。
这样我们的这个起始信号的驱动程序就能够非常简单的写出来了。
如下图所示:
(至于为什么在最前面显示使用SCL线为低电平,SDA线为高电平,然后SCL线又为低电平。
本人也有考虑过这样做是不是多了一步,直接将第一步删除不是一样的吗?
但是驱动是跟协议紧密联系在一起的,要养成这样的一个习惯。
这个启动是为了与其他的驱动进行配合使用的。
这样就能够起到衔接其他启动程序的母的。
)
2、停止信号:
通过查询上面的时间表就可以知道,停止信号的保持时间最少是4us。
因为之前的时间我们已经通过宏定义了一个5us的。
所以就使用这个5us的也没有什么影响。
有图可知在SCL为高电平期间,SDA由低电平变为高电平就暗示着器件之间的通讯就已经结束了。
细节上面也是要注意。
完全按照时序图所画的时间来写驱动。
在看到时序图上的时间间隔是尽量保持的时间长一点。
3、应答信号:
应答信号就是在主机向器件传送一个字节的数据或者是器件向主机传送一个字节的数据完之后,发送一个应答信号,时序图如下所示:
根据上面的时序图就可以知道,在发送完一个字节的数据,紧跟着第九个时钟周期就发送应答信号,发送方会将数据线拉高,但是接收方在接收到这个字节的数据以后要将数据线拉低,以此来表示应答。
由手册中的这句话我们就可以知道如果接收方在第九个时钟周期没有将SDA数据线拉低,那么发送方就会停止发送数据并等待停止信号。
如果接收到了应答信号就会继续发送数据。
驱动程序如下所示。
如果在SCL为高电平期间,释放SDA数据线。
等待接收方将数据线拉低。
如果SDA一直为高电平的话就停止继续发送数据,并且发送一个停止信号。
如果数据线被拉低了。
说明此时已经产生应答信号了,此时再将数据线拉高,释放数据线。
并且在执行完以后就将SCL置低,以此来结束这个时钟周期。
4、发送一个字节。
有手册中的这段话就可以知道,只有在总线空闲是才能够传送数据,只有在SCL为低电平期间SDA线才允许产生跳动。
数据才允许进行传送。
由上面的这张图我们就可以知道了。
在SDA上的第八个字节的数据传送完了以后就必须要吧时钟线拉低,然后才能有应答信号过来。
这个是我们特别需要注意的地方。
接下来就讲一讲这个驱动程序。
首先肯定是将SCL拉低,然后传动数据,数据的传送是由高位至低位以此进行的,通过将这个char型的一个字节的数据进行以此与,可以获得各个为上的数据,在执行了八次以后要跳出这个for循环,并且要特别注意的是,将时钟线拉低,否则无法进行接下来的数据传送。
5、读出一个字节
由之前对手册上的时序图理解,我们知道,在时钟线为高电平的时候数据线上的数据是保持稳定的,这个时候就可以将数据线上的数据反馈回来,然后整理一下得到数据。
同样由图可知,在高电平期间我们就可以读出我们所要的数据。
程序如下图所示:
在SCL为高电平期间,我们可以将数据线上的数据读出来,然后在传送给主机进行整理,识别,最后将SCL线置低,等待数据线上的数据再次传送过来,就这样通过for循环以此由高到低的得到这个一个字节的数据。
最后返回这一个字节的数据。
至于时间我们都可以通过那个时间表查出来的。
由此,我们所有的驱动程序就已经写完了。
这个时候就要开始进行写协议了。
这样我们才能真正灵活的操控这款芯片。
6、在这款芯片的任意一个地址空间写一个字节:
通过手册上的协议表就可以得到写任意一个地址空间的字节数据的协议程序了。
7、读出这款芯片的任意一个空间的数据:
我们通过查看数据手册就可以知道读一个字节有许多的方式。
有立即地址读、还有选择性读、还有连续读。
我们就来谈论里面用的比较多的一个,在任意一地址空间读出一个字节的数据(选择性读)。
备注:
这里要注意一个细节的东西就是要进行伪写操作。
然后才能读取芯片当中的数据。
通过上面的协议这个程序就能够写出来了。
提示:
实际上c语言当中没有uchar这个类型的变量这个是我通过宏定义出来的一个名字。
实际上并没有改变变量的类型。
只是在写程序的时候方便了一点,这个需要在程序之前定义:
#defineucharunsignedchar
这样子这个iic的接口协议就已经能够运行了。
亲测上面的程序是可以运行的。
还要注意的就是在连续写的话使用的是这个选择性读的协议,要至少延时2ms。
否则无法将所有数据全部都写进去,只能将第一个数据读出来。
这个要特别注意,本人亲自在这个上面载过跟头。
接下来就简单的介绍一些ds18b20这款单总线协议的芯片。
Ds18b20是一款测量温度的芯片。
它所使用的是单总线的协议,对时间的把控更为严格。
所以操作起来难度也更是显而易见的,对时序图的解读的要求就更高。
Ds18b20芯片一共就只有三个管脚。
如图所示:
在这里,我们使用的并不是寄生电源,我们将GND直接连接在地线上。
DQ为数据线。
VDD是电源线,通常我们将它接在+5V的电源上。
因为我们有独立的电源供电。
所以芯片所需的能量就是比较充足的,不需要寄生电源来工作了。
寄生电源就是一个可以充放点的电容。
若我们没有连接+5V的电源,那么寄生电源就会从DQ这条数据线上获得能量,用以来维持芯片的正常工作,但是在时间上,它相比于独立电源供电耗费的时间更长。
因此,它对时间就更严格。
在这里我们采用的是+5V作为独立电源来供电,来降低驱动程序的写作难度。
更详细的信息还是要大家看数据手册,在这里,我只教大家关于驱动程序的书写:
Ds18b20有不同的分辨率,不同的分辨率是由芯片中的一个寄存器决定的,在使用的时候,若你不对它进行修改,那么默认的ds18b20是按照12位的分辨率进行显示的,还有一个信号叫做ds1820是按照9位的分辨率显示的,但是无论是九位的还是十二位的分辨率,他在传输数据的时候都需要两个字节,这个时候除了有效位意外其他的数据都是标志位,当温度为零上的时候,这些标志位都是0,但是当测量的温度在零下的时候,这些标志位就全都置1.用来区分温度的正负。
而且需要注意的是,零下温度都是按照补码的形式传送数据的,所以在处理数据的时候就要将补码转换过来,具体的补码转换过程就要自己去XX一下了。
这里就不做重点介绍了。
1、我们首先来看总线的初始化:
因为它对时间的把控比较严格,所以我就线拓展一下,如何才能得到一个比较精准的时间,可以近乎精确到微妙的时间:
首先,得安装上keil,用于调试,在程序中加上一段代码,如下图所示,
在可以执行的主函数中加上这段程序,这个时候编译过,没有错误并且没有警告后在执行下一步;
接下来我们就要点面板上的
;
这个时候就可以进行调试,调试的时候就可以从左边的窗口中看到这个窗口,并且还可以知道执行每一步所需要的时间是多少,如下图所示:
这个时间的单位是s,但是我们可以通过小数点后面的位数读出每一步程序所执行的具体的微妙级的时间。
因为我们之前在调试的时候就已经放好了调试的结点,在程序执行到这个位置的时候自动会停住,不会再继续往下执行。
结点选项如下所示,如果我们想要在某句程序上放置这样的结点的话,首先将光标放置到着据程序行上,然后再点击第一个红色的按钮,就能成功的放置结点了,如果想要取消的话就点击最后一个带有黄色的差的按钮,就能够自然而然的取消掉了。
然后进行调试,选择左上角的这个按钮
,就能够直接进行运行了,这个时候就能够直接执行到了我们所需要的地方,首先就是上图中的结点1,,执行完之后,看一下时间是多少,此时记下时间,我们就说是t1,然后再点击这个运行按钮
,此时,程序停止到了结点2,记下时间为t2,这个时候我们就可以知道我们的这个程序在执行过程中花费了多长的时间,这个时间主要分为三部分,分别是跳转到执行函数的地方,然后再执行程序中的内容,在跳转出当前执行的函数。
而且我们的函数如下图所示,它里面只有一句话。
,不管while(t--);
要进行赋值,还是判断还是执行。
它的时间都是一个整体,所以我们就可以把这个语句看做是一句话,一条程序,每次值执行以此。
所以t2-t1=程序跳转的时间+程序执行一次的时间*此句程序执行的次数+跳转出当前函数的时间+一个周期的时间(_nop_();
)因为本人只是也比较浅薄,不知道程序所停在结点的地方是当前行程序执行完之后还是当前行程序执行前,但是在我们上图所给的程序中,它只会执行一次,不管是结点1处的还是结点2处的,但是我们知道_nop_();
执行的时间是当前所开发的芯片的一个机器周期,在我开发使用的芯片是89c51,那么它的一个机器周期就是1us,然后再按运行按钮,这个时候我们就知道了时间t3,然后再按一次这个运行按钮,这个时候我们就知道了时间t4,吗么我们就可以得到下面的表达式了:
t4-t3=程序跳转的时间+程序执行一次的时间*此句程序执行的次数+跳转出当前函数的时间+一个机器周期的时间。
通过将上面的两个表达式我们就可以知道了,第二个表达式相比于第一个表达式多出来的仅仅只是多执行了3次while(t--);
这个程序,这个时候我们就能够将执行一次while(t--);
的时间,在我的这个以12MHZ的晶振的下面,我算出来,执行一次的时间在10us,这个时候我们现在就能够算出程序跳转的时间加上程序跳转出去的时间,大约就是15us。
这个时候基本上就能够确定任意的执行一次Delay_OneWire(unsignedchart);
的时间了。
然后在写驱动的时候就能够将它运用起来了。
现在我们就来谈一谈初始化的过程:
应答存在脉冲:
首先我们将总线拉低,然后延时至少480us,然后将总线拉高,释放总线,延时至少15us,然后等待器件对总线应答,致使总线电平变低,然后再将总线释放,一个完整的应答过程就是这样了。
完整的应答程序如下所示:
这个程序是完全按照时序图上的时间来进行书写的。
时间的延时也是比较合理的,是按照时序图上面给的时间来执行的。
在总线上传输数据:
我们先来谈论一下向器件写的驱动程序,写“0”和写“1”在时序图上的体现如下图所示:
由此可见,主机必须在前写时间隙开始(将总线拉低开始)的前15us内将数据传送到总线上面,然后器件会在后面15us-60us内在总线上采样,提取上面的数据,提取完之后,主机要将总线拉高,恢复期间至少要延时1us的时间。
在对总线写“1”的时候要注意的是在时间隙开始之后至少要1us的时间用来恢复。
这样,整个时序图我们就已经解读完了。
现在就可以写驱动程序了,如下图所示:
这里的延时时间大家可以参考之前我讲解的时间来计算出比较准确的时间的。
接下来介绍一下在总线上读数据的时序图:
这个时序图我们要注意的地方还是比较多的,首先我们看到主机是在时间隙开始的前15us的时间内对总线进行采样的,我们要知道的是在时间隙开始后要等待至少1us的时间,但是时间也不能太长,太长的话主机会错过对总线上的数据进行采样的最佳时间。
首先是将总线拉低,代表时间隙的开始,然后延时1-2us的时间,再然后将总线释放(即拉高),然后开始采样,采样结束后要延时至少45us的时间,这个时候就能将总线上的数据读出来啦。
具体的程序如下所示:
对时间的把控也是比较精准的。
2、接下来就是对ROM的操作命令:
对ROM的操作命令一共有五个:
分别是readROM(33H)、MatchROM(55H)、SkipROM(CCH)、SearchROM(F0H)、AlarmSearch(ECH)。
通过对数据手册的解读,我们可以知道,因为正常情况下,我们在学习某个传感器的时候,只用到单个、而且是实现它里面的最基本的功能,高级功能我们暂且不需要。
所以我们只需要SkipROM(CCh)。
跳过64为编码,节省时间。
3、存储器操作命令:
我们只需要实现它对温度的转换就可以了。
如果没有使用+5V电源供电的话,ds18b20的转换时间还是比较长的,如果使用+5V电源供电的话,那么它的能量比较充足,转换的时间相对来说就会比较短,通过对手册上的理解,我们就可以知道了。
看图中圈出来的这个时间我们就知道时间还是比较长的。
因为我们的这个器件是从最低有效位开始进行传输的,这就说明了。
一个字节的传输,是先将第八位传输出去,然后再将高八位数据传输出去,但是我们现在知道的是我们实际所使用的是ds18b20这款芯片,它的数据为一共有十二位,如下图所示:
它可以精确到0.0625。
所以它的分辨率还是很高的。
S代表的是温度数据的正负。
在温度为正数的时候,S位都是0.而且在实际情况的时候,我们所测的温度都是零上的温度,所以在条件比较宽松的情况下,我们不需要管理S位。
具体的协议我们也可以参考这数据手册上的例子:
实际的协议程序如下:
这样字我们的数据就能够读出来啦!
!
接下来就只要实现对数据的处理就行了:
Date就是我么传递过来的数据,但是我们还没有进行处理,需要再乘以它的分辨率,ds18b20的分辨率是
,转换成小数的表达方式就是0.0625。
这个时候就能够得到温度数据,但是如果我只想精确到整数位,小数位我不想要的话,那么我只需要将它加上一个0.5通过date这个没有标志位的整形,就能够实现对温度数据的四舍五入啦。
那么关于ds18b20这款芯片的基本使用方法我们也就基本的已经学会了:
-)
在这里我要说明的是我写这篇文章的初衷,一个是为了学习这款芯片的基本使用,但最重要的还是教大家对芯片的时序图的解读,然后能够写出这个驱动和协议,我的这个文章希望能够对大家实现抛砖引玉的作用,日后对这些手册的解读以及对芯片驱动的书写还是要靠大家的自我领悟和多加练习。
本文章是本人手写的,除了参照了芯片的手册,其他的都是我自己独立完成的,所以绝对不可能出现侵权的可能,如果转载了我的这篇文章,亲您务必注明出处。
不得侵权。
本人是版权所有者。
谢谢配合。
另外,如果您对我的文章有好的建议,欢迎在下方留言评论指正,谢谢!