STM32F207V 进行DS18B20处理

1、  DS18B20接口很简单,VCC、DQ、GND三个引脚,VCC采用外部供电3.3V,DQ需上拉电阻,当时按照参考资料上外接4.7K的上拉电阻,GPIO设置的OD无上拉,始终读不到ROM中的64位序列号,后面发送的转换指令更别想了,后来GPIO改成推挽输出时,诶,就能读到数据,推挽输出无非就是增大驱动能力,仔细看手册,其中有提到,DS18B20空闲处于低功耗状态,在执行温度转换或从高速暂存器向EPPROM传送数据时,工作电流可高达1.5mA,但并有说读ROM中的64位数据时,电流需要多少,也许在读ROM中的数据电流也需要要求。知道了加大驱动能力才能读到,加上之前写I2C和FLASH擦除时,数据线都是设置OD类型,通用性较好,好移植,所以还是改成OD类型,把4.7K的电阻换小点,换成1K电阻,就可以正确的读写操作。

2、操作步骤,在使用任何一条功能指令前,都必须先执行有复位、ROM指令。

(1)、复位信号就是双方握手,达成协议后才能相互通信。时序如下,一定要注意minimum和maximum,Master主机先发送低电平脉冲,低电平持续480us~960us(这里设置700us,延迟后记得释放数据线,也就是拉高),DS18B20等待15~60us后(用while语句检测低电平的到来),会发出低电平脉冲信号给Master,该低电平脉冲60~240us,Master接收到后,就说明握手成功,用while语句检测高电平结束。

代码:

 1 void Ds18b20_rst(void)
 2 {
 3     DS18B20_DATA_H;
 4     DS18B20_DATA_L;
 5     Ds18b20_delay(T700US);         //700us
 6     DS18B20_DATA_H;                //释放数据线
 7     while(DS18B20_DATA_Read);      //检测低电平
 8     Ds18b20_delay(T700US);
 9     while(!DS18B20_DATA_Read);    //检测高电平
10     DS18B20_DATA_H;
11 }

(2)、发ROM指令和功能指令,就是1bit 1bit 的往外发,读也是1bit 1bit的往里读,发送顺序是先低后高。读写时有高有低,一定要按照时序严格进行操作:

  a)、写“0”  和“1”时序,先拉低15us,发送高电平持续45us,注意不低于60us,发送完1bit,释放数据线。

代码:

 1 void Ds18b20_Send_0(void)
 2 {
 3     DS18B20_DATA_L;
 4     Ds18b20_delay(T15US);   //15us
 5     DS18B20_DATA_L;
 6     Ds18b20_delay(T45US);        //45us
 7     DS18B20_DATA_H;        //释放总线
 8 }
 9
10 void Ds18b20_Send_1(void)
11 {
12     DS18B20_DATA_L;
13     Ds18b20_delay(T15US);   //15us
14     DS18B20_DATA_H;
15     Ds18b20_delay(T45US);
16     DS18B20_DATA_H;        //释放总线
17 }
18
19 void Ds18b20_send_byte(uint8_t data)
20 {
21     uint8_t i = 8;
22
23     while(i--)
24     {
25         if(data & 0x01)    //从低位开始发送
26             Ds18b20_Send_1();
27         else
28             Ds18b20_Send_0();
29
30         data >>= 1;
31     }
32 }

  b)、读“0”  和“1”时序,在MASTER SAMPLES就可以采样数据,但一般会大于15us后开始采集数据,读写前 和 读写完后,都要记得释放数据

代码:

 1 uint8_t Ds18b20_read_byte(void)
 2 {
 3     uint8_t i = 8;
 4     uint8_t data_buffer = 0;
 5
 6     DS18B20_DATA_H;        //释放数据线
 7     while(i--)
 8     {
 9         data_buffer >>= 1;
10         DS18B20_DATA_L;
11         Ds18b20_delay(T1US);        //1us
12         DS18B20_DATA_H;                //释放数据线
13         Ds18b20_delay(T15US);
14         if(DS18B20_DATA_Read)    //接收低位开始
15         {
16             data_buffer |= 0x80;
17         }
18         Ds18b20_delay(T45US);
19         DS18B20_DATA_H;
20     }
21
22     return data_buffer;
23 }

写好写字节函数 和 读字节函数,那么就可以发送ROM指令和功能指令了,具体指令参考数据手册。

