物联网嵌入式工程师40周\[包含电子书]|之wire单总线通信

161 阅读26分钟

物联网嵌入式工程师40周[包含电子书]|之wire单总线通信

附上资源MP4下载地址

我用夸克网盘分享了「2025年物联网嵌入式工程师40周[包含电子书]-完结」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。 链接:pan.quark.cn/s/3b0a95006…

失效访问:cowcowit.com/course/4/4

一、单总线介绍

1-wire单总线\是Maxim全资子公司Dallas的一项专有技术。与目前多数标准串行数据通信方式,如SPI 、I2C不同,它采用单根信号线,既传输时钟,又传输数据,而且数据传输是双向的\。它具有节省I/O口线资源、结构简单、成本低廉、便于总线扩展和维护等诸多优点。

1-wire单总线适用于单个主机系统,能够控制一个或多个从机设备。当只有一个从机位于总线上时,系统可按照单节点系统操作;而当多个从机位于总线上时,则系统按照多节点系统操作。

每一个符合OneWire协议的从芯片都有一个唯一的地址\,包括48位的序列号、8位的家族代码和8位的CRC代码\。主芯片对各个从芯片的寻址依据这64位的不同来进行。

单总线利用一根线实现双向通信。因此其协议对时序的要求较严格\,如应答等时序都有明确的时间要求。基本的时序包括:复位、应答时序、写1位时序、读1位时序\。在复位及应答时序中,主器件发出复位信号后,要求从器件在规定的时间内送回应答信号;在位读和位写时序中,主器件要在规定的时间内读出或写入数据。

二、DS18B20介绍

The DS18B20 uses Dallas’ exclusive 1-Wire bus protocol that implements bus communication using one control signal.\The control line requires a weak pullup resistor since all devices are linked to the bus via a 3-state or open-drain port (the DQ pin in the case of the DS18B20). In this bus system, the microprocessor (the master device) identifies and addresses devices on the bus using each device’s unique 64-bit code. Because each device has a unique code, the number of devices that can be addressed on one bus is virtually unlimited.

DS18B20采用达拉斯独有的单线总线协议,使用一个控制信号实现总线通信。控制线需要一个弱上拉电阻,因为所有设备都通过三态或漏极端口(DS18B20中的DQ引脚)连接到总线。在该总线系统中,微处理器(主设备)使用每个设备唯一的64位代码识别和寻址总线上的设备。由于每个设备都有唯一的代码,因此可以在一条总线上寻址的设备数量几乎是无限的。

Another feature of the DS18B20 is the ability to operate without an external power supply. Power is instead supplied through the 1-Wire pullup resistor via the DQ pin when the bus is high. The high bus signal also charges an internal capacitor (CPP), which then supplies power to the device when the bus is low. This method of deriving power from the 1-Wire bus is referred to as “parasite power.” As an alternative, the DS18B20 may also be powered by an external supply on VDD

DS18B20的另一个特点是能够在没有外部电源的情况下运行。当总线为高电平时,电源通过DQ引脚通过1-Wire上拉电阻供电。高总线信号还为内部电容器(CPP)充电,然后在总线为低电平时为器件供电。这种从1-Wire总线获取电源的方法被称为“寄生电源”。作为替代方案,DS18B20也可以由VDD上的外部电源供电

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三、MEASURING TEMPERATURE(温度测量)

The core functionality of the DS18B20 is its direct-to-digital temperature sensor. The resolution of the temperature sensor is user-configurable to 9, 10, 11, or 12 bits, corresponding to increments of 0.5℃, 0.25℃, 0.125℃, and 0.0625℃, respectively.The default resolution at power-up is 12-bit.\The DS18B20 powers-up in a low-power idle state;to initiate a temperature measurement and A-to-D conversion, the master must issue a Convert T [44h] command.\Following the conversion, the resulting thermal data is stored in the 2-byte temperature register in the scratchpad memory and the DS18B20 returns to its idle state.

DS18B20的核心功能是其直接数字温度传感器。温度传感器的分辨率可由用户配置为9、10、11或12位,分别对应0.5℃、0.25℃、0.125℃和0.0625℃的增量。上电时的默认分辨率为12位。DS18B20在低功耗空闲状态下上电;要启动温度测量和A到D转换,主机必须发出转换T[44h]命令。转换后,生成的热数据存储在2字节温度寄存器中在暂存器中,DS18B20返回其空闲状态。

