stm32 使用18B20 测试温度

用18b20 测试温度是非常常用的,不过18B20的调试不是这么容易的,有些内容网上很多的,不再重复说了,我先把波形说一下,再说程序部分:
在这里插入图片描述
整个都温度数据的顺序是:
1.700uS的低电平复位并测试18B20的低电平响应
在这里插入图片描述

2.主机发送0xCC,0x44两个字节,表示跳过地址,只有一个18B20就不需要地址
在这里插入图片描述

3.再次复位
4.发送0xCC,0xBE,两个字节让它转换温度
在这里插入图片描述

5.读取2个字节,这两个字节就是温度了。
在这里插入图片描述

6.这两个字节乘0.625就是温度了。

有一点说明一下,主机输出用GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;用开漏不行。

代码贴一下:

void b12_18b20_in()
{
	GPIO_InitStruct.Pin = GPIO_PIN_12;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void b12_18b20_out()
{
	GPIO_InitStruct.Pin = GPIO_PIN_12;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

管脚自己注意一下

#define DS18B20_DQ_OUT0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
#define DS18B20_DQ_OUT1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)

#define DS18B20_DQ_IN HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12)
void DS18B20_Reset(void)
{
	//设置DS18B20为输出模式
	b12_18b20_out();
	//拉低总线480-960us
	DS18B20_DQ_OUT0;
	delay_us(660);

	//释放总线15-60us
	DS18B20_DQ_OUT1;
	delay_us(15);
}

//等待DS18B20的回应
//返回1:未检测到DS18B20的存在    返回0:存在
uint8_t DS18B20_Check(void)
{
    uint8_t retry = 0;
    b12_18b20_in();					//设置为输入
    while (DS18B20_DQ_IN&&retry<200)
    {
           retry++;
           delay_us(1);
     };
    if(retry>=200)return 1;
    else retry=0;
    while (!DS18B20_DQ_IN&&retry<240)
    {
            retry++;
            delay_us(1);
    };
    if(retry>=240)return 1;
    return 0;
}


//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)
 {
    uint8_t j;
    uint8_t testb;
    b12_18b20_out();					//设置为输出
    for (j=1;j<=8;j++)
    {
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) //输出高
        {
            DS18B20_DQ_OUT0;			//输出低电平
            delay_us(2);                //延时2us
            DS18B20_DQ_OUT1;			//输出高电平
            delay_us(60); 				//延时60us
        }
        else //输出低
        {
            DS18B20_DQ_OUT0;			//输出低电平
            delay_us(60);               //延时60us
            DS18B20_DQ_OUT1;			//输出高电平
            delay_us(2);                //延时2us
        }
    }
}

//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_Read_Bit(void) 			 //读一位
{
    uint8_t data;
    b12_18b20_out();					//设置为输出
    DS18B20_DQ_OUT0; 					//输出低电平
    delay_us(2);
    DS18B20_DQ_OUT1; 					//拉高
    b12_18b20_in();						//设置为输入
    delay_us(12);						//延时12us
    if(DS18B20_DQ_IN)data=1;			//读取总线数据
    else data=0;
    delay_us(50);  						//延时50us
    return data;
}

//从DS18B20读取一个字节
//返回值:读到的数据
uint8_t DS18B20_Read_Byte(void)    		//读一字节
{
    uint8_t i,j,dat;
    dat=0;
    for (i=1;i<=8;i++)
    {
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }
    return dat;
}


void DS18B20_start()
{
	DS18B20_Reset();
	DS18B20_Check();
	DS18B20_Write_Byte(0xCC);
	DS18B20_Write_Byte(0x44);
}


 short Get_temp(void)
 {
	uint8_t temp;
	short tem;
	DS18B20_start();
	DS18B20_Reset();
	DS18B20_Check();
	DS18B20_Write_Byte(0xCC);
	DS18B20_Write_Byte(0xBE);
	uint8_t TL = DS18B20_Read_Byte();
	uint8_t TH = DS18B20_Read_Byte();
	if( TH > 7 )
	{
		temp = 0;		//温度为负
		TH = ~TH;
		TL = ~TL;
	}
	else
	{
		temp = 1; 		//温度为正
	}
	tem = TH;
	tem <<= 8;
	tem += TL;
	//printf("=== %f\r\n", tem);
	tem = tem * 6.25;
	if(temp == 1)
	{
		return tem;
	}
	else
	{
		return ~tem;
	}

 }

输出

	  short temp = Get_temp();
	  uint16_t t = temp ;
	  printf("wendu = %02d.%02d\r\n" , t/100, t%100);

因为浮点数直接打印有点问题,现在这样如果有负问题可能存在问题,自己注意一下。
使用了short。
us延时函数看我的前面一篇文章。

  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,基于stm32使用12个DS18B20进行温度测试的编程步骤如下: 1. 确保您的STM32开发板上已经连接了12个DS18B20传感器,并且每个传感器都已经连接到正确的GPIO引脚上。 2. 在您的工程中导入OneWire库和DS18B20库,其中OneWire库用于实现与DS18B20的通信,DS18B20库用于读取温度数据。 3. 使用OneWire库初始化GPIO引脚,以便与DS18B20传感器进行通信。 4. 在程序中实现读取DS18B20的序列,以便向每个传感器发送读取温度数据的命令。 5. 读取每个传感器的温度数据,并将数据存储在一个数组中。 6. 对于每个温度值,使用DS18B20库中提供的公式将其转换为实际温度值。 7. 将所有温度值打印到串口或其他显示设备上。 下面是一个基于STM32使用12个DS18B20进行温度测试的示例代码: ```c #include "stm32f10x.h" #include "OneWire.h" #include "DS18B20.h" #define NUM_SENSORS 12 #define DELAY_MS 1000 uint8_t sensors[NUM_SENSORS][8] = { {0x28, 0xFF, 0xC0, 0xA7, 0x51, 0x16, 0x03, 0x1E}, {0x28, 0xFF, 0x55, 0x2B, 0x51, 0x16, 0x04, 0x5B}, {0x28, 0xFF, 0xD1, 0x68, 0x51, 0x16, 0x04, 0x72}, {0x28, 0xFF, 0x7D, 0xA1, 0x51, 0x16, 0x04, 0x8E}, {0x28, 0xFF, 0x2B, 0x7A, 0x51, 0x16, 0x04, 0x9A}, {0x28, 0xFF, 0x3D, 0x5F, 0x51, 0x16, 0x04, 0xA7}, {0x28, 0xFF, 0x75, 0x7D, 0x51, 0x16, 0x04, 0xD0}, {0x28, 0xFF, 0x8D, 0x74, 0x51, 0x16, 0x04, 0x7B}, {0x28, 0xFF, 0x8F, 0x7A, 0x51, 0x16, 0x04, 0x56}, {0x28, 0xFF, 0x95, 0x5B, 0x51, 0x16, 0x04, 0x8D}, {0x28, 0xFF, 0x9B, 0x76, 0x51, 0x16, 0x04, 0x57}, {0x28, 0xFF, 0xBD, 0x6D, 0x51, 0x16, 0x04, 0x59} }; GPIO_InitTypeDef GPIO_InitStructure; void init_gpio(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); } void delay_ms(uint32_t ms){ uint32_t i; for(i = 0; i < ms; i++){ volatile uint32_t j = 1000; while(j--); } } int main(void){ uint8_t i; float temps[NUM_SENSORS]; init_gpio(); OneWire_Init(GPIOB, GPIO_Pin_3); while(1){ for(i = 0; i < NUM_SENSORS; i++){ DS18B20_Start(&OneWire_GPIO, sensors[i]); delay_ms(DELAY_MS); temps[i] = DS18B20_ReadTemperature(&OneWire_GPIO, sensors[i]); } for(i = 0; i < NUM_SENSORS; i++){ printf("Sensor %d: %.2fC\n", i, temps[i]); } delay_ms(DELAY_MS); } } ``` 在这个示例代码中,我们首先定义了12个DS18B20传感器的地址,然后在初始化函数中初始化了GPIO引脚,并初始化了OneWire库。在主函数中,我们使用一个循环来读取每个传感器的温度值,并将其存储在一个数组中。最后,我们将所有的温度值打印到串口中,然后等待一段时间后重复此过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值