stm32f103zet6 ds18b20

main.c

c 复制代码
// main.c
#include "sys.h"
#include "ds18b20.h"
 int main(void)
 {	
	uart_init(9600);
	delay_init();
	while(DS18B20_Init())	//DS18B20初始化	
	{
		printf("error");
		delay_ms(200);

	}
   	while(1){
		printf("%4.2f\r\n",Get_Temp());
	}
 }

ds18b20.h

c 复制代码
// ds18b20.h
#ifndef __DS18B20_H
#define __DS18B20_H 
#include "sys.h"   
//DS18B20引脚宏定义						
#define DS18B20_GPIO_PORT		GPIOB
#define DS18B20_GPIO_PIN		GPIO_Pin_12
#define DS18B20_GPIO_CLK   	RCC_APB2Periph_GPIOB
//输出状态定义
#define OUT 1
#define IN  0
//控制DS18B20引脚输出高低电平
#define DS18B20_Low  GPIO_ResetBits(DS18B20_GPIO_PORT,DS18B20_GPIO_PIN)
#define DS18B20_High GPIO_SetBits(DS18B20_GPIO_PORT,DS18B20_GPIO_PIN)		
u8 DS18B20_Init(void);//初始化DS18B20
short DS18B20_Get_Temp(void);//获取温度
void DS18B20_Start(void);//开始温度转换
void DS18B20_Write_Byte(u8 dat);//写入一个字节
u8 DS18B20_Read_Byte(void);//读出一个字节
u8 DS18B20_Read_Bit(void);//读出一个位
void DS18B20_Mode(u8 mode);//DS18B20引脚输出模式控制
u8 DS18B20_Check(void);//检测是否存在DS18B20
void DS18B20_Rst(void);//复位DS18B20   
float Get_Temp(void);
#endif

ds18b20.c

c 复制代码
// ds18b20.c
#include "ds18b20.h"
#include "delay.h"			
void DS18B20_Rst(void)	   
{                 
	DS18B20_Mode(OUT); 	//SET OUTPUT
    DS18B20_Low; 				//拉低DQ
    delay_us(750);    	//拉低750us
    DS18B20_High; 			//DQ=1 
	delay_us(15);     	//15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
/*
复位脉冲执行完之后,总线已经被拉高了;
此时,从机需要给总线拉高;
因此,逻辑是:
	主机切换为输入模式
	判断总线是否仍为高点平,如果超过200us,表示从机没反应,初始化失败;
	如果200us内,总线被从机拉低了,则开始计时拉低的时间,<240us初始化成功,超时则失败
*/
u8 DS18B20_Check(void) 	   
{   
	u8 retry=0;
	DS18B20_Mode(IN);	//SET  INPUT	 
    while (GPIO_ReadInputDataBit(DS18B20_GPIO_PORT,DS18B20_GPIO_PIN)&&retry<200)
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=200)return 1;
	else retry=0;
    while (!GPIO_ReadInputDataBit(DS18B20_GPIO_PORT,DS18B20_GPIO_PIN)&&retry<240)
	{
		retry++;
		delay_us(1);
	};
	if(retry>=240)return 1;	    
	return 0;
}
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void) 	 
{
    u8 data;
	DS18B20_Mode(OUT);	//SET OUTPUT
    DS18B20_Low; 
	delay_us(2);
    DS18B20_High; 
	DS18B20_Mode(IN);	//SET INPUT
	delay_us(12);
	if(GPIO_ReadInputDataBit(DS18B20_GPIO_PORT,DS18B20_GPIO_PIN))data=1;
    else data=0;	 
    delay_us(50);           
    return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)     
{        
    u8 i,j,dat;
    dat=0;
	for (i=1;i<=8;i++){
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }						    
    return dat;
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 ByteData)     
 {             
    u8 j;
    u8 LastBit;
	DS18B20_Mode(OUT);	//SET OUTPUT;
    for (j = 1;j <= 8;j++){
		//取最后一位 
        LastBit = ByteData&0x01;
        ByteData = ByteData >> 1;
        if (LastBit) {
            DS18B20_Low;	// Write 1
            delay_us(2);                            
            DS18B20_High;
            delay_us(60);             
        }else{
            DS18B20_Low;	// Write 0
            delay_us(60);             
            DS18B20_High;
            delay_us(2);                          
        }
    }
}
//开始温度转换
void DS18B20_Start(void) {   						               
    DS18B20_Rst();	   
	DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);	// skip rom
    DS18B20_Write_Byte(0x44);	// convert
} 

//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
u8 DS18B20_Init(void)
{
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	RCC_APB2PeriphClockCmd(DS18B20_GPIO_CLK, ENABLE);	 //使能PORTA口时钟 
 	GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_PIN;				//PORTA.6 推挽输出
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		  
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure);
 	GPIO_SetBits(DS18B20_GPIO_PORT,DS18B20_GPIO_PIN);    //输出
	DS18B20_Rst();
	return DS18B20_Check();
}  
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
short DS18B20_Get_Temp(void)
{
    u8 temp;
    u8 TL,TH;
	short tem;
    DS18B20_Start ();  			// ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);	// skip rom
    DS18B20_Write_Byte(0xbe);	// convert	    
    TL=DS18B20_Read_Byte(); 	// LSB   
    TH=DS18B20_Read_Byte(); 	// MSB  
	    	  
    if(TH>7){
        TH=~TH;
        TL=~TL; 
        temp=0;					//温度为负  
    }else temp=1;				//温度为正	  	  
    tem=TH; 					//获得高八位
    tem<<=8;    
    tem+=TL;					//获得底八位
    tem=(float)tem*0.625;		//转换     
	if(temp)return tem; 		//返回温度值
	else return -tem;    
}

void DS18B20_Mode(u8 mode)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(DS18B20_GPIO_CLK, ENABLE);	 //使能PORTA口时钟
	if(mode){
		GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_PIN;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	}else{
		GPIO_InitStructure.GPIO_Pin =  DS18B20_GPIO_PIN;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	}
	GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure);
}
float Get_Temp(void){
	short temperature = 0;
	temperature = DS18B20_Get_Temp();	//读取温度
	float temp = (float)temperature/10;
	return  temp;
}

 
相关推荐
酷飞飞1 天前
RTC和看门狗基于GD32F407VE的天空星的配置
stm32·单片机·嵌入式硬件·mcu
qq_401700411 天前
STM32的HardFault错误处理技巧
stm32
WD137298015571 天前
WD5030A,24V降5V,15A 大电流,应用于手机、平板、笔记本充电器
stm32·单片机·嵌入式硬件·智能手机·汽车·电脑·51单片机
日更嵌入式的打工仔1 天前
GPIO 中断通用配置指南
stm32·单片机·嵌入式硬件
平凡灵感码头1 天前
基于 STM32 的智能门锁系统,系统界面设计
stm32·单片机·嵌入式硬件
Truffle7电子1 天前
STM32理论 —— 存储、中断
stm32·嵌入式硬件·嵌入式·存储·中断
报错小能手1 天前
linux学习笔记(32)网络编程——UDP
单片机·嵌入式硬件
XiangrongZ1 天前
江协科技STM32课程笔记(四)—定时器TIM(输入捕获)
笔记·科技·stm32
xyx-3v1 天前
SPI四种工作模式
stm32·单片机·嵌入式硬件·学习
qiuiuiu4131 天前
正点原子RK3568学习日志6-驱动模块传参
linux·c语言·开发语言·单片机·学习