> 技术文档 > STM32F103单片机与DS18B20温度传感器交互实验套件

STM32F103单片机与DS18B20温度传感器交互实验套件

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:STM32F103是一款高性能的微控制器,适用于各种嵌入式系统设计。本实验课程主要教授如何使用STM32F103与DS18B20数字温度传感器进行通信。DS18B20是一款一线制数字温度传感器,能够直接输出数字信号,具有精度高、使用方便的特点。课程将涵盖从初始化GPIO、软件模拟一线制协议、传感器初始化、温度测量到数据处理的关键步骤。除此之外,还提供RTC、红外遥控和SysTick系统定时器的实验内容,帮助学生全面掌握嵌入式系统设计与传感器应用。
STM32F103

1. STM32F103单片机简介与应用

1.1 STM32F103单片机核心特点

STM32F103是STMicroelectronics公司生产的高性能ARM Cortex-M3微控制器。其特点包括高速运行频率(最高72 MHz),丰富的存储选项(最大128 KB闪存和20 KB SRAM),以及多种集成外设(如ADC、定时器、通信接口等)。这些特性使得STM32F103非常适合用于嵌入式应用,如工业控制、医疗设备、消费电子产品等。

1.2 STM32F103系统架构

该单片机的系统架构基于ARMv7-M架构,核心是Cortex-M3处理器。其包含一个32位RISC处理器、中断系统、存储保护单元、单周期乘法器和硬件除法器等。它还具备一个嵌套向量中断控制器(NVIC),提供多达24个中断通道,并支持优先级和子优先级。

1.3 STM32F103单片机应用领域

在实际应用中,STM32F103广泛应用于多种领域。例如,它可以作为汽车电子中的信息娱乐系统的控制核心,也可以在医疗仪器中处理数据和控制设备,或者用于工业自动化中进行信号采集与实时控制等。它提供高灵活性和可扩展性,支持多种开发环境,包括Keil MDK-ARM、IAR EWARM和GCC-based IDE等。

2. DS18B20数字温度传感器使用与特性

2.1 DS18B20传感器概述

DS18B20是Maxim公司生产的一款数字温度传感器,具有数字信号输出、宽温度测量范围、高精度等特点。传感器以一线制(One-Wire)接口通信,降低了硬件连接的复杂性,使其非常适合用于各种温度监测系统。

2.2 传感器技术特性分析

DS18B20的技术特性包括:
- 测量范围 :-55℃至+125℃,精度达到±0.5℃。
- 分辨率 :可编程设置9位至12位分辨率。
- 供电方式 :可外部供电,也可通过数据线寄生供电。
- 一线制通信 :简化了硬件连接,可实现多点温度监测。
- 报警功能 :具有可编程的高温和低温报警触发点。

2.3 引脚布局与功能

DS18B20的引脚功能如下:
- VDD :电源(3.0V至5.5V)。
- DQ :数据线(一线制通信)。
- GND :地线。

2.4 通信协议解析

DS18B20通信协议基于一线制技术,工作时序包括:
- 复位脉冲 :主设备向传感器发送复位脉冲,传感器响应后开始通信。
- 存在脉冲 :传感器在复位后发送一个存在脉冲,表明其准备就绪。
- ROM命令 :包括读ROM、匹配ROM、搜索ROM等,用于识别和选择特定的传感器。
- 功能命令 :包括启动温度转换、读取温度寄存器等,用于执行具体的功能。

2.5 温度数据读取实践

在实际应用中,读取DS18B20传感器的温度数据通常包含以下步骤:
1. 初始化 :初始化一线制总线和DS18B20传感器。
2. 发送复位脉冲 :确保传感器处于工作状态。
3. 发送ROM命令 :选择特定的DS18B20传感器。
4. 发送功能命令 :例如“转换温度”命令。
5. 等待转换完成 :根据分辨率等待一定时间。
6. 读取温度数据 :发送“读取温度寄存器”命令,并读取数据。

2.6 实际应用案例分析

下面我们通过一个实际案例,分析DS18B20在工业温度监控中的应用。

案例:工业温度监控系统

在工业领域,温度监控至关重要,DS18B20因其高精度和简单易用的特性,常被用于此类系统。

系统构建流程
  1. 硬件连接 :将DS18B20的VDD接到电源,GND接地,DQ连接到单片机的一个GPIO引脚。
  2. 软件编程 :编写程序,实现对DS18B20的初始化、温度读取等功能。
  3. 数据处理 :将读取到的数字信号转换为实际温度,并进行显示或记录。
  4. 报警机制 :设置温度阈值,实现高温或低温报警。
