rt-thread DS18B02 温度采集程序

该代码示例展示了如何在STM32微控制器上,基于RT-Thread实时操作系统,通过DS18B20传感器进行温度采集。代码包括复位、检查传感器响应、写入和读取字节的函数,以及启动温度转换和获取温度值的函数。此外,还创建了一个线程来周期性读取温度,并根据温度值控制LED的状态。
摘要由CSDN通过智能技术生成

下述代码为stm32在rt-thread平台下通过DS18B20采集温度的代码,温度较之实际温度扩大了10倍


static  rt_thread_t ds18b20_tid=NULL;


///* 引脚编号,通过查看设备驱动文件drv_gpio.c确定 */
#define DS18B20_DQ      2  /* PA11 */


//复位DS18B20
void DS18B20_Rst(void)	   
{       
    rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT);// 引脚为输出模式
    rt_pin_write(DS18B20_DQ, PIN_LOW);       //拉低DQ
    rt_hw_us_delay(750);                     //拉低750us(480 ~ 960us)
    rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //设置为输入,即可释放总线的占用
    //进入接收模式,等待应答信号。
}

//等待DS18B20的回应
//返回1:未检测到DS18B20的存在    返回0:存在
//等待了30us,  从机回应为108us,正常。

uint8_t DS18B20_Check(void) 	   
{   
    uint8_t retry=0;
	//------------------等待时间----------------------------------
	rt_hw_us_delay(15);   						 //15 ~60us 等待
    while (rt_pin_read(DS18B20_DQ)&&retry<100)  //最多还等待100us
    {
           retry++;
           rt_hw_us_delay(1);
     };	 
    if(retry>=100)  return 1;                 //100us未响应,则判断未检测到
    else retry=0;
	 
	 //----------------------从机拉低时间开始----------------------
     
    while (!rt_pin_read(DS18B20_DQ)&&retry<240)  
    {
            retry++;
            rt_hw_us_delay(1);
    };
    if(retry>=240)  return 1;	 //最长拉低240us    
    return 0;
}

//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)     
 {             
    uint8_t j;  
    uint8_t testb;
    rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT); // DQ引脚为输出模式
//     dat = 0xaa;
    for (j=1;j<=8;j++) 
    {
        testb=dat&0x01;  
        dat=dat>>1;
        if (testb) //输出高
        {
            rt_pin_write(DS18B20_DQ, PIN_LOW);       //拉低DQ,主机输出低电平
            rt_hw_us_delay(2);                       //延时2us
			rt_pin_write(DS18B20_DQ, PIN_HIGH);       //主机输出高电平
            rt_hw_us_delay(60);                      //延时60us            
        }
        else       //输出低
        {
            rt_pin_write(DS18B20_DQ, PIN_LOW);       //拉低DQ,主机输出低电平
            rt_hw_us_delay(60);                      //延时60us

			rt_pin_write(DS18B20_DQ, PIN_HIGH);       //主机输出高电平
            rt_hw_us_delay(2);                        //延时2us        
        }  
    }
	rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT);         //设置为输入,释放总线
}
 
//从DS18B20读取一个位
//返回值:1/0
uint8_t  DS18B20_Read_Bit(void) 			 // read one bit
{
    uint8_t data;
    rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT); // DQ引脚为输出模式
    rt_pin_write(DS18B20_DQ, PIN_LOW);       //拉低DQ,主机输出低电平
    rt_hw_us_delay(2);                       //延时2us
    rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //设置为输入,释放总线
    rt_hw_us_delay(1);//延时1us
    
    if(rt_pin_read(DS18B20_DQ))
        data=1;//读取总线数据
    else 
        data=0;	 
    rt_hw_us_delay(60);  //延时60us(读一位至少60us)         
    return data;
}

//从DS18B20读取一个字节
//返回值:读到的数据
uint8_t DS18B20_Read_Byte(void)    // read one byte
{        
    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(void)// ds1820 start convert
{   					               
    DS18B20_Rst();	
	DS18B20_Check();
    DS18B20_Write_Byte(0xcc); // skip rom
    DS18B20_Write_Byte(0x44); // convert	
} 



//从ds18b20得到温度值
//精度:0.5度
//返回值:温度值 (-550~1250) 
int16_t DS18B20_Get_Temp(void)
{
    uint8_t temp;         //用来判断符号
    uint8_t TL,TH;
    uint16_t tem;
	rt_base_t level;
	
	level = rt_hw_interrupt_disable();    //API:进入临界区,退出前系统不会发生任务调度
    DS18B20_Start ();     // ds1820 start convert
	rt_hw_interrupt_enable(level);    //API:退出临界区
	
	rt_thread_mdelay(800);  //等待转换完成
	
	level = rt_hw_interrupt_disable();    //API:进入临界区,退出前系统不会发生任务调度
    DS18B20_Rst();        //复位
    DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);   // skip rom
    DS18B20_Write_Byte(0xbe);   // 读取命令	    
    TL=DS18B20_Read_Byte(); 
    TH=DS18B20_Read_Byte();  
  rt_hw_interrupt_enable(level);    //API:退出临界区
    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;  
  rt_kprintf("temp:%d\n",tem); 

} 


void ds18b20_tid_entry(void *parameter)
{
    int16_t dat;
    float dat1;
    while(1)
    {
       rt_thread_mdelay(1000); //1s读取一次     
 
	  dat =  DS18B20_Get_Temp(); 
	  dat1=dat*0.1;
	
    LOG_I("temp : %d\n",dat);//读取温度数据并发送到串口。
	 if(dat>270)
	 {	 
	  rt_thread_mdelay(1000);

	  LOG_I("aaaa");
	  rt_pin_write(LED_458_PIN , PIN_HIGH);
	 
	 }else
	 {
   rt_pin_write(LED_458_PIN , PIN_LOW);
	 
	 }
//	 
//     if(dat>50)
//	 {
//	 	rt_thread_mdelay(1000);
//	  rt_pin_write(LED_458_PIN , PIN_LOW);
//	 LOG_I("BBBB");
	 rt_pin_write(LED_458_PIN , PIN_HIGH);
//	 
//	 }		
    }
     
}
void ds18b20_init(void)
{
    /* 创建线程1,红色LED闪烁线程*/
    ds18b20_tid = rt_thread_create("ds18b20_thread",	 //线程名字
                            ds18b20_tid_entry,	 //线程入口函数  
							RT_NULL,		     //线程入口参数
                            THREAD_STACK_SIZE,	 //堆栈大小,
                            THREAD_PRIORITY, 	 //线程优先级
							THREAD_TIMESLICE);	 //时间片长度
    
    /* 如果获得线程控制块,启动这个线程 */
   /* 如果获得线程控制块,启动这个线程 */
	

//    if (ds18b20_tid != RT_NULL)
//        rt_thread_startup(ds18b20_tid);     
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值