找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1308|回复: 12
收起左侧

大佬们看看,ds18b20单片机读出来温度总是55.9不变

[复制链接]
ID:1058641 发表于 2024-2-5 16:42 | 显示全部楼层 |阅读模式
这是ds18b20.c的:
#include "ds18b20.h"
#include "reg52.h"

sbit DQ=P1^4;

void Delay_OneWire(unsigned int t)  
{
        unsigned char i;
        while(t--){
                for(i=0;i<12;i++);
        }
}

void Write_DS18B20(unsigned char dat)
{
        unsigned char i;
        for(i=0;i<8;i++)
        {
                DQ = 0;
                DQ = dat&0x01;
                Delay_OneWire(5);
                DQ = 1;
                dat >>= 1;
        }
        Delay_OneWire(5);
}

unsigned char Read_DS18B20(void)
{
        unsigned char i;
        unsigned char dat;

        for(i=0;i<8;i++)
        {
                DQ = 0;
                dat >>= 1;
                DQ = 1;
                if(DQ)
                {
                        dat |= 0x80;
                }            
                Delay_OneWire(5);
        }
        return dat;
}

unsigned char init_ds18b20(void)
{
          unsigned char initflag = 0;
         
          DQ = 1;
          Delay_OneWire(12);
          DQ = 0;
          Delay_OneWire(80);
          DQ = 1;
          Delay_OneWire(10);
    initflag = DQ;     
          Delay_OneWire(5);

          return initflag;
}

float read_ds18b20_temp()
{
        unsigned char ls;
        unsigned int hs;

        init_ds18b20();
        Write_DS18B20(0xcc);
        Write_DS18B20(0x44);
        Delay_OneWire(1000);
        
        init_ds18b20();
        Write_DS18B20(0xcc);
        Write_DS18B20(0xbe);
        
        ls=Read_DS18B20();
        hs=Read_DS18B20();

  return ((hs<<8)|ls)/16.0;
}


这是主程序:
#include "reg52.h"
#include "ds18b20.h"

unsigned char smgdata[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x8c};
float temp;

void selecthc573(unsigned char a)
{
        switch(a)
        {
                case 4: P2=(P2&0x1f)|0x80;break;
                case 5: P2=(P2&0x1f)|0xa0;break;
                case 6: P2=(P2&0x1f)|0xc0;break;
                case 7: P2=(P2&0x1f)|0xe0;break;
        }
}

void seg_dy(unsigned char wei,duan,point)
{
        P0=0xff;
        
        if(point)
        {
                selecthc573(7);
                P0=duan&0x7f;
                P2&=0x1f;
        }
        else
        {
                selecthc573(7);
                P0=duan;
                P2&=0x1f;
        }
        
        selecthc573(6);
        P0=0x01<<wei;
        P2&=0x1f;
        
        
}

void delay(int s)
{
        while(s--);
}

void segdisplay()
{
        temp=read_ds18b20_temp();
        seg_dy(0,smgdata[((unsigned char)temp/10%10)],0);
        delay(600);
        seg_dy(1,smgdata[((unsigned char)temp%10)],1);
        delay(600);
        seg_dy(2,smgdata[((unsigned int)(temp*10)%10)],0);
        delay(600);
}

int main()
{
        while(1)
        {
                segdisplay();
        }
               
}

回复

使用道具 举报

ID:1109793 发表于 2024-2-6 09:53 | 显示全部楼层
10多年前研究过,记得时序要求比较严格。还有加上拉
回复

使用道具 举报

ID:1058641 发表于 2024-2-6 12:47 | 显示全部楼层
xiaobendan001 发表于 2024-2-6 09:53
10多年前研究过,记得时序要求比较严格。还有加上拉

我感觉这也没问题啊
回复

使用道具 举报

ID:1058641 发表于 2024-2-6 14:50 | 显示全部楼层
有人知道吗
回复

使用道具 举报

ID:213173 发表于 2024-2-6 15:07 | 显示全部楼层
rtyweq 发表于 2024-2-6 12:47
我感觉这也没问题啊

ds18b20对时序要求很高,数码管动态显示也要求稳定扫描,你不掌握两者时间的有序协调,很难成功。