代码实现

下面是使用STM32单片机读取DS18B20温度数据的示例代码:

// 假设使用STM32 HAL库#include \"stm32f1xx_hal.h\"// DS18B20初始化函数void DS18B20_Init(void) { // 初始化一线制总线及GPIO}// 向DS18B20发送命令函数void DS18B20_SendCommand(uint8_t command) { // 通过GPIO发送命令到DS18B20}// 从DS18B20读取数据函数uint8_t DS18B20_ReadData(void) { // 从DS18B20读取数据}// 主函数int main(void) { HAL_Init(); // 初始化HAL库 DS18B20_Init(); // 初始化DS18B20 uint8_t tempData[2]; // 存储温度数据 int16_t temperature; // 启动温度转换 DS18B20_SendCommand(0x44); HAL_Delay(200); // 等待转换完成 // 读取温度数据 DS18B20_SendCommand(0xBE); tempData[0] = DS18B20_ReadData(); tempData[1] = DS18B20_ReadData(); // 将数据转换为温度 temperature = (int16_t)(tempData[1] << 8) | tempData[0]; // 根据DS18B20的数据手册进行进一步处理}

在上述代码中, DS18B20_Init 函数负责初始化一线制总线和DS18B20传感器的GPIO引脚。 DS18B20_SendCommand 函数用于向传感器发送命令,而 DS18B20_ReadData 函数则用于读取传感器返回的数据。主函数 main 中,首先初始化单片机和DS18B20,然后发送温度转换命令,等待转换完成并读取数据,最后将读取到的数据转换为温度值。

以上代码仅作为示例,具体实现时需要根据实际硬件连接和需求进行调整。

结果分析与优化

通过实验读取DS18B20传感器的数据,并将其转换为温度值后,我们可以通过进一步的分析和校准,优化温度读取的精度和系统的稳定性。同时,通过持续监控温度数据,我们可以对工业设备的运行状态进行实时判断和预警,保证生产过程的安全与效率。

在下一章节,我们将详细探讨如何通过STM32F103单片机的GPIO引脚配置实现一线制接口,并与DS18B20传感器进行数据交换。

3. GPIO引脚配置与一线制接口实现

引脚配置基础

STM32F103单片机提供了丰富的通用输入输出(GPIO)引脚,为开发人员提供了灵活的接口配置能力。在进行任何外设通信之前,正确配置GPIO引脚是至关重要的一步。

首先,我们需要理解GPIO引脚的模式选择,这包括输入模式(浮空、上拉、下拉)、输出模式(推挽和开漏)、复用功能模式和模拟模式。STM32F103的每个GPIO引脚都可以被编程为以上四种模式之一。

在本章节,我们将重点讨论一线制接口(One-Wire Protocol)实现过程中GPIO引脚的配置。一线制通信是一种串行通信协议,它允许数据的双向传输仅使用一根数据线(和地线),加上供电。这种通信方式在连接多个设备时非常节省引脚资源。

GPIO引脚配置代码示例

/* 配置GPIO引脚为推挽输出模式 */void GPIO_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; /* 使能GPIO端口时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* 配置GPIO引脚参数 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; // PB6配置为输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 输出速度50MHz /* 初始化GPIO端口 */ GPIO_Init(GPIOB, &GPIO_InitStructure);}

在上述代码中,我们首先使能了GPIOB端口的时钟。然后,我们创建了一个 GPIO_InitTypeDef 结构体变量,用来配置引脚。 GPIO_Pin_6 指明我们要配置的是B端口的第六个引脚。通过 GPIO_Mode_Out_PP 选项,我们将引脚配置为推挽输出模式,并设置输出速度为50MHz。

理解引脚配置的参数

在进行引脚配置时, GPIO_Mode 参数至关重要,它定义了引脚的工作模式:

  • GPIO_Mode_Out_PP :推挽输出,能够在引脚上输出高低电平。
  • GPIO_Mode_Out_OD :开漏输出,通常需要外部上拉电阻才能产生高电平。
  • GPIO_Mode_AF_PP :复用功能推挽输出,可以将引脚配置为特定外设的信号线。
  • GPIO_Mode_AF_OD :复用功能开漏输出,同上,但是为开漏模式。
  • GPIO_Mode_IPD :内部上拉输入。
  • GPIO_Mode_IPU :内部下拉输入。

一线制通信协议要点

一线制通信协议关键在于数据的同步和精确时序控制。在STM32F103中,我们需要精确控制GPIO引脚的电平变化,以满足一线制协议的严格时序要求。

