蓝桥杯模块DS18B20温度传感器Part_2
发布日期:2021-07-01 03:12:41
浏览次数:2
分类:技术文章
本文共 5219 字,大约阅读时间需要 17 分钟。
九层妖塔 起于垒土
蓝桥杯模块DS18B20温度传感器Part_2
一、初始化
1、初始化时序图:
2、相关延时时间的计算:
AB:主机下拉500us发送存在脉冲。
B:主机释放总线并进入接收模式(RX)。释放总线即DQ=1
。 BC:DS18B20等待时间。15us<BC<60us CD:DS18B20发送存在脉冲。60us<CD<240us T:主机读取DQ数据线电平状态时刻。 BT: B C m a x BC_{max} BCmax< B T BT BT< B C m i n BC_{min} BCmin+ C D m i n CD_{min} CDmin ,即60us< B T BT BT<75us, B T BT BT取65us TE:取500us 3、官方底层驱动代码:
//DS18B20初始化bit init_ds18b20(void){ bit initflag = 0; DQ = 1; Delay_OneWire(12); DQ = 0; Delay_OneWire(80); // 延时大于480us DQ = 1; Delay_OneWire(10); // 14 initflag = DQ; // initflag等于1初始化失败 Delay_OneWire(5); return initflag;}
4、Template:
bit DS18B20_Init(void){ bit presence = 0; //返回值,DS18B20返回存在脉冲为1 DQ = 1; //为主机拉低总线做准备 Delay5us(); //稍加延时使总线电平稳定 DQ = 0; //主机下拉500us,发送存在脉冲 Delay500us(); DQ = 1; //主机释放单总线 Delay65us(); //等待DS18B20 presence = !DQ; Delay500us(); //保持时序完整 return presence;}
5、Notes:
●按照官方底层驱动所要求的12MHz,Debug了多次,例程延时所测偏离正常。
●presence = !DQ;
存在presence为1即真。 ●函数名DS18B20_Init
便于在Functions
栏中快速查找。 二、写时序/读时序
1、读/写时序图:
3、官方底层驱动代码:
//通过单总线向DS18B20写一个字节void Write_DS18B20(unsigned char dat){ unsigned char i; for(i=0;i<8;i++) { DQ = 0; DQ = dat&0x01; Delay_OneWire(5); DQ = 1; dat >>= 1; } Delay_OneWire(5);}//从DS18B20读取一个字节unsigned char Read_DS18B20(void){ unsigned char i; unsigned char dat;// unsigned char index = 0; for(i=0;i<8;i++) { DQ = 0; dat >>= 1; DQ = 1; Delay_us(); if(DQ) { dat |= 0x80; } Delay_OneWire(5); } return dat;}
4、Template:
//---------------------------------------向DS18B20写一个字节-------------------------//void DS18B20_Write(uchar dat){ uchar i; for(i=0;i<8;i++) { DQ=0; //下拉 DQ=dat&0X01; //写入一位数据 Delay65us(); //保持时序完整 DQ=1; //释放总线 dat >>=1; } Delay65us(); //保持时序完整}//--------------------------------------从DS18B20读一个字节----------------------------//uchar DS18B20_Read(void){ uchar i; uchar dat=0; for(i=0;i<8;i++) { DQ=0; //主机拉低总线 dat >>=1; //右移兼延时,第一次移位无效 DQ=1; //释放总线 Delay5us();//稍加延时使总线电平稳定 if(DQ==1) { dat |=0X80; } Delay65us();//保持时序完整 } return dat;}
5、Notes:
●读时序中将返回值uchar dat=0;
。
○在函数调用时对自动变量赋初值,每调用一次函数重新给一次初值。
○若在定义时不赋初值,自动变量的初值不确定。每次函数调用结束后存储单元已释放,下次调用时又重新另分配存储单元,而所分配的单元中的内容是不可知的。
●读时序中Delay5us();//稍加延时使总线电平稳定
。释放总线后,若读到的是1,则DQ线会被上拉电阻拉高,从0到1需要跨过阈值需要一段时间。按照芯片手册要求尽量在15us后端取检测。
三、DS18B20温度采集函数
1、Template:
//-------------------------------------DS18B20温度采集函数---------------------------//uint DS18B20_get_Temperature(void){ uint low,high; uint Temp=0; DS18B20_Init(); //初始化 DS18B20_Write(0XCC); //跳过ROM DS18B20_Write(0X44); //转换温度 DS18B20_Init(); //初始化 DS18B20_Write(0XCC); //跳过ROM DS18B20_Write(0XBE); //读暂存器 low = DS18B20_Read(); //低字节,16位温度低8位,Byte 0 high = DS18B20_Read();//高字节,16位温度高8位, Byte 1 Temp = (high<<8)+(low&0X00FF); return Temp;}
2、Notes:
●uint low,high;
官方例程中将其定义为uchar,并且也进行了high<<8
操作,若使用uchar在调用子函数之初就开辟了8位的内存地址,再进行左移,感觉会数据溢出。但是调试时并没有发生错误。
uint Temp=0;
和low&0X00FF
●返回值Temp
为16位无符号整型。 ●12位分辨率的精度位0.0625,最大转换时间为750ms。写入DS18B20_Write(0X44); //转换温度
开始温度转换后,就由DS18B20的相关硬件部分去执行温度转换,转换完成后存放在暂存器的低两位字节中;若不进行初始化直接读取时序,如果DS18B20正在温度转换过程中则返回0来响应,若转换完成则返回1。主机可以对DS18B20进行其他操作,由DS18B20的其他硬件部分响应;主机若对DS18B20进行其他操作,必须由初始化开始。 在执行第二个初始化时,转换温度的命令已经写入DS18B20,虽然温度还未转换完成,但是单总线已经空闲,可以继续执行下边几乎不耗时的读暂存器命令。所以在上电之初,会出现短暂的85
初始值。 四、DS18B20温度数码管段码转换函数
1、Template:
//-------------------------------------DS18B20温度数码管段码转换函数------------------------//void DS18B20_SEG(uint Temp){ yi=20; //符号位 er=(Temp>>4)/100; //百位 san=((Temp>>4)%100)/10; //十位 si=((Temp>>4)%10)+10; //个位 wu=((Temp&=0X000F)*625)/1000; //小数点后一位 liu=((Temp&=0X000F)*625)/100%10;//小数点后两位 qi=((Temp&=0X000F)*625)/10%10; //小数点后三位 ba=((Temp&=0X000F)*625)%10; //小数点后四位}
2、Notes:
●第一位为符号位,现写入全灭,可以通过判断Temp
高四位确认正负。
(Temp>>4)
为整体进行操作。虽然从暂存器读到的Tenp
为16位二进制无符号整数,进行取余、除法运算时,右端的数为十进制,对于单片机(计算机)统一转换为二进制进行运算,同样在用户端为了便于理解可以理解为都是十进制 ●小数部分以((Temp&=0X000F)*625)
为整体进行操作。(Temp&=0X000F)
的四位有效数值为的权值依次为 2 3 2^3 23, 2 2 2^2 22, 2 1 2^1 21, 2 0 2^0 20,若为二进制小数,小数点后四位小数权值依次为 2 − 1 2^{-1} 2−1, 2 − 2 2^{-2} 2−2, 2 − 3 2^{-3} 2−3, 2 − 4 2^{-4} 2−4,所以将(Temp&=0X000F)
乘以 2 − 4 2^{-4} 2−4即0.0625,((Temp&=0X000F)*0.0625)
即为小数点后四位(最多表示4位小数)。为了避免浮点数运算,可将十进制小数((Temp&=0X000F)*0.0625)
扩大一万倍,即将十进制小数点左移四位,即为((Temp&=0X000F)*625)
。 ●对小数部分,尝试了右移4位来代替除法运算,可是在这儿,数值却移出去了。最后一位出现了0,5以外的值。 ●12位分辨率的精度位0.0625,所以数码管最后一位一定为0或5。 ●若要求不显示四位小数,通过除法和求余的方法是将不显示的部分直接抹掉;若采用prinft
或sprinft
指定小数位数输出,可以实现四舍五入。 五、主函数
uint Temp; //DS18B20温度值,16位uchar SEG_Array[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, //数字0~9无点,索引值0~9 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10, //数字0~9有点,索引值(0~9)+10 0XFF, //灭灯,索引值20 0X86, //字母大写E,索引值21 0XC8, //字母小写n,索引值22 0XBF //中间一横,索引值23};void main(void){ All_Init(); //开发板初始化 while(1) { Temp=DS18B20_get_Temperature(); //温度采集 DS18B20_SEG(Temp); //将16位Temp转换为段码 SEG_1_2(yi,er); SEG_3_4(san,si); SEG_5_6(wu,liu); SEG_7_8(qi,ba); SEG_Init(); }}
补:
- 不同类型间数值的运算。
-
prinft
或sprinft
的具体使用。 - 将相对独立的模块化程序使用头文件和从c文件的形式在主c文件中调用。
- Debug的具体使用规则。
转载地址:https://methadone-no1.blog.csdn.net/article/details/107971305 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年05月02日 13时37分38秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
前端学习 -- Css -- 样式的继承
2019-05-02
python 循环语句
2019-05-02
前端学习 -- Css -- 文本标签
2019-05-02
python 字典
2019-05-02
python 字符串
2019-05-02
Python 文件I/O
2019-05-02
python 异常处理
2019-05-02
前端学习 -- Css -- 有序列表和无序列表
2019-05-02
Python 日期和时间
2019-05-02
前端学习 -- 长度单位
2019-05-02
前端学习 -- Css -- 定义列表
2019-05-02
前端学习 -- Css -- 字体
2019-05-02
前端学习 -- 颜色
2019-05-02
前端学习 -- Css -- 字体的几个属性学习
2019-05-02
前端学习 -- Css -- 字体分类
2019-05-02
Shell脚本学习
2019-05-02
前端学习 -- Css -- 行间距
2019-05-02
前端学习 -- Css -- 文本样式
2019-05-02
前端学习 -- Css -- 盒子模式
2019-05-02
前端学习 -- Css -- 默认样式
2019-05-02