无标题.jpg

  1. #include "reg52.h"
  2. #include "intrins.h"

  3. sbit DQ=P1^4;

  4. unsigned char code smgdata[]={
  5. 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
  6. 0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x8c};
  7. unsigned char  data dis_buf[8];
  8. unsigned int temp;

  9. bit flag;

  10. void delay(unsigned int n)
  11. {
  12.         while(n--);      
  13. }

  14. unsigned char init_ds18b20()
  15. {
  16.         unsigned char x=0;
  17.         DQ = 1;
  18.         delay(8);
  19.         DQ=0;
  20.         delay(80);
  21.         DQ=1;
  22.         delay(10);
  23.         x=DQ;
  24.         delay(20);
  25.         return x;
  26. }

  27. void Write_DS18B20(unsigned char dat)
  28. {
  29.         unsigned char i;
  30.         for(i=8;i>0;i--)
  31.         {
  32.                 DQ=0;
  33.                 DQ=dat&0x01;
  34.                 delay(5);
  35.                 DQ=1;
  36.                 dat>>=1;
  37.         }
  38.         delay(4);
  39. }

  40. unsigned char Read_DS18B20()
  41. {
  42.         unsigned char i,dat;

  43.         for(i=8;i>0;i--)
  44.         {
  45.                 DQ=0;
  46.                 dat>>=1;
  47.                 DQ=1;
  48.                 if(DQ)
  49.                 dat|=0x80;
  50.                 delay(4);
  51.         }
  52.         return (dat);
  53. }

  54. void read_ds18b20_temp()
  55. {
  56.         static unsigned char ls,hs,i;
  57.         switch(i)
  58.         {
  59.                 case  0: init_ds18b20();        break;
  60.                 case  1: Write_DS18B20(0xcc);   break;
  61.                 case  2: Write_DS18B20(0x44);   break;
  62.                 case 94: init_ds18b20();        break;
  63.                 case 95: Write_DS18B20(0xcc);   break;
  64.                 case 96: Write_DS18B20(0xbe);   break;
  65.                 case 97: ls=Read_DS18B20();     break;
  66.                 case 98: hs=Read_DS18B20();     break;
  67.                 case 99: temp=((hs<<8)|ls)/1.6; break;//保留1位小数
  68.         }
  69.         i=++i%100;
  70. }

  71. void Timer0_Init(void)                //2毫秒@11.0592MHz
  72. {
  73.         TMOD |= 0x01;                        //设置定时器模式
  74.         TL0 = 0xCD;                                //设置定时初始值
  75.         TH0 = 0xF8;                                //设置定时初始值
  76.         TF0 = 0;                                //清除TF0标志
  77.         TR0 = 1;                                //定时器0开始计时
  78.         ET0 = 1;                                //使能定时器0中断
  79.         EA  = 1;
  80. }

  81. void main()
  82. {
  83.         unsigned char i,j;
  84.         Timer0_Init();
  85.         while (1)
  86.         {
  87.                 if(flag)
  88.                 {
  89.                         flag=0;
  90.                         P0=0xff;       P2=0xe0; P2=0x00;//段消影
  91.                         P0=0x01<<i;    P2=0xd0; P2=0x00;//传位码
  92.                         P0=dis_buf[i]; P2=0xe0; P2=0x00;//传段码
  93.                         i=++i%4;
  94.                         read_ds18b20_temp();
  95.                         switch(j)
  96.                         {
  97.                                 case 0: dis_buf[0]=smgdata[temp/1000%10]; break;
  98.                                 case 1: dis_buf[1]=smgdata[temp/100%10]; break;
  99.                                 case 2: dis_buf[2]=smgdata[temp/10%10]&0x7f; break;//加小数点
  100.                                 case 3: dis_buf[3]=smgdata[temp%10]; break;
  101.                         }       
  102.                         j=++j%4;
  103.                 }
  104.         }
  105. }
  106. void Timer0_Isr(void) interrupt 1
  107. {
  108.         TL0 = 0xCD;                                //设置定时初始值
  109.         TH0 = 0xF8;                                //设置定时初始值
  110.         flag=1;
  111. }
复制代码



回复

使用道具 举报

ID:1109793 发表于 2024-2-6 19:04 | 显示全部楼层
wulin 发表于 2024-2-6 15:07
ds18b20对时序要求很高,数码管动态显示也要求稳定扫描,你不掌握两者时间的有序协调,很难成功。

真不错,学习了
回复

使用道具 举报

ID:1058641 发表于 2024-2-6 21:29 | 显示全部楼层
wulin 发表于 2024-2-6 15:07
ds18b20对时序要求很高,数码管动态显示也要求稳定扫描,你不掌握两者时间的有序协调,很难成功。

就是对这里不明白,做这个延时就很烦
回复

使用道具 举报

ID:161164 发表于 2024-2-6 21:37 | 显示全部楼层
Delay_OneWire这函数有问题
在11.0592Mhz之下
Delay_OneWire(5)=766us
Delay_OneWire(12)=1814us
Delay_OneWire(80)=1200us
回复

使用道具 举报

ID:1058641 发表于 2024-2-6 21:40 | 显示全部楼层
lkc8210 发表于 2024-2-6 21:37
Delay_OneWire这函数有问题
在11.0592Mhz之下
Delay_OneWire(5)=766us

是把for循环去掉吗?
回复

使用道具 举报

ID:1058641 发表于 2024-2-6 22:26 | 显示全部楼层
lkc8210 发表于 2024-2-6 21:37
Delay_OneWire这函数有问题
在11.0592Mhz之下
Delay_OneWire(5)=766us

好像是多了这个,仿真不是12Mhz。但是为什么那个显示出来的温度要跳成别的温度?
回复

使用道具 举报

ID:161164 发表于 2024-2-7 09:10 | 显示全部楼层
本帖最后由 lkc8210 于 2024-2-7 11:09 编辑
rtyweq 发表于 2024-2-6 22:26
好像是多了这个,仿真不是12Mhz。但是为什么那个显示出来的温度要跳成别的温度?

时序不对就会出现莫名奇妙的情况

正好你用的是仿真
可以加个虚拟逻辑分析仪来看看信号电平变化时序
回复

使用道具 举报

ID:213173 发表于 2024-2-7 10:20 | 显示全部楼层
rtyweq 发表于 2024-2-6 21:29
就是对这里不明白,做这个延时就很烦

软件都是基于硬件条件编写的。给你改的代码是基于你以前的帖子用的蓝桥杯CT107D电路。小延时可以用阻塞型没有问题,超过1ms延时不宜用阻塞型,要用定时器。否则无法满足各个子函数对时序的要求。上述程序主函数有效运行周期2ms。也就是数码管每2ms显示1位。8ms完成一轮扫描。读取温度DS18B20函数需要在主函数中运行100次才能完成,实际有效运行只有9次,其它时间都是在等待确保转换成功。读/写DS18B20函数中的小延时都是us级的不会影响数码管动态扫描。
回复

使用道具 举报

ID:1058641 发表于 2024-2-7 15:08 | 显示全部楼层
wulin 发表于 2024-2-7 10:20
软件都是基于硬件条件编写的。给你改的代码是基于你以前的帖子用的蓝桥杯CT107D电路。小延时可以用阻塞型 ...

学到了学到了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表