一线制通信协议实现流程

  1. 初始化一线制总线为低电平。
  2. 产生复位脉冲。
  3. 等待设备响应。
  4. 发送ROM命令或功能命令。
  5. 读取或发送数据。

一线制通信代码示例

/* 一线制总线初始化函数 */void OneWire_Init(void){ /* 拉低总线 */ GPIO_ResetBits(GPIOB, GPIO_Pin_6); Delay(480); // 延时,至少480us GPIO_SetBits(GPIOB, GPIO_Pin_6);}/* 一线制复位脉冲函数 */uint8_t OneWire_Reset(void){ uint8_t presence = 0; /* 拉低总线 */ GPIO_ResetBits(GPIOB, GPIO_Pin_6); Delay(480); // 至少480us /* 释放总线 */ GPIO_SetBits(GPIOB, GPIO_Pin_6); Delay(70); // 等待70us /* 等待设备的存在脉冲 */ while(!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6)); // 等待直到总线被拉低 Delay(410); // 等待410us后检测总线状态 /* 检测设备的存在脉冲 */ if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6)) presence = 1; Delay(480); return presence;}

在此段代码中, OneWire_Init 函数用于初始化一线制总线,首先拉低总线480us以上,然后释放总线。 OneWire_Reset 函数用于检测一线制总线上是否存在设备,通过拉低总线等待设备回应,检测存在脉冲。

接下来,我们需要编写发送和接收字节的函数,确保每个时序都精确到位,满足一线制协议的要求。

4. 一线制协议时序控制与温度数据处理

4.1 一线制通信协议时序分析

一线制通信协议是一种非常简洁且高效的串行通信技术,被广泛应用于低速数据通信场合,尤其是在传感器数据采集系统中。一线制通信协议只需要一根数据线和一根地线,通信双方共享这一对信号线,因此非常适合在资源受限的嵌入式系统中使用。

4.1.1 一线制通信协议的时序要求

一线制通信协议的时序要求必须严格遵守,才能保证数据传输的正确性。在DS18B20传感器的应用中,一线制通信的时序主要包括以下几个方面:

  • 复位脉冲 :主机通过发送至少480微秒的低电平脉冲来进行复位操作。
  • 存在脉冲 :DS18B20在检测到复位脉冲后会发出一个存在脉冲,即60微秒至240微秒的高电平。
  • 写时序 :写一个位时,主机需要将数据线先拉低至少1微秒,然后释放数据线让其恢复到高电平状态。对于写0,高电平的持续时间需要在60微秒到120微秒之间;对于写1,高电平持续时间可以在1微秒到15微秒之间。
  • 读时序 :读取数据时,主机首先将数据线拉低,然后释放数据线,DS18B20会在主机释放后拉低数据线以输出0。读取1时,数据线会在主机释放后保持高电平。

下面是一段复位脉冲的示意性代码,展示了如何在STM32F103上实现复位脉冲的生成:

// 假设使用GPIOB的第10脚作为一线制数据线#define ONewire_PIN GPIO_Pin_10#define ONewire_PORT GPIOBvoid Delay_us(uint16_t us);void OneWire_Reset(void);void OneWire_Reset(void) { // 初始化数据线为高电平 GPIO_SetBits(ONewire_PORT, ONewire_PIN); Delay_us(480); // 延时至少480us // 拉低数据线持续至少480us GPIO_ResetBits(ONewire_PORT, ONewire_PIN); Delay_us(480); // 释放数据线,等待设备的应答脉冲 GPIO_SetBits(ONewire_PORT, ONewire_PIN); Delay_us(70); // 等待设备产生应答脉冲的高电平 // 如果检测到应答脉冲,数据线应仍保持高电平状态 if(GPIO_ReadInputDataBit(ONewire_PORT, ONewire_PIN) == Bit_RESET) { // 没有检测到应答脉冲,DS18B20可能未响应 }}

4.1.2 一线制时序控制实践

精确的时序控制是实现一线制通信的关键。为了确保数据的正确发送和接收,开发者通常使用精确的延时函数来控制时间间隔。然而,在嵌入式系统中,使用硬编码的延时并不总是可靠的,尤其是在不同的系统工作频率下。因此,开发者可能需要使用定时器来生成精确的时序。

4.1.3 使用定时器进行时序控制

STM32F103单片机含有丰富的定时器资源,可以用来实现精确的时序控制。以下是一个示例,展示了如何使用定时器来实现一线制协议的写时序:

void TIM_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / 1000000) - 1; // 1MHz计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 60; // 设置脉冲宽度 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM2, ENABLE); TIM_Cmd(TIM2, ENABLE);}

