利用stm32f103c8t6配合JMSBWZ-2460测量温度,显示到LED上
时间: 2025-05-20 16:20:23 AIGC 浏览: 29
### STM32F103C8T6 配合 JMSBWZ-2460 测量温度并显示在 LED 上的方法
为了实现通过 STM32F103C8T6 和 JMSBWZ-2460 传感器测量温度并将结果显示在 LED 上的功能,需要完成以下几个部分的设计:
#### 1. **硬件连接**
JMSBWZ-2460 是一种基于 DS18B20 的单总线数字温度传感器。其典型接法如下:
- VCC 连接到 STM32 的 3.3V 或 5V。
- GND 接到地。
- DQ 数据引脚连接到 STM32 的 GPIO 口,并通过一个约 4.7kΩ 的上拉电阻连接到电源。
LED 显示可以通过简单的 GPIO 输出控制来点亮或熄灭。
---
#### 2. **软件设计**
以下是完整的代码示例,展示如何初始化 DS18B20 温度传感器、读取温度值以及根据温度变化控制 LED 的亮灭。
```c
#include "stm32f10x.h"
#define ONE_WIRE_PIN GPIO_Pin_0 // 定义DS18B20数据引脚为PA0
#define LED_PIN GPIO_Pin_1 // 定义LED引脚为PA1
// 延时函数
void delay_us(uint32_t us) {
while (us--) {
__asm("nop");
}
}
// 初始化GPIO
void GPIO_Config(void) {
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 启用GPIOA时钟
// 配置DS18B20数据引脚
GPIO_InitStruct.GPIO_Pin = ONE_WIRE_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD; // 开漏输出模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置LED引脚
GPIO_InitStruct.GPIO_Pin = LED_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
// 单总线写入一位
void OneWire_WriteBit(uint8_t bit) {
if (bit) { // 写'1'
GPIO_SetBits(GPIOA, ONE_WIRE_PIN);
} else { // 写'0'
GPIO_ResetBits(GPIOA, ONE_WIRE_PIN);
delay_us(60);
GPIO_SetBits(GPIOA, ONE_WIRE_PIN);
}
delay_us(10);
}
// 单总线读取一位
uint8_t OneWire_ReadBit(void) {
uint8_t bit;
GPIO_SetBits(GPIOA, ONE_WIRE_PIN);
GPIO_ResetBits(GPIOA, ONE_WIRE_PIN);
delay_us(2);
GPIO_SetBits(GPIOA, ONE_WIRE_PIN);
delay_us(12);
if (GPIO_ReadInputDataBit(GPIOA, ONE_WIRE_PIN)) {
bit = 1;
} else {
bit = 0;
}
delay_us(60);
return bit;
}
// 发送复位脉冲
uint8_t OneWire_Reset(void) {
uint8_t presence_pulse = 0;
GPIO_ResetBits(GPIOA, ONE_WIRE_PIN);
delay_us(480);
GPIO_SetBits(GPIOA, ONE_WIRE_PIN);
delay_us(70);
if (!GPIO_ReadInputDataBit(GPIOA, ONE_WIRE_PIN)) {
presence_pulse = 1;
}
delay_us(400);
return presence_pulse;
}
// 写一字节
void OneWire_WriteByte(uint8_t byte) {
uint8_t i;
for (i = 0; i < 8; i++) {
OneWire_WriteBit(byte & 0x01);
byte >>= 1;
}
}
// 读一字节
uint8_t OneWire_ReadByte(void) {
uint8_t i, byte = 0;
for (i = 0; i < 8; i++) {
byte >>= 1;
if (OneWire_ReadBit()) {
byte |= 0x80;
}
}
return byte;
}
// 转换温度
float ConvertTemperature(uint8_t lsb, uint8_t msb) {
int16_t temp_raw = ((msb << 8) | lsb);
float temperature_celsius = (temp_raw * 0.0625); // 计算实际温度[^2]
return temperature_celsius;
}
int main(void) {
float temperature;
uint8_t data[9];
GPIO_Config(); // 初始化GPIO
while (1) {
if (OneWire_Reset()) { // 复位通信
OneWire_WriteByte(0xCC); // 跳过ROM命令
OneWire_WriteByte(0x44); // 转换温度命令
delay_us(750); // 等待转换完成
if (OneWire_Reset()) { // 再次复位
OneWire_WriteByte(0xCC); // 跳过ROM命令
OneWire_WriteByte(0xBE); // 读取刮板寄存器
for (int i = 0; i < 9; i++) {
data[i] = OneWire_ReadByte();
}
temperature = ConvertTemperature(data[0], data[1]); // 获取温度
if (temperature > 25.0) { // 如果温度高于25℃,点亮LED
GPIO_SetBits(GPIOA, LED_PIN);
} else { // 否则关闭LED
GPIO_ResetBits(GPIOA, LED_PIN);
}
}
}
delay_us(100000); // 延时一段时间再检测
}
}
```
---
#### 3. **功能说明**
上述代码实现了以下功能:
- 使用 PA0 引脚作为 DS18B20 的数据接口。
- 实现了单总线协议的低层操作(如发送复位脉冲、写/读字节等)。
- 将读取到的温度值存储在一个数组中,并调用 `ConvertTemperature` 函数将其转化为摄氏温度。
- 当温度超过设定阈值(此处设为 25°C),点亮 LED;否则熄灭 LED。
---
#### 4. **注意事项**
- 在使用前需确认 DS18B20 是否已正确配置为匹配模式。
- 若有多个 DS18B20 设备,则需要额外处理 ROM 地址匹配逻辑。
- 系统延时应适当调整以适应具体应用场景的需求。
---
相关问题
阅读全文
相关推荐
















