基于STM32F103C8T6的DS18B20温度检测

具体代码:(参考了up江科大的代码)
ds18b20: GPIOA 4

①ds18b20.c:

#include "stm32f10x.h"
#include "delay.h"
#include "OLED.h"

void DS18B20_Mode_IN(void)//设置GPIO输入模式
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
}

void DS18B20_Mode_OUT(void)//设置GPIO输出模式
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
}

unsigned char DS18B20_Init(void)
{
	Delay_Init();
	
	//从机复位,检测从机给主机返回的脉冲
	unsigned char ACK;
	DS18B20_Mode_IN();//设置输入模式
	
	GPIO_ResetBits(GPIOA,GPIO_Pin_4);//拉低总线(低电平)
	DelayUs(500);
	GPIO_SetBits(GPIOA,GPIO_Pin_4);//释放总线
	DelayUs(70);
	ACK = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);
	DelayUs(500);
	
	return ACK;		
}

void DS18B20_Send_Bit(unsigned char bit)  //(主机:stm32)发送一位到(从机:ds18b20)
{
	Delay_Init();
	DS18B20_Mode_OUT();//设置输出模式

	GPIO_ResetBits(GPIOA,GPIO_Pin_4);//拉低总线(低电平)
	DelayUs(10);
	if(bit)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_4);
		DelayUs(50);
	}
	else
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_4);
		DelayUs(50);
	}
	GPIO_SetBits(GPIOA,GPIO_Pin_4);
}

unsigned char DS18B20_Receive_Bit(void) //(从机:ds18b20)发送一位到(主机:stm32)
{
	Delay_Init();
	unsigned char Bit;
	
	DS18B20_Mode_IN();//设置输入模式
	GPIO_ResetBits(GPIOA,GPIO_Pin_4);//拉低总线(低电平)
	DelayUs(5);
	GPIO_SetBits(GPIOA,GPIO_Pin_4);//从机发0,主机拉高但是总线此时还是0
	DelayUs(5);
	Bit = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);
	DelayUs(50);
	
	return Bit;
}

void DS18B20_Send_Byte(unsigned char Byte)//主机发送一个字节,从机接受
{
	unsigned char i=0;
	for(i=0;i<8;i++)
	{
		DS18B20_Send_Bit(Byte&(0x01<<i)); //依次取出二进制下对应的bit发送   
	}
}

unsigned char DS18B20_Receive_Byte(void)//从机发送一个字节,主机接受
{
	unsigned char Byte =0x00;
	unsigned char i=0;
	for(i=0;i<8;i++)
	{
	
		if(DS18B20_Receive_Bit())
		{
			Byte|=(0x01<<i);
		}
	}
	return Byte;
}

void DS18B20_ConvertTemperature(void)//温度变换
{
	DS18B20_Init();
	DS18B20_Send_Byte(0xCC); //SKIP_ROM
	DS18B20_Send_Byte(0x44); //COVERT_T
}

float DS18B20_ReadTemperature(void)//温度读取
{
	unsigned char TLSB,TMSB;
	int Temp;
	float T;
	DS18B20_Init();
	DS18B20_Send_Byte(0xCC); //SKIP_ROM
	DS18B20_Send_Byte(0xBE); //READ_SCRATCHPAD
	TLSB = DS18B20_Receive_Byte();
	TMSB = DS18B20_Receive_Byte();
//	OLED_ShowBinNum(1,1,TMSB,8);
//	OLED_ShowBinNum(1,9,TLSB,8);
	Temp=(TMSB<<8)|TLSB;
	T = Temp/16.0;
	
	return T;
}

②main.c

#include "stm32f10x.h"
#include "ds18b20.h"
#include "delay.h"
#include "OLED.h"

float T;
int main(void)
{
     OLED_Init();
	 OLED_ShowString(1,1,"Temperature:");
//	 unsigned char ACK;
//	 ACK = DS18B20_Init();
//	 OLED_ShowNum(2,3,ACK,3);  检测从机是否应答
     while(1)
	{
	    DS18B20_ConvertTemperature();
		DelayMs(10);
		T =  DS18B20_ReadTemperature();
		if(T<0)
		{
			OLED_ShowChar(2,1,'-');
			T=-T;
		}
		else
		{
			OLED_ShowChar(2,1,'+');
		}
		OLED_ShowNum(2,2,T,3);
		OLED_ShowChar(2,5,'.');
		OLED_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);
	}

}

附1:
oled代码直接复制up江科大;
delay代码:

//单片机头文件
#include "stm32f10x.h"
//delay头文件
#include "delay.h"

//延时系数
unsigned char UsCount = 0;
unsigned short MsCount = 0;

void Delay_Init(void)
{

	SysTick->CTRL &= ~(1 << 2);		//选择时钟为HCLK(72MHz)/8		103--9MHz
	
	UsCount = 9;					//微秒级延时系数
	
	MsCount = UsCount * 1000;		//毫秒级延时系数

}

void DelayUs(unsigned short us)
{

	unsigned int ctrlResult = 0;
	
	us &= 0x00FFFFFF;											//取低24位
	
	SysTick->LOAD = us * UsCount;								//装载数据
	SysTick->VAL = 0;
	SysTick->CTRL = 1;											//使能倒计数器
	
	do
	{
		ctrlResult = SysTick->CTRL;
	}
	while((ctrlResult & 0x01) && !(ctrlResult & (1 << 16)));	//保证在运行、检查是否倒计数到0
	
	SysTick->CTRL = 0;											//关闭倒计数器
	SysTick->VAL = 0;

}

void DelayXms(unsigned short ms)
{

	unsigned int ctrlResult = 0;
	
	if(ms == 0)
		return;
	
	ms &= 0x00FFFFFF;											//取低24位
	
	SysTick->LOAD = ms * MsCount;								//装载数据
	SysTick->VAL = 0;
	SysTick->CTRL = 1;											//使能倒计数器
	
	do
	{
		ctrlResult = SysTick->CTRL;
	}
	while((ctrlResult & 0x01) && !(ctrlResult & (1 << 16)));	//保证在运行、检查是否倒计数到0
	
	SysTick->CTRL = 0;											//关闭倒计数器
	SysTick->VAL = 0;

}

void DelayMs(unsigned short ms)
{

	unsigned char repeat = 0;
	unsigned short remain = 0;
	
	repeat = ms / 500;
	remain = ms % 500;
	
	while(repeat)
	{
		DelayXms(500);
		repeat--;
	}
	
	if(remain)
		DelayXms(remain);

}

附2:

在这里插入图片描述
附3:
百度网盘分享的文件:stm32-ds…
链接:https://pan.baidu.com/s/12AutmQyw3QnOPi4hMxqWAw 
提取码:a437

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值