STM32的DS18B20驱动

目录

复位脉冲和应答脉冲

初始化

读时序

 写时序

 温度转换

 获取温度

运行结果: 


首先我用的是一块STM32F103VCT6

复位脉冲和应答脉冲

将总线切换为输出模式,主机先拉低电平480us,再拉高15~60us,我直接拉高60us,将总线切换为输入模式,读取ds18b20的应答,设置延时为240us,没超时的话最后切换为输出模式,拉高总线。

uint8_t DS18B20_Rst(void)	   
{        
	uint8_t retry=0;
	DS18B20_IO_OUT();   //设置为输出
	W1DQ_Write(0);  	//拉低DQ
	delay_us(480);      //拉480us
	W1DQ_Write(1);  	//DQ=1 
	delay_us(60);       //60US

	DS18B20_IO_IN();    //设置为输入 
	//等待ds18b20回应
  while (!W1DQ_Read()&&retry<240)
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=200)
		return -1;
	else 
		retry=0;
	
	DS18B20_IO_OUT();
  W1DQ_Write(1);
	delay_us(240);  
	return retry;
}

初始化

//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回-1:不存在
//返回0:存在    	 
uint8_t DS18B20_Init(void)
{
	rv=DS18B20_Rst();
	if(rv<0)
			return -1;
	GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOA_CLK_ENABLE();			//开启GPIOA时钟
	
    GPIO_Initure.Pin=GPIO_PIN_7;           	//PA7
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
    GPIO_Initure.Pull=GPIO_NOPULL;          //不拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);     //初始化

	return rv;
}

读时序

 总线设为输出拉低2us,设为输入,延时13us再开始读ds18b20的回应,读完数据后延时50us再读下一个位。

//从DS18B20读取一个字节
//返回值:读到的数据
uint8_t DS18B20_Read_Byte(void)   
{        
	uint8_t i,dt,date;
	date=0;
	for (i=1;i<=8;i++) 
	{
		DS18B20_IO_OUT();   //设置为输出
		W1DQ_Write(0);
		delay_us(2);
		DS18B20_IO_IN();    //设置为输入
		delay_us(13);
		if(W1DQ_Read())
			dt=1;
		else 
			dt=0;	 
		delay_us(50);    
		//将获得的dt放在最前面,然后再右移一下空出最前面的位置		
    date=(dt<<7)|(date>>1);
   }						    
	return date;
}

 写时序

//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)     
 {             
    uint8_t j;
    uint8_t testb;
    DS18B20_IO_OUT();     //设置为输出
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if(testb)       // 写1
        {
            W1DQ_Write(0);  
            delay_us(2);                            
            W1DQ_Write(1);
            delay_us(60);             
        }
        else            //写0
        {
            W1DQ_Write(0);  
            delay_us(60);             
            W1DQ_Write(1);
            delay_us(2);                          
        }
    }
}

 温度转换

//开始温度转换
static inline int DS18B20_Start(void)
{   						               
    if(0!=DS18B20_Rst())
			return -1;
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0x44);// convert
}

 获取温度

//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
short DS18B20_Get_Temp(void)
{
    uint8_t temp;
    uint8_t LSB,MSB;
    short tem;
    DS18B20_Start ();           //开始转换
    DS18B20_Rst();
//    DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);   // skip rom
    DS18B20_Write_Byte(0xbe);   // convert	    
    LSB=DS18B20_Read_Byte();     // LSB   
    MSB=DS18B20_Read_Byte();     // MSB   
    if(MSB>7)
    {
        MSB=~MSB;
        LSB=~LSB; 
        temp=0;//温度为负  
    }else temp=1;//温度为正	  	  
    tem=MSB; //获得高八位
    tem<<=8;    
    tem+=LSB;//获得底八位
    tem=(double)tem*0.625;//转换 
		
		if(temp)
			return tem; //返回温度值
		else 
			return -tem;    
}

运行结果: 

用手捂住之后温度上升:

 

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值