The temperature data is stored as a 16-bit sign-extended two’s complement number in the temperature register . The sign bits (S) indicate if the temperature is positive or negative: for positive numbers S = 0 and for negative numbers S = 1. If the DS18B20 is configured for 12-bit resolution, all bits in the temperature register will contain valid data.

温度数据在温度寄存器中存储为16位符号扩展的二进制补码。符号位(S)指示温度是正的还是负的:对于正数S=0,对于负数S=1。如果DS18B20配置为12位分辨率,温度寄存器中的所有位都将包含有效数据。

For 11-bit resolution, bit 0 is undefined. For 10-bit resolution, bits 1 and 0 are undefined, and for 9-bit resolution bits 2, 1 and 0 are undefined. Table 2 gives examples of digital output data and the corresponding temperature reading for 12-bit resolution conversions.

对于11位分辨率,位0是未定义的。对于10位分辨率,位1和0是未定义的,对于9位分辨率,位2、1和0是未定义的。表2给出了12位分辨率转换的数字输出数据和相应温度读数的示例。

四、DS18B20操作

The transaction sequence for accessing the DS18B20 is as follows:

Step 1. Initialization\

Step 2. ROM Command\

Step 3. DS18B20 Function Command\

1.INITIALIZATION

All transactions on the 1-Wire bus begin with an initialization sequence. The initialization sequence consists of a reset pulse transmitted by the bus master followed by presence pulse(s) transmitted by the slave(s). The presence pulse lets the bus master know that slave devices (such as the DS18B20) are on the bus and are ready to operate.

1-Wire总线上的所有事务都以初始化序列开始。初始化序列由总线主站发送的复位脉冲和从站发送的存在脉冲组成。存在脉冲让总线主站知道从站设备(如DS18B20)在总线上并准备好运行。

2.ROM COMMANDS

After the bus master has detected a presence pulse, it can issue a ROM command. These commands operate on the unique 64-bit ROM codes of each slave device and allow the master to single out a specific device if many are present on the 1-Wire bus.

总线主站检测到存在脉冲后,它可以发出ROM命令。这些命令对每个从设备的唯一64位ROM代码进行操作,如果1-Wire总线上存在许多设备,则允许主站单独选择特定设备。

l SEARCH ROM [F0h]

l READ ROM [33h]\

l MATCH ROM [55h]

l SKIP ROM [CCh]\

l ALARM SEARCH [ECh]

(1)READ ROM [33h]

This command can only be used when there is one slave on the bus. It allows the bus master to read the slave’s 64-bit ROM code without using the Search ROM procedure. If this command is used when there is more than one slave present on the bus, a data collision will occur when all the slaves attempt to respond at the same time.

此命令只能在总线上有一个从站时使用。它允许总线主机读取从站的64位ROM代码,而无需使用搜索ROM过程。如果在总线上有多个从站时使用此命令,当所有从站尝试同时响应时,将发生数据冲突。

Each DS18B20 contains a unique 64–bit code stored in ROM.The least significant 8 bits of the ROM code contain the DS18B20’s 1-Wire family code: 28h.\The next 48 bits contain a unique serial number.The most significant 8 bits contain a cyclic redundancy check (CRC) byte that is calculated from the first 56 bits of the ROM code.\

每个DS18B20都包含一个存储在ROM中的唯一64位代码。ROM代码的最低有效8位包含DS18B20的1-Wire系列代码:28h。接下来的48位包含一个唯一的序列号。最高有效8位包含一个循环冗余码检测(CRC)字节,该字节是从ROM代码的前56位计算出来的。

(2)SKIP ROM [CCh]

The master can use this command to address all devices on the bus simultaneously without sending out any ROM code information.For example, the master can make all DS18B20s on the bus perform simultaneous temperature conversions by issuing a Skip ROM command followed by a Convert T [44h] command.\

主机可以使用此命令同时寻址总线上的所有设备,而无需发送任何ROM代码信息。例如,主机可以通过发出跳过ROM命令后跟转换T[44h]命令来使总线上的所有DS18B20同时执行温度转换。

3.FUNCTION COMMANDS

After the bus master has used a ROM command to address the DS18B20 with which it wishes to communicate, the master can issue one of the DS18B20 function commands.

总线主站使用ROM命令寻址它希望与之通信的DS18B20后,主站可以发出DS18B20功能命令之一。

l CONVERT T [44h]\

l WRITE SCRATCHPAD [4Eh]

l READ SCRATCHPAD [BEh]\

l COPY SCRATCHPAD [48h]

l RECALL E2 [B8h]

l READ POWER SUPPLY [B4h]

(1)CONVERT T [44h]

This command initiates a single temperature conversion. Following the conversion, the resulting thermal data is stored in the 2-byte temperature register in the scratchpad memory and the DS18B20 returns to its low-power idle state.

此命令启动单次温度转换。转换后,生成的热数据存储在便签簿内存中的2字节温度寄存器中,DS18B20返回低功耗空闲状态。

(2)READ SCRATCHPAD [BEh]

This command allows the master to read the contents of the scratchpad. The data transfer starts with the least significant bit of byte 0 and continues through the scratchpad until the 9th byte (byte 8 – CRC) is read. The master may issue a reset to terminate reading at any time if only part of the scratchpad data is needed.

此命令允许主机读取暂存板的内容。数据搬迁从字节0的最低有效位开始,并继续通过暂存板,直到读取第9个字节(字节8-CRC)。如果只需要部分暂存板数据,主机可以随时发出重置以终止读取。

五、DS18B20操作时序

1.INITIALIZATION PROCEDURE: RESET AND PRESENCE PULSES

All communication with the DS18B20 begins with an initialization sequence that consists of a reset pulse from the master followed by a presence pulse from the DS18B20. When the DS18B20 sends the presence pulse in response to the reset, it is indicating to the master that it is on the bus and ready to operate.

与DS18B20的所有通信都以初始化序列开始,该序列由主设备的复位脉冲和DS18B20的存在脉冲组成。当DS18B20响应复位发送存在脉冲时,它向主设备表明它在总线上并准备好操作

During the initialization sequence the bus master transmits (TX) the reset pulse by pulling the 1-Wire bus low for a minimum of 480us.The bus master then releases the bus and goes into receive mode (RX).When the bus is released, the 5k pullup resistor pulls the 1-Wire bus high. When the DS18B20 detects this rising edge, it waits 15us to 60us and then transmits a presence pulse by pulling the 1-Wire bus low for 60us to 240us.\

在初始化序列中,总线主控器通过将1-Wire总线拉低至少480秒来发送复位脉冲。然后总线主控器释放总线并进入接收模式(RX)。当总线释放时,5k上拉电阻将1-Wire总线拉高。当DS18B20检测到这种上升沿时,它等待15us到60us,然后通过将1-Wire总线拉低60us到240us来发送存在脉冲。

2.WRITE TIME SLOTS

There are two types of write time slots: “Write 1” time slots and “Write 0” time slots. The bus master uses a Write 1 time slot to write a logic 1 to the DS18B20 and a Write 0 time slot to write a logic 0 to the DS18B20. All write time slots must be a minimum of 60us in duration with a minimum of a 1us recovery time between individual write slots. Both types of write time slots are initiated by the master pulling the 1-Wire bus low .

有两种类型的写入时隙:“写入1”时隙和“写入0”时隙。总线主控器使用写入1时隙将逻辑1写入DS18B20,使用写入0时隙将逻辑0写入DS18B20。所有写入时隙的持续时间至少为60us,单个写入时隙之间的恢复时间至少为1us。这两种类型的写入时隙都是由主控器将1-Wire总线拉低启动的。

To generate a Write 1 time slot, after pulling the 1-Wire bus low, the bus master must release the 1-Wire bus within 15us.\When the bus is released, the 5k pullup resistor will pull the bus high.To generate a Write 0 time slot, after pulling the 1-Wire bus low, the bus master must continue to hold the bus low for the duration of the time slot (at least 60us).\

要产生写1时隙,在将1-Wire总线拉低后,总线主机必须在15us内释放1-Wire总线。当总线释放时,5k上拉电阻将把总线拉高。要产生写0时隙,在将1-Wire总线拉低后,总线主机必须在时隙持续时间(至少60us)内继续保持总线低电平。

The DS18B20 samples the 1-Wire bus during a window that lasts from 15us to 60us after the master initiates the write time slot. If the bus is high during the sampling window, a 1 is written to the DS18B20. If the line is low, a 0 is written to the DS18B20.

DS18B20在主机启动写入时隙后的15us到60us的窗口中对1-Wire总线进行采样。如果在采样窗口中总线为高电平,则向DS18B20写入1。如果线路为低电平,则向DS18B20写入0。

3.READ TIME SLOTS

The DS18B20 can only transmit data to the master when the master issues read time slots. Therefore, the master must generate read time slots immediately after issuing a Read Scratchpad [BEh] or Read Power Supply [B4h] command, so that the DS18B20 can provide the requested data. In addition, the master can generate read time slots after issuing Convert T [44h] or Recall E2 [B8h] commands to find out the status of the operation as explained in the DS18B20 FUNCTION COMMAND section.

DS18B20只有在主控机发出读取时隙时才能向主控机传输数据。因此,主控机必须在发出读取记录板[BEh]或读取电源[B4h]命令后立即生成读取时隙,以便DS18B20能够提供所请求的数据。此外,主控机可以在发出转换T[44h]或召回E2[B8h]命令后生成读取时隙,以找出操作的状态,如DS18B20功能命令部分所述。

All read time slots must be a minimum of 60us in duration with a minimum of a 1us recovery time between slots. A read time slot is initiated by the master device pulling the 1-Wire bus low for a minimum of 1us and then releasing the bus .

所有读取时隙的持续时间必须至少为60us,时隙之间的恢复时间至少为1us。读取时隙由主设备将1-Wire总线拉低至少1us,然后释放总线启动。

After the master initiates the read time slot, the DS18B20 will begin transmitting a 1 or 0 on bus. The DS18B20 transmits a 1 by leaving the bus high and transmits a 0 by pulling the bus low. When transmitting a 0, the DS18B20 will release the bus by the end of the time slot, and the bus will be pulled back to its high idle state by the pullup resister. Outputdata from the DS18B20 is valid for 15us after the falling edge that initiated the read time slot. Therefore, the master must release the bus and then sample the bus state within 15us from the start of the slot.

当主机启动读取时隙后,DS18B20将开始在总线上传输1或0。DS18B20通过将总线保持在高电平来传输1,并通过将总线拉低来传输0。当传输0时,DS18B20将在时隙结束时释放总线,总线将被上拉电阻拉回其高空闲状态。DS18B20的输出数据在启动读取时隙的下降沿后对15us有效。因此,主机必须释放总线,然后从时隙开始在15us内对总线状态进行采样。

六、DS18B20硬件原理图分析

七、GPIO控制器相关操作函数接口

1 void ds18b20_pin_init(void)

2 {

3 IOMUXC_SW_MUX_CTL_PAD_GPIO5_IO02 &= ~(0xf << 0);

4 IOMUXC_SW_MUX_CTL_PAD_GPIO5_IO02 |= (0x5 << 0);

5

6 return;

7 }

2.输入输出方向控制

1 //read direction

2 void ds18b20_pin_input(void)

3 {

4 GPIO5->GDIR &= ~(1 << 2);

5 }

6

7 //write direction

8 void ds18b20_pin_output(void)

9 {

10 GPIO5->GDIR |= (1 << 2);

11 }

3.写入输出电平

1 //write level

2 void ds18b20_write_level(int level)

3 {

4 if(level){

5 GPIO5->DR |= (1 << 2);

6 }else{

7 GPIO5->DR &= ~(1 << 2);

8 }

9

10 return;

11 }

4.读取输入电平

1 int ds18b20_read_level(void)

2 {

3 int level;

4

5 level = GPIO5->PSR & (1 << 2);

6 return level ? 1 : 0;

7 }

八、DS18B20相关操作函数接口

1.初始化探测DS18B20设备

1 int ds18b20_detect(void)

2 {

3 int level;

4

5 ds18b20_pin_output();

6 ds18b20_write_level(DS18B20_HIGH_LEVEL);

7 gpt_delay_us(10);

8 /*

9 *master transmits (TX) the reset pulse by pulling the

10 *1-Wire bus low for a minimum of 480us.

11 */

12 ds18b20_write_level(DS18B20_LOW_LEVEL);

13 gpt_delay_us(700);

14

15 ds18b20_write_level(DS18B20_HIGH_LEVEL);

16 ds18b20_pin_input();

17 //wait 15~60us

18

19 //ds18b20 pull pin low : 60-240us

20 gpt_delay_us(70);

21 level = ds18b20_read_level();

22

23 gpt_delay_us(200);

24 if(level == DS18B20_HIGH_LEVEL){

25 uart_printf("Detect ds18b20 failed\r\n");

26 return -1;

27 }else{

28 uart_printf("Detect ds1b20 success\r\n");

29 }

30

31 return 0;

32 }

2.向DS18B20写入一个位

1 void ds18b20_write_bit(int bit)

2 {

3 if(bit){

4 /*

5 To generate a Write 1 time slot, after pulling the 1-Wire bus low,

6 the bus master must release the 1-Wire bus within 15us.

7 */

8 ds18b20_pin_output();

9 ds18b20_write_level(DS18B20_LOW_LEVEL);

10 ds18b20_pin_input();

11 gpt_delay_us(70);

12

13 }else{

14 /*

15 To generate a Write 0 time slot, after pulling the 1-Wire bus low,

16 the bus master must continueto hold the bus low for the duration of

17 the time slot (at least 60us).

18 */

19 ds18b20_pin_output();

20 ds18b20_write_level(DS18B20_LOW_LEVEL);

21 gpt_delay_us(80);

22 ds18b20_pin_input();

23 gpt_delay_us(10);

24 }

25

26 return;

27 }

3.从DS18B20读取一个位

1 uint8_t ds18b20_read_bit(void)

2 {

3 uint8_t bit;

4

5 /*

6 A read time slot is initiated by the master device pulling

7 the 1-Wire bus low for a minimum of 1us and then releasing the bus .

8 */

9 ds18b20_pin_output();

10 ds18b20_write_level(DS18B20_HIGH_LEVEL);

11 gpt_delay_us(1);

12 ds18b20_write_level(DS18B20_LOW_LEVEL);

13 gpt_delay_us(5);

14 ds18b20_pin_input();

15 gpt_delay_us(3);

16 /*

17 Outputdata from the DS18B20 is valid for 15us after the falling edge

18 that initiated the read time slot.

19 */

20 bit = ds18b20_read_level();

21

22 gpt_delay_us(60);

23

24 return bit;

25 }

4.向DS18B20写入一个字节

1 void ds18b20_write_byte(uint8_t data)

2 {

3 int i;

4 int bit;

5

6 for(i = 0;i < 8;i ++){

7 bit = data & 1;

8 ds18b20_write_bit(bit);

9 data = data >> 1;

10 }

11

12 return;

13 }

5.从DS18B20读取一个字节

1 uint8_t ds18b20_read_byte(void)

2 {

3 int i;

4 uint8_t bit;

5 uint8_t data = 0;

6

7 for(i = 0;i < 8;i ++){

8 bit = ds18b20_read_bit();

9 if(bit){

10 //0000 0000

11 data = data | (1 << i);

12 }

13 }

14

15 return data;

16 }

九、读取DS1B20的ID和采集的温度

1.读取ID

1 void ds18b20_read_id(void)

2 {

3 int i;

4 int ret;

5 uint8_t serial_id[8];

6

7 ds18b20_gpio_init();

8

9 ret = ds18b20_init_detect();

10 if (ret == DS18B20_OK)

11 {

12 uart_printf("detect ds18b20\r\n");

13 }

14 else

15 {

16 uart_printf("not found ds18b20\r\n");

17 return;

18 }

19

20 // ds18b20_write_byte(0xcc);

21 ds18b20_write_byte(0x33); // Read ROM指令

22

23 serial_id[0] = ds18b20_read_byte();

24 serial_id[1] = ds18b20_read_byte();

25 serial_id[2] = ds18b20_read_byte();

26 serial_id[3] = ds18b20_read_byte();

27 serial_id[4] = ds18b20_read_byte();

28 serial_id[5] = ds18b20_read_byte();

29 serial_id[6] = ds18b20_read_byte();

30 serial_id[7] = ds18b20_read_byte();

31

32 uart_printf("Serial ID:");

33 for (i = 7; i >= 0; i--)

34 {

35 uart_printf("%02x", serial_id[i]);

36 }

37 uart_printf("\r\n");

38

39 return;

40 }

输出效果如下:

1 detect ds18b20

2 Serial ID:9806224649f80028

3

4 Data:28 00 f8 49 46 22 06

5 CRC :0x98

6

通过在线CRChttp://www.ip33.com/crc.html验证自己读取的ID是否正确

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

DS18B20的CRC校验多项式如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.读取温度

1 void read_ds18b20_temperature(void)

2 {

3 int ret;

4 uint8_t data[2];

5 uint16_t temperature;

6 uint8_t low4bit;

7 uint8_t interger;

8 uint8_t temp[2];

9

10 ds18b20_pin_init();

11 ret = ds18b20_detect();

12 if(ret < 0){

13 return;

14 }

15 ds18b20_write_byte(0xcc);//skip rom

16 ds18b20_write_byte(0x44);//转换命令

17

18 gpt_delay_sec(1);

19

20 ds18b20_pin_init();

21 ret = ds18b20_detect();

22 if(ret < 0){

23 return;

24 }

25 ds18b20_write_byte(0xcc);//skip rom

26 ds18b20_write_byte(0xbe);//读取 SCRATCHPAD

27

28 data[0] = ds18b20_read_byte();

29 data[1] = ds18b20_read_byte();

30

31 uart_printf("Temp H:%x,Temp L:%x\r\n",data[1],data[0]);

32 temperature = *((uint16_t *)data);

33

34 low4bit = temperature & 0xf;

35 interger = temperature >> 4;

36 if(interger & 0x80){//1000 0000

37 temp[1] = ~interger;

38 if(low4bit & 0x8){//1000

39 temp[0] = ~low4bit + 1;

40 }else{

41 temp[0] = low4bit;

42 }

43

44 //0.0625 x 10000 = 625

45 uart_printf("temperature:-%d.%04d\r\n",temp[1],625 * temp[0]);

46 }else{

47 temp[1] = interger;

48 temp[0] = low4bit;

49 uart_printf("temperature:%d.%04d\r\n",temp[1],625 * temp[0]);

50 }

51

52 return;

53 }

3.完整代码

1 #include "imx6ull.h"

2

3 #define DS18B20_HIGH_LEVEL 1

4 #define DS18B20_LOW_LEVEL 0

5

6 void ds18b20_pin_init(void)

7 {

8 IOMUXC_SW_MUX_CTL_PAD_GPIO5_IO02 &= ~(0xf << 0);

9 IOMUXC_SW_MUX_CTL_PAD_GPIO5_IO02 |= (0x5 << 0);

10

11 return;

12 }

13

14 //read direction

15 void ds18b20_pin_input(void)

16 {

17 GPIO5->GDIR &= ~(1 << 2);

18 }

19

20 //write direction

21 void ds18b20_pin_output(void)

22 {

23 GPIO5->GDIR |= (1 << 2);

24 }

25

26 //write level

27 void ds18b20_write_level(int level)

28 {

29 if(level){

30 GPIO5->DR |= (1 << 2);

31 }else{

32 GPIO5->DR &= ~(1 << 2);

33 }

34

35 return;

36 }

37

38 int ds18b20_read_level(void)

39 {

40 int level;

41

42 level = GPIO5->PSR & (1 << 2);

43 return level ? 1 : 0;

44 }

45

46 int ds18b20_detect(void)

47 {

48 int level;

49

50 ds18b20_pin_output();

51 ds18b20_write_level(DS18B20_HIGH_LEVEL);

52 gpt_delay_us(10);

53 /*

54 *master transmits (TX) the reset pulse by pulling the

55 *1-Wire bus low for a minimum of 480us.

56 */

57 ds18b20_write_level(DS18B20_LOW_LEVEL);

58 gpt_delay_us(700);

59

60 ds18b20_write_level(DS18B20_HIGH_LEVEL);

61 ds18b20_pin_input();

62 //wait 15~60us

63

64 //ds18b20 pull pin low : 60-240us

65 gpt_delay_us(70);

66 level = ds18b20_read_level();

67

68 gpt_delay_us(200);

69 if(level == DS18B20_HIGH_LEVEL){

70 uart_printf("Detect ds18b20 failed\r\n");

71 return -1;

72 }else{

73 uart_printf("Detect ds1b20 success\r\n");

74 }

75

76 return 0;

77 }

78

79 void ds18b20_write_bit(int bit)

80 {

81 if(bit){

82 /*

83 To generate a Write 1 time slot, after pulling the 1-Wire bus low,

84 the bus master must release the 1-Wire bus within 15us.

85 */

86 ds18b20_pin_output();

87 ds18b20_write_level(DS18B20_LOW_LEVEL);

88 ds18b20_pin_input();

89 gpt_delay_us(70);

90

91 }else{

92 /*

93 To generate a Write 0 time slot, after pulling the 1-Wire bus low,

94 the bus master must continueto hold the bus low for the duration of

95 the time slot (at least 60us).

96 */

97 ds18b20_pin_output();

98 ds18b20_write_level(DS18B20_LOW_LEVEL);

99 gpt_delay_us(80);

100 ds18b20_pin_input();

101 gpt_delay_us(10);

102 }

103

104 return;

105 }

106

107 void ds18b20_write_byte(uint8_t data)

108 {

109 int i;

110 int bit;

111

112 for(i = 0;i < 8;i ++){

113 bit = data & 1;

114 ds18b20_write_bit(bit);

115 data = data >> 1;

116 }

117

118 return;

119 }

120

121 uint8_t ds18b20_read_bit(void)

122 {

123 uint8_t bit;

124

125 /*

126 A read time slot is initiated by the master device pulling

127 the 1-Wire bus low for a minimum of 1us and then releasing the bus .

128 */

129 ds18b20_pin_output();

130 ds18b20_write_level(DS18B20_HIGH_LEVEL);

131 gpt_delay_us(1);

132 ds18b20_write_level(DS18B20_LOW_LEVEL);

133 gpt_delay_us(5);

134 ds18b20_pin_input();

135 gpt_delay_us(3);

136 /*

137 Outputdata from the DS18B20 is valid for 15us after the falling edge

138 that initiated the read time slot.

139 */

140 bit = ds18b20_read_level();

141

142 gpt_delay_us(60);

143

144 return bit;

145 }

146

147 uint8_t ds18b20_read_byte(void)

148 {

149 int i;

150 uint8_t bit;

151 uint8_t data = 0;

152

153 for(i = 0;i < 8;i ++){

154 bit = ds18b20_read_bit();

155 if(bit){

156 //0000 0000

157 data = data | (1 << i);

158 }

159 }

160

161 return data;

162 }

163

164 void read_ds18b20_id(void)

165 {

166 int i;

167 int ret;

168 uint8_t id[8];

169

170 ds18b20_pin_init();

171 ret = ds18b20_detect();

172 if(ret < 0){

173 return;

174 }

175 ds18b20_write_byte(0x33);

176

177 for(i = 0;i < 8;i ++){

178 id[i] = ds18b20_read_byte();

179 }

180

181 uart_printf("H-L : ");

182 for(i = 7;i >=0 ;i --){

183 uart_printf("%x ",id[i]);

184 }

185 uart_printf("\r\n");

186

187 uart_printf("L-H : ");

188 for(i = 0;i < 8;i ++){

189 uart_printf("%x ",id[i]);

190 }

191 uart_printf("\r\n");

192

193 return;

194 }

195

196 void read_ds18b20_temperature(void)

197 {

198 int ret;

199 uint8_t data[2];

200 uint16_t temperature;

201 uint8_t low4bit;

202 uint8_t interger;

203 uint8_t temp[2];

204

205 ds18b20_pin_init();

206 ret = ds18b20_detect();

207 if(ret < 0){

208 return;

209 }

210 ds18b20_write_byte(0xcc);//skip rom

211 ds18b20_write_byte(0x44);//转换命令

212

213 gpt_delay_sec(1);

214

215 ds18b20_pin_init();

216 ret = ds18b20_detect();

217 if(ret < 0){

218 return;

219 }

220 ds18b20_write_byte(0xcc);//skip rom

221 ds18b20_write_byte(0xbe);//读取 SCRATCHPAD

222

223 data[0] = ds18b20_read_byte();

224 data[1] = ds18b20_read_byte();

225

226 uart_printf("Temp H:%x,Temp L:%x\r\n",data[1],data[0]);

227 temperature = *((uint16_t *)data);

228

229 low4bit = temperature & 0xf;

230 interger = temperature >> 4;

231 if(interger & 0x80){//1000 0000

232 temp[1] = ~interger;

233 if(low4bit & 0x8){//1000

234 temp[0] = ~low4bit + 1;

235 }else{

236 temp[0] = low4bit;

237 }

238

239 //0.0625 x 10000 = 625

240 uart_printf("temperature:-%d.%04d\r\n",temp[1],625 * temp[0]);

241 }else{

242 temp[1] = interger;

243 temp[0] = low4bit;

244 uart_printf("temperature:%d.%04d\r\n",temp[1],625 * temp[0]);

245 }

246

247 return;

248 }

249

250 void ds18b20_test(void)

251 {

252 while(1){

253 read_ds18b20_id();

254 read_ds18b20_temperature();

255 gpt_delay_sec(1);

256 }

257 return;

258 }