关于#单片机#的问题:ds18b20温度显示数据有误

代码是根据小蜜蜂老 师的蓝桥杯强化训练ds18b20板块写的,我输入的温度数据是230也就是23.0但是烧录出来的数据是53.5,求问哪里有出错 😭

img

img

img

img

确定下你的数码管是共阴还是共阳,计算下编码是否正确!

各个节点用调试断点查看一下变量值是否正确,或者用串口输出,
比如最关键的,从DS18B20读出的温度数值,看是读错了还是显示错了。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7549366
  • 这篇博客你也可以参考下:51单片机DS18B20与中断冲突解决方式
  • 除此之外, 这篇博客: 单片机的ds18b20程序中的 ds18b20对时序要求很高,所以一定要注意延时 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    下面是32单片机的程序

    //复位DS18B20
    void DS18B20_Rst(void)	   
    {                 
    	DS18B20_IO_OUT(); 	//SET PG11 OUTPUT
        DS18B20_DQ_OUT=0; 	//拉低DQ
        delay_us(750);    	//延时750us
        DS18B20_DQ_OUT=1; 	//DQ=1 
    	delay_us(15);     	//15US
    }
    
    //等待DS18B20的回应
    //返回1:未检测到DS18B20的存在
    //返回0:存在
    u8 DS18B20_Check(void) 	   
    {   
    	u8 retry=0;
    	DS18B20_IO_IN();	//SET PG11 INPUT	 
        while (DS18B20_DQ_IN&&retry<200)
    	{
    		retry++;
    		delay_us(1);
    	};	 
    	if(retry>=200)return 1;
    	else retry=0;
        while (!DS18B20_DQ_IN&&retry<240)
    	{
    		retry++;
    		delay_us(1);
    	};
    	if(retry>=240)return 1;	    
    	return 0;
    }
    
    //从DS18B20读取一位
    //返回1/0
    u8 DS18B20_Read_Bit(void) 	 
    {
        u8 data;
    	DS18B20_IO_OUT();	//SET PG11 OUTPUT
        DS18B20_DQ_OUT=0; 
    	delay_us(2);
        DS18B20_DQ_OUT=1; 
    	DS18B20_IO_IN();	//SET PG11 INPUT
    	delay_us(12);
    	if(DS18B20_DQ_IN)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
    void DS18B20_Write_Byte(u8 dat)     
     {             
        u8 j;
        u8 testb;
    	DS18B20_IO_OUT();	//SET PG11 OUTPUT;
        for (j=1;j<=8;j++) 
    	{
            testb=dat&0x01;
            dat=dat>>1;
            if (testb) 
            {
                DS18B20_DQ_OUT=0;	// Write 1
                delay_us(2);                            
                DS18B20_DQ_OUT=1;
                delay_us(60);             
            }
            else 
            {
                DS18B20_DQ_OUT=0;	// Write 0
                delay_us(60);             
                DS18B20_DQ_OUT=1;
                delay_us(2);                          
            }
        }
    }
    
    //开始温度转换
    void DS18B20_Start(void) 
    {   						               
        DS18B20_Rst();	   
    	DS18B20_Check();	 
        DS18B20_Write_Byte(0xcc);	// skip rom
        DS18B20_Write_Byte(0x44);	// convert
    } 
    
    //初始化DS18B20的DQ 同时检测DS18B20的存在
    //返回1:不存在
    //返回0:存在   	 
    u8 DS18B20_Init(void)
    {
     	GPIO_InitTypeDef  GPIO_InitStructure;
     	
     	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    	
     	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;		
     	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		  
     	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     	GPIO_Init(GPIOC, &GPIO_InitStructure);
    
     	GPIO_SetBits(GPIOC,GPIO_Pin_10);    //拉高
    
    	DS18B20_Rst();
    
    	return DS18B20_Check();
    }  
    
    //从ds18b20得到温度值
    //精度0.1C
    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  
    		USART_SendData(USART1, TL);
    		delay_ms(10);
    		USART_SendData(USART1, TH);
    	   	  
        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;    
    }
    
    

    然后这里是51单片机的程序

    这里我用的是12M晶振,延时程序如下

    /*us延时,参数为1时约延时7us
    			  10时约延时50us
    			 100时约延时205us
    			 250时约延时480us	
    */
    void delay(uchar us) {
    	while(us--);
    }
    

    然后下面就是对DQ信号线操作的程序

    //复位ds18b20
    void Init_ds18b20(void) {
    	DQ = 1; 
    	delay(1); 
    	DQ = 0; 
    	delay(250); 
    	DQ = 1; 
    	delay(100);
    }
    
    //读一个字节
    uchar ReadoneByte() {
    	uchar i;
    	uchar dat = 0;
    	for(i=8; i>0; i--) {
    		DQ = 0;
    		_nop_();
    		dat >>= 1;
    		DQ = 1;
    		delay(1);
    		if(DQ) dat |= 0x80;
    		delay(10);
    	}
    	return dat;
    }
    
    //写一个字节
    void WriteoneByte(uchar dat) {
    	uchar i;
    	for(i=8; i>0; i--) {
    		DQ = 0;
    		_nop_();
    		DQ = dat & 0x01;
    		delay(10);
    		DQ = 1;
    		dat >>= 1;
    		delay(1);
    	}
    }
    
    //获取温度值
    int GetTempe() {
    	int temp;
    	uchar teml, temh;
    	Init_ds18b20();
    	WriteoneByte(0xcc);
    	WriteoneByte(0x44);
    	Init_ds18b20();
    	WriteoneByte(0xcc);
    	WriteoneByte(0xbe);
    	teml = ReadoneByte();//先读低四位
    	temh = ReadoneByte();//再读高四位
    	
    	temp = teml/16+temh*16;//这里只保留了整数,去掉了小数
    	//temp <<= 8;
    	//temp += teml;
    	//t = temp * 0.625;
    	return temp;
    }
    
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

无无无无无无无无无无无无无无