STM32单片机驱动DS18B20

为了方便移值,把ds18b20驱动用ds18b20.c 和ds18b20.h封装起来
ds18b20.c代码如下

#include "ds18b20.h"

unsigned char wendubuf1[2];//wendubuf[0]存扩大10倍的温度高8位   wendubuf[0]存扩大10倍的温度低8位   比如326 为32.6

void DS18B20Init(void)
{
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(DS_GPIO_CLK, ENABLE);	 //使能时钟 
	
 	GPIO_InitStructure.GPIO_Pin = DS_GPIO_PIN;				
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		  
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(DS_GPIO_PORT, &GPIO_InitStructure);
	

 	DS_OUT=1;    //输出1


} 





/* 复位总线,获取存在脉冲,以启动一次读写操作 */
unsigned char Get18B20Ack(void)
{
    u8 retry=0;
    
    DS18B20_IO_OUT(); //SET PA0 OUTPUT
    DS_OUT = 0;     //产生500us复位脉冲
    delay_us(750);
    DS_OUT = 1;
    delay_us(15);    //延时15us
		DS18B20_IO_IN();//SET PA0 INPUT	
    while (DS_IN&&retry<200)
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=200)return 1;
	else retry=0;
    while (!DS_IN&&retry<240)
	{
		retry++;
		delay_us(1);
	};
	if(retry>=240)return 1;	    
	return 0;
}

//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void) 			 // read one bit
{
  u8 data;
	DS18B20_IO_OUT();//SET OUTPUT
  DS_OUT=0; 
	delay_us(2);
  DS_OUT=1; 
	DS18B20_IO_IN();//SET INPUT
	delay_us(12);
	if(DS_IN)data=1;
  else data=0;	 
  delay_us(50);           
  return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据

//写一个字节到DS18B20
//dat:要写入的字节


/* 向DS18B20写入一个字节,dat-待写入字节 */
void Write18B20(unsigned char dat)
{
    u8 j;
    u8 testb;
	DS18B20_IO_OUT();//SET  OUTPUT;



    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) 
        {
            DS_OUT=0;// Write 1
            delay_us(2);                            
            DS_OUT=1;
            delay_us(60);             
        }
        else 
        {
            DS_OUT=0;// Write 0
            delay_us(60);             
            DS_OUT=1;
            delay_us(2);                          
        }
    }
}


/* 从DS18B20读取一个字节,返回值-读到的字节 */
unsigned char Read18B20(void)
{
    u8 i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }						    
    return dat;
}


/* 启动一次18B20温度转换,返回值-表示是否启动成功 */
void Start18B20()
{
    unsigned char ack=1;
    
    ack = Get18B20Ack();   //执行总线复位,并获取18B20应答
    if (ack == 0)          //如18B20正确应答,则启动一次转换
    {
       Write18B20(0xCC);  //跳过ROM操作
       Write18B20(0x44);  //启动一次温度转换
    }
    
}


/* 读取DS18B20转换的温度值,返回值-表示是否读取成功 */
unsigned char Get18B20Temp(int *temp)
{
    unsigned char ack=1;
    unsigned char LSB, MSB; //16bit温度值的低字节和高字节
    
    ack = Get18B20Ack();    //执行总线复位,并获取18B20应答
    if (ack == 0)           //如18B20正确应答,则读取温度值
    {
        Write18B20(0xCC);   //跳过ROM操作
        Write18B20(0xBE);   //发送读命令
        LSB = Read18B20();  //读温度值的低字节
       
        MSB = Read18B20();  //读温度值的高字节
				
        *temp = ((int)MSB << 8) + LSB;  //合成为16bit整型数
    }
    return ack;  //ack==0表示操作应答,所以返回值为其取反值
}




void Get_Temp()//获取温度
{
	unsigned char res=1;
	int temp;        //读取到的当前温度值
	int intT, decT;  //温度值的整数和小数部分
	//unsigned char wenduzs,wenduxs;//整数  小数

	res = Get18B20Temp(&temp);  //读取当前温度

	if (res==0)                    //读取成功时,刷新当前温度显示
	{
		if(temp<0)//把负数变正数
		{
			temp=~(temp-1);//把负数变为正数
			intT = temp >> 4;             //右移后16进制转换为十进制值刚好等于温度整数值,分离出温度值整数部分0.0625
			
		}
		else
		{
			intT = temp >> 4;             //右移后16进制转换为十进制值刚好等于温度整数值,分离出温度值整数部分0.0625
		}
		decT = temp & 0x000F;            //分离出温度值小数部分
        decT = (decT*10) / 16;        //1/16=0.0625,除以16等于乘以0.0625,乘以10就保留了1位小数了。二进制的小数部分转换为1位十进制位
		//wenduzs=(unsigned char)intT;//整除
		//wenduxs=(unsigned char)decT;//小数
		//wendubuf[0]=wenduzs;//把整数存入暂存数组0
		//wendubuf[1]=wenduxs;//把小数存入暂存数组1  注意  小数是*10后的值
		wendubuf1[0]=(intT*10+decT)>>8;//高8位
		wendubuf1[1]=(unsigned char)(intT*10+decT);//低8位
  }

  Start18B20();               //重新启动下一次转换

}


ds18b20.h代码如下

#ifndef _DS18B20_H
#define _DS18B20_H
#include "config.h"



//IO方向设置
#define DS18B20_IO_IN()  {GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=8<<0;}
#define DS18B20_IO_OUT() {GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=3<<0;}


#define DS_GPIO_PIN                         GPIO_Pin_8                
#define DS_GPIO_PORT                   GPIOB                    
#define DS_GPIO_CLK                    RCC_APB2Periph_GPIOB

#define DS_IN   PBin(8)
#define DS_OUT  PBout(8)

extern unsigned char wendubuf1[2];//wendubuf[0]存扩大10倍的温度高8位   wendubuf[1]存扩大10倍的温度低8位   比如326 为32.6




void Start18B20(void);// 启动一次18B20温度转换,返回值-表示是否启动成功 */  初始化值调用1次
void Get_Temp(void);//温度处理函数,包括把温度值存入数组    获取温度值调用
void DS18B20Init(void);//温度传感器

#endif



  • 0
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白q_5793545

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值