野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 8859|回复: 1

指南者驱动ds18b20的驱动代码分享

[复制链接]
发表于 2022-5-24 22:05:33 | 显示全部楼层 |阅读模式
硬件连接:DQ连接到PB7引脚,VCC连接5V, GND连接地(DQ的引脚可以在硬件宏中进行更改)

实验验证:利用串口将温度信息进行打印

驱动代码
bsp_ds18b20.c

  1. #include "bsp_ds18b20.h"

  2. static uint8_t Read_Byte(void);
  3. static uint8_t Read_Bit(void);
  4. static void Write_Bit_1(void);
  5. static void Write_Bit_0(void);
  6. static void Write_Byte(uint8_t dat);
  7. static void DS_DIR_OUT(void);
  8. static void DS_DIR_IN(void);


  9. void Init_DS18B20(void)
  10. {
  11.         uint8_t t = 0;
  12.         DS_DIR_OUT();        //设置GPIO为推挽输出模式
  13.         GPIO_SetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN);
  14.         delay_us(10);
  15.         GPIO_ResetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN);        //发送一个复位脉冲
  16.         delay_us(600);        //延时>480us
  17.         GPIO_SetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN);                //拉高数据线
  18.         delay_us(55);        //等待15-60us
  19.         DS_DIR_IN();        //设置GPIO口为上拉输入模式
  20.         while (GPIO_ReadInputDataBit(DS18B20_DQ_PORT, DS18B20_DQ_PIN) == SET)        //等待被拉低
  21.         {
  22.                 delay_us(1);
  23.                 t++;
  24.                 if (t>=240)
  25.                 {
  26.                         printf("DS18B20初始化失败\n");
  27.                         return ;
  28.                 }
  29.         }

  30.         t = 0;

  31.         /* 等待总线被释放 */
  32.         while (GPIO_ReadInputDataBit(DS18B20_DQ_PORT, DS18B20_DQ_PIN)==RESET && t<=240)
  33.         {
  34.                 t++;
  35.                 delay_us(1);
  36.         }
  37.         if (t>=240)
  38.                 printf("DS18B20初始化失败\n");
  39. //        else
  40. //                printf("DS18B20在线\n");
  41. }

  42. /**
  43. * [url=home.php?mod=space&uid=41770]@brief[/url] 向DS18B20写入一位0
  44. *
  45. */
  46. static void Write_Bit_0(void)
  47. {
  48.         GPIO_ResetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN);        //启动总线
  49.         delay_us(90);                                                //在60us-120us之间
  50.         GPIO_SetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN);                //释放总线,0写入完成
  51.         delay_us(10);                                                //至少1us
  52. }

  53. /**
  54. * @brief 向DS18B20写入一位1
  55. *
  56. */

  57. static void Write_Bit_1(void)
  58. {
  59.         GPIO_ResetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN);        //启动总线
  60.         delay_us(10);                                                //大于1us
  61.         GPIO_SetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN);                //写入1
  62.         delay_us(50);                                                //在15-60us之间
  63. }

  64. /**
  65. * @brief 单片机从DS18B20读一位
  66. *
  67. */
  68. static uint8_t Read_Bit(void)
  69. {
  70.         uint8_t dat;
  71.         /* 设置GPIO为输出模式 */
  72.         DS_DIR_OUT();
  73.         GPIO_ResetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN);        //启动总线
  74.         delay_us(8);                                                //大于1us
  75.         DS_DIR_IN();                                                //设置为上拉输入模式,从GPIO读取数据

  76.         if (GPIO_ReadInputDataBit(DS18B20_DQ_PORT, DS18B20_DQ_PIN))        //高电平返回1
  77.                 dat = 1;
  78.         else                                                                //低电平返回0
  79.         {
  80.                 dat = 0;
  81.         }

  82.         delay_us(50);

  83.         return dat;        
  84. }

  85. /**
  86. * @brief 从DS18B20读取一个字节
  87. *
  88. */
  89. static uint8_t Read_Byte(void)
  90. {
  91.         uint8_t i, dat=0;

  92.         for (i=0; i<8; i++)
  93.         {
  94.                 dat = dat | (Read_Bit()<<i);        //DS18B20先传递低位
  95.         }
  96.         return dat;
  97. }


  98. /**
  99. * @brief 单片机向DS18B20写入一个字节
  100. *
  101. */

  102. static void Write_Byte(uint8_t dat)
  103. {
  104.         uint8_t i=0;
  105.         DS_DIR_OUT();                //设置GPIO为输出方向

  106.         for(i=0; i<8; i++)
  107.         {
  108.                 if (dat & (1<<i))
  109.                         Write_Bit_1();
  110.                 else
  111.                         Write_Bit_0();
  112.         }
  113. }

  114. double Read_Temperature(void)
  115. {
  116.         uint8_t tempL, tempH;
  117.         double temp;

  118.         Init_DS18B20();                //初始化DS18B20
  119.         Write_Byte(0xCC);        //跳过读取序列号操作
  120.         Write_Byte(0x44);        //启动温度转换

  121.         
  122.         /* 等待DS18B20温度转化完成 */
  123.         while (Read_Bit()==0)
  124.         {
  125.                 delay_us(100000);        //100ms
  126.         }
  127.         Init_DS18B20();                //再次初始化DS18B20
  128.         Write_Byte(0xCC);        
  129.         Write_Byte(0xBE);        //读取温度寄存器
  130.         tempL = Read_Byte();        //读取LSB
  131.         tempH = Read_Byte();        //读取MSB

  132.         if (tempH>0x7F)                //最高位为1,则表示为负数
  133.         {
  134.                 tempL = ~tempL;        //???????
  135.                 tempH = ~tempH + 1;
  136.         }
  137.         temp = ( (tempH<<8) + tempL ) * 0.0625;

  138.         return temp;
  139. }

  140. /* 设置DS18B20为接收指令模式 */
  141. void DS_DIR_OUT(void)
  142. {
  143.         GPIO_InitTypeDef GPIO_InitStructure;

  144.         RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE);

  145.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  146.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  147.         GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_PIN;

  148.         GPIO_Init(DS18B20_DQ_PORT, &GPIO_InitStructure);
  149. }

  150. /* 设置DS18B20为发送数据模式 */
  151. void DS_DIR_IN(void)
  152. {
  153.         GPIO_InitTypeDef GPIO_InitStructure;

  154.         RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE);

  155.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  156.         GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_PIN;

  157.         GPIO_Init(DS18B20_DQ_PORT, &GPIO_InitStructure);
  158. }

  159. /**
  160.         * @brief 读取DS18B20的64位CODE
  161.         */

  162. void Read_DS18B20_Code(void)
  163. {
  164.         uint8_t i;
  165.         uint8_t code[4];
  166.         
  167.         /* 对DS18B20进行初始化 */
  168.         Init_DS18B20();
  169.         /* 读取CODE */
  170.         Write_Byte(0x33);
  171.         for (i=0; i<3; i++)
  172.         {
  173.                 code[i] = Read_Byte();
  174.         }
  175.         printf("Code = %x%x%x%x\n", code[3], code[2], code[1], code[0]);
  176. }

  177. /**
  178. * @brief 设置DS18B20进行警报的上下界
  179. *
  180. */

  181. void Set_DS18B20_Alarm(int8_t th, int8_t tl)
  182. {
  183.         /* 对DS18B20进行初始化 */
  184.         Init_DS18B20();
  185.         /* 跳过对DS18B20的寻址 */
  186.         Write_Byte(0xCC);
  187.         /* 准备对2,3字节写入数据 */
  188.         Write_Byte(0x4E);
  189.         /* 对2,3字节写入数据 */
  190.         Write_Byte(th);
  191.         Write_Byte(tl);
  192.         Write_Byte(0x7F);        //设置12bit
  193. }

  194. /**
  195. * @brief 读取DS18B20寄存器中的数据
  196. *
  197. */

  198. void Read_DS18B20_Data(void)
  199. {
  200.         uint8_t i;
  201.         Init_DS18B20();
  202.         Write_Byte(0xCC);
  203.         Write_Byte(0xBE);

  204.         for(i=0; i<9; i++)
  205.         {
  206.                 printf("Byte%d: %x\n", i, Read_Byte());
  207.         }
  208. }
