ds18b20.c文件#include “ds18b20.h” #include “user_SysTick.h” /******************************************************************************* 函 数 名 : DS18B20_IO_IN 函数功能 : DS18B20_IO输入配置 输 入 : 无 输 出 : 无 *******************************************************************************/ void DS18B20_IO_IN(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=DS18B20_PIN; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; GPIO_Init(DS18B20_PORT,&GPIO_InitStructure); } /******************************************************************************* 函 数 名 : DS18B20_IO_OUT 函数功能 : DS18B20_IO输出配置 输 入 : 无 输 出 : 无 *******************************************************************************/ void DS18B20_IO_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=DS18B20_PIN; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_Init(DS18B20_PORT,&GPIO_InitStructure); } /******************************************************************************* 函 数 名 : DS18B20_Reset 函数功能 : 复位DS18B20 输 入 : 无 输 出 : 无 *******************************************************************************/ void DS18B20_Reset(void) { DS18B20_IO_OUT(); //SET PG11 OUTPUT DS18B20_DQ_OUT=0; //拉低DQ SysTick_Delay_Us(750); //拉低750us DS18B20_DQ_OUT=1; //DQ=1 SysTick_Delay_Us(15); //15US } /******************************************************************************* 函 数 名 : DS18B20_Check 函数功能 : 检测DS18B20是否存在 输 入 : 无 输 出 : 1:未检测到DS18B20的存在,0:存在 *******************************************************************************/ u8 DS18B20_Check(void) { u8 retry=0; DS18B20_IO_IN();//SET PG11 INPUT while (DS18B20_DQ_IN&&retry<200) { retry++; SysTick_Delay_Us(1); }; if(retry>=200) return 1; else retry=0; while (!DS18B20_DQ_IN&&retry<240) { retry++; SysTick_Delay_Us(1); }; if(retry>=240) return 1; return 0; } /******************************************************************************* 函 数 名 : DS18B20_Read_Bit 函数功能 : 从DS18B20读取一个位 输 入 : 无 输 出 : 1/0 *******************************************************************************/ u8 DS18B20_Read_Bit(void) // read one bit { u8 data; DS18B20_IO_OUT();//SET PG11 OUTPUT DS18B20_DQ_OUT=0; SysTick_Delay_Us(2); DS18B20_DQ_OUT=1; DS18B20_IO_IN();//SET PG11 INPUT SysTick_Delay_Us(12); if(DS18B20_DQ_IN) data=1; else data=0; SysTick_Delay_Us(50); return data; } /******************************************************************************* 函 数 名 : DS18B20_Read_Byte 函数功能 : 从DS18B20读取一个字节 输 入 : 无 输 出 : 一个字节数据 *******************************************************************************/ u8 DS18B20_Read_Byte(void) // read one byte { u8 i,j,dat; dat=0; for (i=1;i<=8;i++) { j=DS18B20_Read_Bit(); dat=(j<<7)|(dat>>1); } return dat; } /******************************************************************************* 函 数 名 : DS18B20_Write_Byte 函数功能 : 写一个字节到DS18B20 输 入 : dat:要写入的字节 输 出 : 无 *******************************************************************************/ void DS18B20_Write_Byte(u8 dat) { u8 j; u8 testb; DS18B20_IO_OUT();//SET PG11 OUTPUT; for (j=1;j<=8;j++) { testb=dat&0x01; dat=dat>>1; if (testb) { DS18B20_DQ_OUT=0;// Write 1 SysTick_Delay_Us(2); DS18B20_DQ_OUT=1; SysTick_Delay_Us(60); } else { DS18B20_DQ_OUT=0;// Write 0 SysTick_Delay_Us(60); DS18B20_DQ_OUT=1; SysTick_Delay_Us(2); } } } /******************************************************************************* 函 数 名 : DS18B20_Start 函数功能 : 开始温度转换 输 入 : 无 输 出 : 无 *******************************************************************************/ void DS18B20_Start(void)// ds1820 start convert { DS18B20_Reset(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0x44); } /******************************************************************************* 函 数 名 : DS18B20_Init 函数功能 : 初始化DS18B20的IO口 DQ 同时检测DS的存在 输 入 : 无 输 出 : 1:不存在,0:存在 *******************************************************************************/ u8 DS18B20_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(DS18B20_PORT_RCC,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE); GPIO_InitStructure.GPIO_Pin=DS18B20_PIN; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_Init(DS18B20_PORT,&GPIO_InitStructure); DS18B20_Reset(); return DS18B20_Check(); } /******************************************************************************* 函 数 名 : DS18B20_GetTemperture 函数功能 : 从ds18b20得到温度值 输 入 : 无 输 出 : 温度数据 *******************************************************************************/ float DS18B20_GetTemperture(void) { u16 temp; u8 a,b; float value; DS18B20_Start(); // ds1820 start convert DS18B20_Reset(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0xbe); a=DS18B20_Read_Byte(); b=DS18B20_Read_Byte(); temp=b; temp=(temp<<8)+a; if((temp&0xf800)==0xf800) { temp=(~temp)+1; value=temp*(-0.0625); } else { value=temp*0.0625; } return value; } ds18b20.h文件#ifndef DS18B20_H #define DS18B20_H #include “stm32f10x.h” /* DS18B20时钟端口、引脚定义 */ #define DS18B20_PORT GPIOA #define DS18B20_PIN (GPIO_Pin_6) #define DS18B20_PORT_RCC RCC_APB2Periph_GPIOA #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //F103XXIO 口地址映射 #define GPIOA_ODR_Addr (GPIOA_BASE+0x0C) //0x40020014 #define GPIOB_ODR_Addr (GPIOB_BASE+0x0C) //0x40020414 #define GPIOC_ODR_Addr (GPIOC_BASE+0x0C) //0x40020814 #define GPIOD_ODR_Addr (GPIOD_BASE+0x0C) //0x40020C14 #define GPIOE_ODR_Addr (GPIOE_BASE+0x0C) //0x40021014 #define GPIOA_IDR_Addr (GPIOA_BASE+0x08) //0x40020010 #define GPIOB_IDR_Addr (GPIOB_BASE+0x08) //0x40020410 #define GPIOC_IDR_Addr (GPIOC_BASE+0x08) //0x40020810 #define GPIOD_IDR_Addr (GPIOD_BASE+0x08) //0x40020C10 #define GPIOE_IDR_Addr (GPIOE_BASE+0x08) //0x40021010 //F103XXIO 口操作,只对单一的IO 口,n 的值范围[0-15] #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //GPIOA 某一位输出 #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //GPIOA 某一位输入 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //GPIOB 某一位输出 #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //GPIOB 某一位输入 #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //GPIOC 某一位输出 #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //GPIOC 某一位输入 #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //GPIOD 某一位输出 #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //GPIOD 某一位输入 #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //GPIOE 某一位输出 #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //GPIOE 某一位输入 ////IO操作函数 #define DS18B20_DQ_OUT PAout(6) //数据输出 #define DS18B20_DQ_IN PAin(6) //数据输入 u8 DS18B20_Init(void); //初始化DS18B20 float DS18B20_GetTemperture(void); //获取温度 void DS18B20_Start(void); //开始温度转换 void DS18B20_Write_Byte(u8 dat);//写入一个字节 u8 DS18B20_Read_Byte(void); //读出一个字节 u8 DS18B20_Read_Bit(void); //读出一个位 u8 DS18B20_Check(void); //检测是否存在DS18B20 void DS18B20_Reset(void); //复位DS18B20 #endif 告诉我温度传感器的工作原理?他是怎么被STM32控制的?它和STM32之间是怎么通信的?
时间: 2025-05-28 09:41:41 浏览: 25
温度传感器DS18B20的工作原理基于热敏电阻的特性,它能够感知环境温度的变化并将其转化为电信号。DS18B20是一款数字温度传感器,具有单总线通信协议,这意味着它只需要一根数据线与微控制器(如STM32)进行通信。以下是详细解释:
### DS18B20工作原理
DS18B20内部包含一个温度敏感元件和A/D转换器。当环境温度发生变化时,该元件会检测到这些变化,并通过A/D转换器将模拟信号转换为数字信号。DS18B20支持9到12位的分辨率,允许用户根据需求选择不同的精度。
### STM32对DS18B20的控制
STM32通过GPIO引脚与DS18B20连接。在代码中可以看到,DS18B20的数据引脚被配置为GPIOA的第6引脚。STM32通过设置这个引脚的高低电平来发送命令或读取数据。
#### 主要步骤:
1. **初始化**:STM32初始化DS18B20相关的GPIO引脚。
2. **复位**:发送复位脉冲以确保DS18B20进入准备状态。
3. **存在性检测**:确认DS18B20是否连接。
4. **发送命令**:发送开始转换温度的命令。
5. **读取数据**:从DS18B20读取温度数据。
### 通信方式
DS18B20使用单总线协议与STM32通信。单总线协议的特点是只用一根数据线完成所有通信任务,包括数据的发送和接收。
#### 单总线通信过程:
- **复位**:主机(STM32)拉低数据线至少480微秒,然后释放。如果从机(DS18B20)存在,它会在15到60微秒内拉低数据线作为响应。
- **写操作**:主机发送数据给从机。每一位的传输时间约为60微秒。
- **读操作**:主机读取从机的数据。每一位的读取时间也约为60微秒。
下面是实现上述功能的部分代码示例:
```c
void DS18B20_Reset(void)
{
DS18B20_IO_OUT(); // 设置PG11为输出模式
DS18B20_DQ_OUT=0; // 拉低DQ
SysTick_Delay_Us(750); // 延迟750us
DS18B20_DQ_OUT=1; // 释放DQ
SysTick_Delay_Us(15); // 延迟15us
}
u8 DS18B20_Read_Bit(void)
{
u8 data;
DS18B20_IO_OUT(); // 设置PG11为输出模式
DS18B20_DQ_OUT=0; // 拉低DQ
SysTick_Delay_Us(2); // 延迟2us
DS18B20_DQ_OUT=1; // 释放DQ
DS18B20_IO_IN(); // 设置PG11为输入模式
SysTick_Delay_Us(12); // 延迟12us
if(DS18B20_DQ_IN) // 读取DQ的状态
data=1;
else
data=0;
SysTick_Delay_Us(50); // 等待剩余的时间
return data;
}
```
上述代码中`DS18B20_Reset`函数实现了DS18B20的复位操作,而`DS18B20_Read_Bit`函数则用于从DS18B20读取一位数据。
### 结论
通过单总线协议,STM32可以有效地控制DS18B20并读取温度数据。这种通信方式简单高效,非常适合在嵌入式系统中使用。
阅读全文
相关推荐















