我现在手上有四个ds18b20,我现在需要用stm32f1的标准库函数来写一个代码,要求每个能够区分每个ds18b20的温度,并且在lcd上面显示出来
时间: 2024-02-12 17:02:42 浏览: 72
DS18B20数字温度传感器在STM32上实现代码.rar_DS18B20 stm32_herdb2p_stm32 18b20
好的,那么我们可以在上面的代码基础上进行修改,实现对四个DS18B20传感器的温度读取和显示。
首先,我们需要对每个DS18B20传感器进行编号,可以使用ROM码来实现。每个DS18B20传感器都有一个唯一的64位ROM码,其中前8位是家族码,接下来的48位是序列号,最后8位是CRC校验码。我们可以使用序列号部分作为每个传感器的编号。在读取温度值时,需要先发送“匹配ROM”命令,将总线上的设备地址指向指定的传感器,然后才能读取该传感器的温度值。
下面是一个示例代码,可以读取四个DS18B20传感器的温度值,并将温度值显示在LCD上:
```c
#include <stm32f10x.h>
#include <stdio.h>
#include "lcd.h"
#define DS18B20_PORT GPIOA
#define DS18B20_PIN_1 GPIO_Pin_0
#define DS18B20_PIN_2 GPIO_Pin_1
#define DS18B20_PIN_3 GPIO_Pin_2
#define DS18B20_PIN_4 GPIO_Pin_3
#define DS18B20_NUM 4
#define DS18B20_ROM_1 {0x28, 0xFF, 0x82, 0x1B, 0x77, 0x16, 0x04, 0x3E}
#define DS18B20_ROM_2 {0x28, 0xFF, 0x8E, 0x1B, 0x77, 0x16, 0x04, 0x5C}
#define DS18B20_ROM_3 {0x28, 0xFF, 0xC2, 0x1B, 0x77, 0x16, 0x04, 0x69}
#define DS18B20_ROM_4 {0x28, 0xFF, 0x06, 0x1C, 0x77, 0x16, 0x04, 0x3B}
uint8_t ds18b20_rom[][8] = {DS18B20_ROM_1, DS18B20_ROM_2, DS18B20_ROM_3, DS18B20_ROM_4};
// 初始化1-Wire总线
void ds18b20_init(uint16_t pin)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
GPIO_SetBits(DS18B20_PORT, pin);
delay_us(500);
}
// 发送1-Wire总线复位信号
void ds18b20_reset(uint16_t pin)
{
GPIO_ResetBits(DS18B20_PORT, pin);
delay_us(480);
GPIO_SetBits(DS18B20_PORT, pin);
delay_us(70);
}
// 发送1-Wire总线写入位
void ds18b20_write_bit(uint16_t pin, uint8_t bit)
{
GPIO_ResetBits(DS18B20_PORT, pin);
delay_us(2);
if (bit)
{
GPIO_SetBits(DS18B20_PORT, pin);
}
delay_us(60);
GPIO_SetBits(DS18B20_PORT, pin);
delay_us(2);
}
// 发送1-Wire总线写入字节
void ds18b20_write_byte(uint16_t pin, uint8_t byte)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
ds18b20_write_bit(pin, byte & 0x01);
byte >>= 1;
}
}
// 发送1-Wire总线读取位
uint8_t ds18b20_read_bit(uint16_t pin)
{
uint8_t bit;
GPIO_ResetBits(DS18B20_PORT, pin);
delay_us(2);
GPIO_SetBits(DS18B20_PORT, pin);
delay_us(8);
bit = GPIO_ReadInputDataBit(DS18B20_PORT, pin);
delay_us(50);
return bit;
}
// 发送1-Wire总线读取字节
uint8_t ds18b20_read_byte(uint16_t pin)
{
uint8_t i, byte = 0;
for (i = 0; i < 8; i++)
{
byte |= ds18b20_read_bit(pin) << i;
}
return byte;
}
// 发送1-Wire总线匹配ROM命令
void ds18b20_match_rom(uint8_t *rom)
{
uint8_t i;
ds18b20_write_byte(DS18B20_PIN_1, 0x55); // 匹配ROM命令
for (i = 0; i < 8; i++)
{
ds18b20_write_byte(DS18B20_PIN_1, rom[i]); // 发送ROM码
}
}
// 读取DS18B20温度值
float ds18b20_read_temperature(uint8_t *rom)
{
uint8_t i;
uint8_t scratchpad[9];
float temperature;
ds18b20_reset(DS18B20_PIN_1);
ds18b20_match_rom(rom); // 匹配ROM
ds18b20_write_byte(DS18B20_PIN_1, 0x44); // 启动温度转换
delay_us(750); // 最大转换时间为750ms
ds18b20_reset(DS18B20_PIN_1);
ds18b20_match_rom(rom); // 匹配ROM
ds18b20_write_byte(DS18B20_PIN_1, 0xBE); // 读取温度数据
for (i = 0; i < 9; i++) // 读取9个字节的温度数据
{
scratchpad[i] = ds18b20_read_byte(DS18B20_PIN_1);
}
temperature = (scratchpad[1] << 8) | scratchpad[0]; // 读取温度值
temperature /= 16.0;
return temperature;
}
int main(void)
{
float temperature[DS18B20_NUM];
char buf[16];
uint8_t i;
ds18b20_init(DS18B20_PIN_1);
ds18b20_init(DS18B20_PIN_2);
ds18b20_init(DS18B20_PIN_3);
ds18b20_init(DS18B20_PIN_4);
lcd_init(); // 初始化LCD
while (1)
{
for (i = 0; i < DS18B20_NUM; i++)
{
temperature[i] = ds18b20_read_temperature(ds18b20_rom[i]); // 读取温度值
}
lcd_clear(); // 清屏
for (i = 0; i < DS18B20_NUM; i++)
{
sprintf(buf, "DS18B20 %d: %.2fC", i+1, temperature[i]); // 格式化字符串
lcd_puts(buf, 0, i*16); // 显示字符串
}
delay_ms(1000); // 等待1s后再次读取温度值
}
}
```
在上面的代码中,`ds18b20_init()`函数初始化了1-Wire总线,并将数据线设置为输出高电平。`ds18b20_reset()`函数发送了1-Wire总线复位信号。`ds18b20_write_bit()`函数实现了1-Wire总线写入位的操作。`ds18b20_write_byte()`函数实现了1-Wire总线写入字节的操作。`ds18b20_read_bit()`函数实现了1-Wire总线读取位的操作。`ds18b20_read_byte()`函数实现了1-Wire总线读取字节的操作。`ds18b20_match_rom()`函数实现了发送“匹配ROM”命令的操作。`ds18b20_read_temperature()`函数实现了读取DS18B20温度值的操作。
在`main()`函数中,我们初始化了四个DS18B20传感器的GPIO口,并定义了每个传感器的ROM码。然后在一个无限循环中,不断读取每个传感器的温度值,并将温度值显示在LCD上。`lcd_puts()`函数用于将字符串显示在LCD上。
需要注意的是,本代码中使用了LCD显示模块,请根据实际情况进行修改。同时需要根据实际硬件接口修改GPIO口的引脚号和ROM码。
阅读全文