复制代码
bsp_ds18b20.h
  1. /****************************

  2.         * DS18B20的驱动程序
  3.         * 条件
  4.                                 需要实现 void delay_us(uint32_t delay),实现delay微秒的定时

  5. ****************************/


  6. #ifndef BSP_DS18B20_H_
  7. #define BSP_DS18B20_H_


  8. #include "stm32f10x.h"
  9. #include <stdio.h>

  10. /* 硬件端口的相关定义 */
  11. #define DS18B20_DQ_PORT        GPIOB
  12. #define DS18B20_DQ_PIN GPIO_Pin_7
  13. #define DS18B20_CLK        RCC_APB2Periph_GPIOA

  14. /* 使用到的函数定义 */

  15. void Init_DS18B20(void);                                        //对DS18B20进行初始化
  16. double Read_Temperature(void);        //读取温度,将结果返回
  17. void Read_DS18B20_Code(void);                        //读取DS18B20的64位CODE码
  18. void Set_DS18B20_Alarm(int8_t th, int8_t tl);
  19. void Read_DS18B20_Data(void);                //读取寄存器中的数据


  20. extern void delay_us(uint32_t delay);

  21. #endif
复制代码




野火论坛202205242201433428..png
回复

使用道具 举报

发表于 2022-5-26 09:18:36 | 显示全部楼层
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 00:23 , Processed in 0.036783 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表