在上述代码中,我们配置了TIM2的时钟频率为1MHz,并设置了脉冲宽度为60个周期,这样可以在1微秒的时间内完成高电平的输出。通过改变TIM_OCInitStructure中的TIM_Pulse参数,可以精确控制高电平持续时间,从而满足一线制协议的写时序要求。

4.2 温度数据的读取与处理

DS18B20传感器通过一线制通信接口输出温度数据,这些数据以9位或10位的数字码形式存在,其中包含了温度信息的二进制补码表示。为了将这些原始数据转换为实际的温度值,开发者需要进行一系列的数据处理。

4.2.1 读取原始温度数据

首先,我们需要从DS18B20读取原始的温度数据,这需要在一线制协议的基础上进行读操作。数据的读取过程需要严格遵守一线制协议的读时序要求,以下是读取一个位的示例代码:

uint8_t OneWire_ReadBit(void) { uint8_t bit; // 拉低数据线以产生读时序 GPIO_ResetBits(ONewire_PORT, ONewire_PIN); Delay_us(1); // 释放数据线,等待DS18B20拉低数据线 GPIO_SetBits(ONewire_PORT, ONewire_PIN); Delay_us(14); // 读取数据线状态 bit = GPIO_ReadInputDataBit(ONewire_PORT, ONewire_PIN) ? 1 : 0; Delay_us(45); return bit;}

4.2.2 温度数据的转换与计算

在成功读取了原始温度数据后,我们需要将其转换成可读的温度值。DS18B20输出的数字码可以通过以下公式转换为摄氏度:

TEMP_READ = {LOW[7:0], HIGH[7:4]} / 16 °C

其中,LOW和HIGH分别是读取到的原始数据的低8位和高4位。以下是一个转换函数的示例代码:

int16_t DS18B20_GetTemperature(void) { uint8_t high, low; int16_t temp_read; // 激活传感器并发出转换温度命令 // ... // 等待转换完成 Delay_ms(750); // 读取温度数据 low = OneWire_ReadByte(); high = OneWire_ReadByte(); temp_read = (high << 8) | low; // 拼接低8位和高4位 // 转换为实际温度 temp_read = ((int16_t)(temp_read <> 4; if(temp_read > 511) { temp_read = -((temp_read ^ 0xFFF) + 1); // 转换为负温度值 } return temp_read;}

4.2.3 温度处理中的常见问题及解决方法

在温度数据处理过程中,开发者可能会遇到一些问题,例如数据传输错误、传感器故障或测量范围超出等情况。为了确保温度数据的准确性,开发者需要实现数据校验和错误处理机制。

  • 数据校验 :通常,DS18B20会使用CRC校验来确保数据传输的正确性。开发者需要在软件中实现相应的CRC计算,并验证从传感器读取的数据。
  • 错误处理 :如果校验失败,则需要重新发起读取请求,直到获得有效的数据为止。如果多次尝试失败,应考虑传感器是否发生故障或通信线路是否存在问题。

4.3 一线制协议实现的完整流程

将时序控制和数据处理结合起来,就形成了一个完整的一线制协议实现流程。这个流程不仅需要按照硬件协议的要求来执行,还需要考虑到软件层面的数据处理和异常处理。

4.3.1 初始化阶段

在初始化阶段,首先需要配置一线制数据线对应的GPIO引脚为开漏输出,并初始化定时器等硬件资源。

4.3.2 通信阶段

在通信阶段,首先发送复位脉冲以初始化一线制通信,然后执行写时序来发送所需的命令(比如温度转换命令),之后是读时序来读取数据。

4.3.3 数据处理阶段

数据处理阶段涉及将原始的数字码转换为实际的温度值,并进行必要的异常处理和数据校验。

4.3.4 错误处理和优化

如果在任何阶段出现错误,都需要进行适当的错误处理。同时,为了提高系统的稳定性和响应速度,可能需要对软件进行优化,例如减少不必要的延时、合理安排任务执行顺序等。

4.4 一线制通信的优势与应用场景

一线制通信因其简单性和低成本而被广泛应用在各种嵌入式系统中,尤其适用于需要多个传感器的场合。

4.4.1 一线制通信的优势

一线制通信的优势主要体现在以下几个方面:

  • 低成本 :仅需要一根数据线,降低了硬件成本。
  • 简单性 :通信协议简单,易于实现。
  • 扩展性 :可以在一根线上挂载多个设备。

4.4.2 典型应用场景分析

典型的一线制通信应用场景包括:

  • 家庭自动化 :温度、湿度等传感器。
  • 工业控制系统 :压力、流量等传感器。
  • 远程监控 :井下或海底等恶劣环境的监测设备。

一线制通信在这些场景中可以有效地减少布线的复杂性,降低系统整体成本,同时也便于维护和扩展。

通过本章的介绍,我们不仅深入理解了一线制通信协议的技术细节和实现方法,还学习了温度数据的处理和错误校验技术。这些知识对于在实际项目中应用DS18B20传感器和其他一线制设备至关重要。在下一章,我们将结合本章的知识点,通过具体的实践案例来进一步加深理解。

5. 综合应用实践与系统拓展

实验例程:构建温度监测系统

在本节中,我们将整合之前章节介绍的STM32F103单片机、DS18B20数字温度传感器和RTC模块的理论知识,通过具体的实验例程来实现一个完整的温度监测系统。此外,我们还将加入红外遥控模块HS0038,使其具备远程数据采集与控制功能。

首先,需要准备以下硬件组件:

  • STM32F103单片机开发板
  • DS18B20数字温度传感器
  • RTC模块(DS1302)
  • 红外遥控模块(HS0038)
  • 相关连线和电源

硬件连接

  1. STM32F103与DS18B20连接 :将DS18B20的数据线(DQ)连接到STM32F103的某个GPIO引脚上,同时需要一个10KΩ上拉电阻连接VDD到DQ。
  2. STM32F103与RTC模块连接 :将DS1302模块的通信线连接到STM32F103的特定SPI接口或通过GPIO模拟的接口。
  3. STM32F103与红外遥控模块连接 :HS0038的输出端连接到STM32F103的一个GPIO引脚,用于接收红外信号。

软件编程

接下来,我们需要编写程序来实现以下功能:

  • 初始化所有硬件模块
  • 实现DS18B20的温度读取
  • 显示温度值到LCD/串口
  • 使用RTC模块记录时间
  • 接收红外遥控信号并响应

以下是实现上述功能的伪代码示例:

// 初始化函数void setup_system() { // 初始化GPIO // 初始化DS18B20 // 初始化RTC模块 // 初始化红外遥控模块 // 初始化显示模块}// 主循环函数void loop() { // 读取温度 float temperature = read_temperature(); // 显示温度 display_temperature(temperature); // 检查是否接收到红外信号 if (is红外信号接收到()) { handle_infrared_signal(); } // 使用RTC模块的时间信息 use_RTC_info();}// DS18B20温度读取函数float read_temperature() { // 实现DS18B20的通信协议和温度读取}// 显示温度到LCD/串口void display_temperature(float temperature) { // 调用LCD显示函数或串口打印函数}// 红外遥控信号处理函数void handle_infrared_signal() { // 解析红外信号并执行相应操作}// 使用RTC模块时间信息函数void use_RTC_info() { // 读取时间并记录}

调试与优化

  1. 调试 : 在硬件连接完成后,逐步测试每个模块是否正常工作。首先检查DS18B20能否正常读取温度值,然后检查RTC模块时间是否准确,最后测试红外遥控功能。
  2. 优化 : 根据实际运行情况,调整程序逻辑,优化读取温度的准确度和响应红外遥控的灵敏度。

通过以上步骤,我们可以实现一个具有温度监测、实时时间记录和红外遥控功能的系统。系统可以用于环境监测、工业控制等多个领域。

graph LRA[STM32F103单片机] -->|控制| B[DS18B20传感器]A -->|通信| C[RTC模块(DS1302)]A -->|接收| D[红外遥控模块(HS0038)]B -->|温度值| E[LCD/串口显示]C -->|时间信息| ED -->|遥控信号| A

以上Mermaid流程图展示了整个系统的工作流程。每个模块协同工作,共同完成温度监测系统的功能。在实际应用中,每个模块的编程实现和调试细节将会更加复杂,需要根据具体的硬件情况和需求来调整。

在接下来的章节中,我们将深入探讨如何利用SysTick系统定时器实现定时数据采集和处理功能,进一步增强系统的自动化能力。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:STM32F103是一款高性能的微控制器,适用于各种嵌入式系统设计。本实验课程主要教授如何使用STM32F103与DS18B20数字温度传感器进行通信。DS18B20是一款一线制数字温度传感器,能够直接输出数字信号,具有精度高、使用方便的特点。课程将涵盖从初始化GPIO、软件模拟一线制协议、传感器初始化、温度测量到数据处理的关键步骤。除此之外,还提供RTC、红外遥控和SysTick系统定时器的实验内容,帮助学生全面掌握嵌入式系统设计与传感器应用。

本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif