初中生
最后登录1970-1-1
在线时间 小时
注册时间2021-12-23
|
硬件连接:DQ连接到PB7引脚,VCC连接5V, GND连接地(DQ的引脚可以在硬件宏中进行更改)
实验验证:利用串口将温度信息进行打印
驱动代码
bsp_ds18b20.c
- #include "bsp_ds18b20.h"
- static uint8_t Read_Byte(void);
- static uint8_t Read_Bit(void);
- static void Write_Bit_1(void);
- static void Write_Bit_0(void);
- static void Write_Byte(uint8_t dat);
- static void DS_DIR_OUT(void);
- static void DS_DIR_IN(void);
- void Init_DS18B20(void)
- {
- uint8_t t = 0;
- DS_DIR_OUT(); //设置GPIO为推挽输出模式
- GPIO_SetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN);
- delay_us(10);
- GPIO_ResetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN); //发送一个复位脉冲
- delay_us(600); //延时>480us
- GPIO_SetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN); //拉高数据线
- delay_us(55); //等待15-60us
- DS_DIR_IN(); //设置GPIO口为上拉输入模式
- while (GPIO_ReadInputDataBit(DS18B20_DQ_PORT, DS18B20_DQ_PIN) == SET) //等待被拉低
- {
- delay_us(1);
- t++;
- if (t>=240)
- {
- printf("DS18B20初始化失败\n");
- return ;
- }
- }
- t = 0;
- /* 等待总线被释放 */
- while (GPIO_ReadInputDataBit(DS18B20_DQ_PORT, DS18B20_DQ_PIN)==RESET && t<=240)
- {
- t++;
- delay_us(1);
- }
- if (t>=240)
- printf("DS18B20初始化失败\n");
- // else
- // printf("DS18B20在线\n");
- }
- /**
- * [url=home.php?mod=space&uid=41770]@brief[/url] 向DS18B20写入一位0
- *
- */
- static void Write_Bit_0(void)
- {
- GPIO_ResetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN); //启动总线
- delay_us(90); //在60us-120us之间
- GPIO_SetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN); //释放总线,0写入完成
- delay_us(10); //至少1us
- }
- /**
- * @brief 向DS18B20写入一位1
- *
- */
- static void Write_Bit_1(void)
- {
- GPIO_ResetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN); //启动总线
- delay_us(10); //大于1us
- GPIO_SetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN); //写入1
- delay_us(50); //在15-60us之间
- }
- /**
- * @brief 单片机从DS18B20读一位
- *
- */
- static uint8_t Read_Bit(void)
- {
- uint8_t dat;
- /* 设置GPIO为输出模式 */
- DS_DIR_OUT();
- GPIO_ResetBits(DS18B20_DQ_PORT, DS18B20_DQ_PIN); //启动总线
- delay_us(8); //大于1us
- DS_DIR_IN(); //设置为上拉输入模式,从GPIO读取数据
- if (GPIO_ReadInputDataBit(DS18B20_DQ_PORT, DS18B20_DQ_PIN)) //高电平返回1
- dat = 1;
- else //低电平返回0
- {
- dat = 0;
- }
- delay_us(50);
- return dat;
- }
- /**
- * @brief 从DS18B20读取一个字节
- *
- */
- static uint8_t Read_Byte(void)
- {
- uint8_t i, dat=0;
- for (i=0; i<8; i++)
- {
- dat = dat | (Read_Bit()<<i); //DS18B20先传递低位
- }
- return dat;
- }
- /**
- * @brief 单片机向DS18B20写入一个字节
- *
- */
- static void Write_Byte(uint8_t dat)
- {
- uint8_t i=0;
- DS_DIR_OUT(); //设置GPIO为输出方向
- for(i=0; i<8; i++)
- {
- if (dat & (1<<i))
- Write_Bit_1();
- else
- Write_Bit_0();
- }
- }
- double Read_Temperature(void)
- {
- uint8_t tempL, tempH;
- double temp;
- Init_DS18B20(); //初始化DS18B20
- Write_Byte(0xCC); //跳过读取序列号操作
- Write_Byte(0x44); //启动温度转换
-
- /* 等待DS18B20温度转化完成 */
- while (Read_Bit()==0)
- {
- delay_us(100000); //100ms
- }
- Init_DS18B20(); //再次初始化DS18B20
- Write_Byte(0xCC);
- Write_Byte(0xBE); //读取温度寄存器
- tempL = Read_Byte(); //读取LSB
- tempH = Read_Byte(); //读取MSB
- if (tempH>0x7F) //最高位为1,则表示为负数
- {
- tempL = ~tempL; //???????
- tempH = ~tempH + 1;
- }
- temp = ( (tempH<<8) + tempL ) * 0.0625;
- return temp;
- }
- /* 设置DS18B20为接收指令模式 */
- void DS_DIR_OUT(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE);
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_PIN;
- GPIO_Init(DS18B20_DQ_PORT, &GPIO_InitStructure);
- }
- /* 设置DS18B20为发送数据模式 */
- void DS_DIR_IN(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE);
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_PIN;
- GPIO_Init(DS18B20_DQ_PORT, &GPIO_InitStructure);
- }
- /**
- * @brief 读取DS18B20的64位CODE
- */
- void Read_DS18B20_Code(void)
- {
- uint8_t i;
- uint8_t code[4];
-
- /* 对DS18B20进行初始化 */
- Init_DS18B20();
- /* 读取CODE */
- Write_Byte(0x33);
- for (i=0; i<3; i++)
- {
- code[i] = Read_Byte();
- }
- printf("Code = %x%x%x%x\n", code[3], code[2], code[1], code[0]);
- }
- /**
- * @brief 设置DS18B20进行警报的上下界
- *
- */
- void Set_DS18B20_Alarm(int8_t th, int8_t tl)
- {
- /* 对DS18B20进行初始化 */
- Init_DS18B20();
- /* 跳过对DS18B20的寻址 */
- Write_Byte(0xCC);
- /* 准备对2,3字节写入数据 */
- Write_Byte(0x4E);
- /* 对2,3字节写入数据 */
- Write_Byte(th);
- Write_Byte(tl);
- Write_Byte(0x7F); //设置12bit
- }
- /**
- * @brief 读取DS18B20寄存器中的数据
- *
- */
- void Read_DS18B20_Data(void)
- {
- uint8_t i;
- Init_DS18B20();
- Write_Byte(0xCC);
- Write_Byte(0xBE);
- for(i=0; i<9; i++)
- {
- printf("Byte%d: %x\n", i, Read_Byte());
- }
- }
复制代码 bsp_ds18b20.h
- /****************************
- * DS18B20的驱动程序
- * 条件
- 需要实现 void delay_us(uint32_t delay),实现delay微秒的定时
- ****************************/
- #ifndef BSP_DS18B20_H_
- #define BSP_DS18B20_H_
- #include "stm32f10x.h"
- #include <stdio.h>
- /* 硬件端口的相关定义 */
- #define DS18B20_DQ_PORT GPIOB
- #define DS18B20_DQ_PIN GPIO_Pin_7
- #define DS18B20_CLK RCC_APB2Periph_GPIOA
- /* 使用到的函数定义 */
- void Init_DS18B20(void); //对DS18B20进行初始化
- double Read_Temperature(void); //读取温度,将结果返回
- void Read_DS18B20_Code(void); //读取DS18B20的64位CODE码
- void Set_DS18B20_Alarm(int8_t th, int8_t tl);
- void Read_DS18B20_Data(void); //读取寄存器中的数据
- extern void delay_us(uint32_t delay);
- #endif
复制代码
|
-
|