一些具体操作指令代码:

 1 void Ds18b20_Read_ROM(uint8_t *pBuff)
 2 {
 3     uint8_t i =0;
 4     Ds18b20_rst();
 5     Ds18b20_send_byte(0x33);            //读Rom指令
 6     for(i=0; i<8; i++)
 7     {
 8         pBuff[i] = Ds18b20_read_byte();
 9     }
10 }
11
12 void Ds18b20_Convert_temprature(void)
13 {
14     Ds18b20_rst();
15     Ds18b20_send_byte(0xcc);                //忽略ROM指令
16     Ds18b20_send_byte(0x44);                //转换指令
17 }
18
19 void Ds18b20_Read_register(uint8_t *pBuff)
20 {
21     uint8_t i = 0;
22     Ds18b20_Convert_temprature();
23     Ds18b20_rst();
24     Ds18b20_send_byte(0xcc);                //忽略ROM指令
25     Ds18b20_send_byte(0xbe);                //读取存储器指令
26     for(i=0; i<8; i++)
27     {
28         pBuff[i] = Ds18b20_read_byte();
29     }
30 }
31
32 void Ds18b20_weite_threshold(uint8_t TH, uint8_t TL, uint8_t Resolution)
33 {
34     Ds18b20_rst();
35     Ds18b20_send_byte(0xcc);                //忽略ROM指令
36     Ds18b20_send_byte(0x4e);                //写暂存器指令
37     Ds18b20_send_byte(TH);
38     Ds18b20_send_byte(TL);
39     if(Resolution == 9)
40     {
41         Ds18b20_send_byte(0x1f);
42     }
43     else if(Resolution == 10)
44     {
45         Ds18b20_send_byte(0x3f);
46     }
47     else if(Resolution == 11)
48     {
49         Ds18b20_send_byte(0x5f);
50     }
51     else //if(Resolution == 12)    //其他任何都默认设置12bit分辨率
52     {
53         Ds18b20_send_byte(0x7f);
54     }
55 }

主函数:

 1 int main(void)
 2 {
 3     u8 i = 0;
 4     u8 id[8];
 5     RCC_ClocksTypeDef rcc_clocks;
 6
 7     Clock_Config();
 8     USART_Config();
 9
10     Ds18b20_GPIO_Config();
11     Ds18b20_Read_ROM(id);
12     printf("DS18B20 64bit ROM Data:\n");
13     for(i=0; i<8; i++)
14     {
15         printf("0x%02x,",id[i]);
16     }
17     printf("\n");
18     printf("DS18B20 Memory Data:\n");
19
20     Ds18b20_Read_register(id);
21     for(i=0; i<8; i++)
22     {
23         printf("0x%02x,",id[i]);
24     }
25
26     printf("\n");
27
28     Ds18b20_weite_threshold(0x3b,0x36,12);
29     Ds18b20_Read_register(id);
30     for(i=0; i<8; i++)
31     {
32         printf("0x%02x,",id[i]);
33     }
34
35     printf("\n");
36
37     while(1)
38     {
39         Ds18b20_Read_register(id);
40         printf("temprature:%.4f\n",((id[1]<<8) | id[0]) * 6.25 /100);
41         Delay(0x1fffff0);   /* delay 1000ms */
42     }
43 }

3、打印信息

(1)、读5个不同DS18B20中ROM数据:

    0x28,0x37,0x4f,0xca,0x06,0x00,0x00,0x03
    0x28,0x3b,0xf4,0xc9,0x06,0x00,0x00,0xc9
    0x28,0xee,0xa0,0xcc,0x06,0x00,0x00,0xed
    0x28,0xca,0x02,0xcb,0x06,0x00,0x00,0xb1
    0x28,0xf0,0xbf,0xcb,0x06,0x00,0x00,0x30

    最前面8位是单线系列编码固定28H,接着48位是唯一序列号,最后8位是CRC,有关CRC计算参考手册,这里也没有去验证CRC是否正确。

(2)、

  DS18B20 64bit ROM Data:

  0x28,0xf0,0xbf,0xcb,0x06,0x00,0x00,0x30,   //64位中的序列号

  DS18B20 Memory Data:

  0xcd,0x01,0x4b,0x46,0x7f,0xff,0x03,0x10,  //读暂存器中的默认值

  0xcd,0x01,0x3b,0x36,0x7f,0xff,0x03,0x10, //改写后,读暂存器中的数据

  temprature:28.8125            //转换温度

printf("temprature:%.4f\n",((id[1]<<8) | id[0]) * 6.25 /100);

这里只考虑了正数温度,关于*6.25*100,参考数据手册:"温度传感器的精度为用户可编程的9、10、11或12位,分别以0.5°、0.25°、0.125°和0.0625°增量递增",程序选的是12bit分辨率,单位增量即为0.0625

时间: 2024-10-11 04:01:41

STM32F207V 进行DS18B20处理的相关文章

Cubieboard1显示DS18B20温度信息到LED

Cubieboard1的内核已经支持w1温度传感器DS18B20 (依赖的内核选项和模块包括dallas's 1-wire support, gpio_sunxi, w1_sunxi, w1_gpio, w1_slave_therm ). 下图的DIY是在8位8段LED显示模块上同时显示当前时间和气温的实验. jarry大侠在很久前的帖子(http://forum.cubietech.com/forum.php?mod=viewthread&tid=474)中介绍了DS18B20在cubiebo

51单片机课程设计:基于DS18B20的温度报警器

51单片机课程设计:基于DS18B20的温度报警器 本程序用于读取DS18B20温度,同时具备报警功能,工程分为3个文件,main.c.temp.c.temp.h,经本人修改部分代码,适用于吉林农业大学51开发板,其他朋友亦可移植到其他型号开发板.工程文件在文章最下方. 1.main.c文件 /*********************************说明****************************************** 本程序用于读取温度检测模块DS18B20数值,并

DS18B20 pi

所需材料:DS18B20        好了,先截图展示一下(对嘴吹起的结果,所以感觉室内气温偏高): 教程开始: 本帖隐藏的内容1.如何接线: 如何接,上图很清楚,就不多说.接线好了后,下面说命令:A.更新升级内核 (新版本一般不需要这一步)::apt-get updateapt-get upgradeB.查看设备是否存在:sudo modprobe w1-gpiosudo modprobe w1-thermcd /sys/bus/w1/devices/ls显示结果: 上图中的28-00000

1-wire单总线DS18B20

要想实现单总线通信,每一个挂在总线上的从机必须拥有开路或3态输出.单总线DS18B20的DQ引脚用内部电路实现了开漏输出,其等效电路如下图: 当单片机IO引脚配置为 mcu IO引脚 电流流向 DS18B20 输入浮空(高阻) DS18B20开漏输出高阻态,被上拉电阻拉为高电平. +5V-->4.7K上拉电阻-->DQ-->(5uA Typ)-->GND TX输出1: TX输出0: 推挽输出1: 输出0: +VDD-->mos-->MCU IO引脚-->(5uA

DS18B20时序分析详细步骤

作者:华清远见讲师 1.过程1.2是初始化过程,每次读取都要初始化,否则18b20处于待机状态,无法成功读取.过程1:拉低信号线480-700us,使它复位,然后释放总线15-60us,18b20会拉低总线60-240us,然后它释放总线.所以初始化成功的一个标志就是能否读到18b20这个先低后高的操作时序. (注意:黑色部分表示主机操作,蓝色部分表示18b20操作,每次主机操作完成之后等待18b20状态时,必须要释放总线,比如将IO设置为高阻态什么的.否则18B20没法把状态写到线上) 2.过

DS18B20的操作

DS18B20 1    Feature 1.         一总线接口,只有一个端口用来通信: 2.         可多个传感器支路并联使用简化了分布式温度传感应用: 3.         不需要再外接其他器件: 4.         可以从数据线驱动,电源供应范围为3.0V到5.5V,也可从专用管脚接电: 5.         零备用电源要求: 6.         测温范围为-55度到125度,在-10到+85度之间测量时误差为0.5度: 7.         可编程分辨率9到12位,

DS18B20函数库建立实验

1.主代码: /* 温度传感器  */#include "DS18B20.h"#include"def.h" u16 get_temp (void){    float tt;    u16 temp;    u8 a,b;    ds_delay(40);    dsic_init();    write_byte(0xcc);    write_byte(0x44);    ds_delay(40);    dsic_init();    write_byte(

ds18b20驱动及应用程序

------------------------------------------------------------------------------------------------------------------------------ 交叉编译器:arm-linux-gcc-4.5.4 Linux内核版本:Linux-3.0 主机操作系统:Centos 6.5 开发板:FL2440 温度传感器:ds18b20 ----------------------------------

ds18b20采集温度并上报服务器

------------------------------------------------------------------------------------------------------------------------------ 交叉编译器:arm-linux-gcc-4.5.4 Linux内核版本:Linux-3.0 主机操作系统:Centos 6.5 开发板:FL2440 温度传感器:ds18b20 注:此程序的客户端是在装有ds18b20模块并有ds18b20驱动的