微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 温度传感器18B20时序正确,但总是不成功的原因

温度传感器18B20时序正确,但总是不成功的原因

时间:10-02 整理:3721RD 点击:
前几天学习温度传感器的时候,按照时序图写好各个功能函数,但调试时复位总失败,今天突然发现原来是单片机的问题,同是11.0952Mhz晶振下89C52执行一次加减运算耗时10us,而STC12C5A69S2则是89C52的十二分之一。我用的是STC12C5A60S2单片机,延时10us却做的89C52的10us,
难怪会失败!

前几天也出现向小编一样的情况

这就是时序不正确

不知道 咋的 我的还没调出来,同时也不上面的原因,不知为啥     哎   http://bbs.elecfans.com/jishu_448097_1_1.html

温度传感器读不出来一般都是时序的问题, for(time=0;time<200;time++);  
你这延时是有多久啊?

书上写的是 600us左右吧   这也是我一直疑惑的问题,晶振12MHZ,不知这个语句时间怎么算。   哥,你指的时序问题是 像上面一样的语句时间长度问题

你用的是什么单片机啊!我来调试一下,看哈问题所在

                 不管能不能找到问题所在,先谢谢了   你先试试 吧

用的是
at89c51                                                   

bit datayn(void)       //初始化设置
{
                 bit flag=1;
                 di=1;
                 for(time=0;time<2;time++);
                 di=0;
                 for(time=0;time<200;time++);  
                 di=1;
                 for(time=0;time<10;time++);
                 flag=di;
                 for(time=0;time<100;time++);
                  di=1;
                 for(time=0;time<10;time++);
                 return(flag) ;
}
uchar read_onechar(void)
{
        unsigned char dat;
        unsigned char i;

     for(i=0;i<8;i++)
         {
               di=1;
                   _nop_();
                   di=0;
                   dat>>=1;
                   _nop_();
                   _nop_();
                   _nop_();
                   _nop_();
                   _nop_();
                   di=1;
                   for(time=0;time<2;time++);
                   if(di)
                   {
                       dat |= 0x80;
                   }
                    for(time=0;time<15;time++);        //这里原先的4应该改大,否则读取错误
         }
        return dat;  
}
void write_onechar(uchar dat)
{
        unsigned char i;
     for(i=0;i<8;i++)
         {
             di=1;
                 _nop_();
                 di=0;
                 for(time=0;time<5;time++);
         di=dat&0x01;
                 for(time=0;time<15;time++);
                 di=1; //这个释放总线必不可少,但你这里没错
                 _nop_();
                 _nop_();
                 dat>>=1;
         }
         for(time=0;time<3;time++);
}
你应该就是第一个注释那里有错,时间的精度没有问题,我调试的时候忘啦第二个注释的语句,结果搞啦好半天,这是按照你的仿真图来调试的
没有加液晶,是用LED灯来测试的,这样基本是没问题的啦!

哥,很感谢了   谢谢了  

哥,有空能在帮我看个程序吗,还是18b20,温度倒是出来 ,也挺好。后来我在原来基础上加了四个模块(由不同温度调电机转速),刚开始还好,一段时间后就不稳了,有空帮忙看看吧,先谢谢了     http://bbs.elecfans.com/jishu_448650_1_1.html

最近因为开学等事情很忙,所以可能挤不出多少时间,不过我会帮你看一下的,这也算我们共同学习吧!
如果已经调试好啦!告诉我一下

    先谢谢了   哈哈        暂时还没有调好,还有就是18b20温度变化后,显示屏变化显示很慢,一般有10s左右才变化;没加后面模块时候,温度显示时候,偶尔还会闪一下其他数字值温度,个人认为很可能是时序问题   

                  后来我又把程序改过了 ,还是一样的毛病,现在才感觉写程序好写,不好调试啊          http://bbs.elecfans.com/jishu_448704_1_1.html

挺不错的资料,收藏了先

#include<reg52.h>
#include <intrins.h>
#define uchar  unsigned char
#define uint unsigned int
sbit ds=P2^2;
sbit lcden=P3^4;
sbit lcdrs=P3^5;
sbit dula=P2^6;
sbit wela=P2^7;
uchar flag,num;
uint temp;
uchar code table[]={"Temp=      C"};
uchar code table1[]={"0123456789"};     //不带小数点数字编码

void delay_us(uint x)                         //延时x微秒
{
        while(x--);
}
void delay(uint i)                          //延时i 毫秒
{                 
        uint x,y;
        for(x=i;x>0;x--)
                for(y=110;y>0;y--);
}
void write_com(uchar com)           //液晶写命令函数
{
         lcdrs=0;
         P0=com;
         delay(5);
         lcden=1;
         delay(5);
         lcden=0;
}
void write_data(uchar date)                 //液晶写数据
{
        lcdrs=1;
        P0=date;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}

void init_yejing()                                  //液晶初始化
{
        dula=0;
        wela=0;
        lcden=0;
        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
        write_com(0x80);
        for(num=0;num<12;num++)
        {
                write_data(table[num]);
                delay(5);
        }
        write_com(0x80+10);
        write_data(0xdf);
}
/*void ds_reset()            //DS18B20初始化
{
        ds=1;
        delay_us(1);
        ds=0;
//        delay_us(600);
//        delay_us(40);
        delay_us(81);
        ds=1;
        delay_us(44);
        if(ds==0)
                flag=1;                 //检测28b20成功
        else
                flag=0;                 //检测28b20失败
        delay_us(140);
        ds=1;
}                         */
void ds_reset()            //DS18B20初始化
{
        uint i;
        ds=0;
        i=103;
        while(i>0) i--;
        ds=1;
        i=4;
        while(i>0) i--;
}
/*bit ds_read_bit()      //温度传感器读一位
{
        bit dat;
//        ds=1;
//        delay_us(2);
        ds=0;
//        delay_us(6);
//        delay_us(2);
        ds=1;
        delay_us(4);
        dat=ds;
        delay_us(15);
        return(dat);
}          */
bit ds_read_bit()                              
{
        uint i;
        bit dat;
        ds=0;
        i++;
        ds=1;
        i++;i++;
        dat=ds;
        i=8;
        while(i>0) i--;
        return dat;
}
uchar ds_read_byte()      //温度传感器读一字节
{
        uchar value,i,j;
        value=0;
        for(i=0;i<8;i++)
        {
                j=ds_read_bit();
                value=(j<<7)|(value>>1);
        }        
        return value;
}
void ds_write_byte(uchar dat)          //温度传感器写一个字节
{
uchar j;                                         
        uint i;
        bit onebit;
        for(j=0;j<8;j++)
        {
                onebit=dat&0x01;
                dat=dat>>1;        
        if(onebit)                                                //写1
        {
                ds=0;
                i++;i++;
                ds=1;
                i=8;while(i>0)i--;
        }
        else                              //写0
        {
                ds=0;
                i=8;
                while(i>0)
                i--;
                ds=1;
                i++;i++;
        }
        }
}                                

void tem_change()              //发送温度转换命令
{
        ds_reset();
        delay(2);
        ds_write_byte(0xcc);
        ds_write_byte(0x44);
}
uint get_temp()
{
        float wendu;
        uchar H,L;
        ds_reset();
        delay(2);
        ds_write_byte(0xcc);
        ds_write_byte(0xbe);
        L=ds_read_byte();
        H=ds_read_byte();
        temp=H;
        temp=temp<<8;
        temp=temp|L;
        wendu=temp*0.0625;
        temp=wendu*100+0.05;
        return temp;         
}
void display(uint wendu)                           //液晶屏显示温度
{
        uchar qian,bai,shi,ge,wenduH,wenduL;
        wenduH=wendu/100;
        wenduL=wendu%100;
        qian=wenduH/10;       //测得的温度的首位
        bai=wenduH%10;       //测得的温度的第二位
        shi=wenduL/10;       //测得的温度的第三位
        ge=wenduL%10;       //测得的温度的第四位
        write_com(0x80+5);
        delay(5);
        write_data(table1[qian]);
        delay(5);
        write_data(table1[bai]);
        delay(5);
        write_data('.');
        delay(5);
        write_data(table1[shi]);
        delay(5);
        write_data(table1[ge]);
        delay(5);
}
                                                         
void main()
{
        uint e;
        init_yejing();
        while(1)
        {
                 tem_change();
                 for(e=10;e>0;e--)
                 {
                         display(get_temp());
             }
        }
}

我想问下大神们写一个字节这个地方为什么一定要分别把j定义为uchar  把i定义为uint,不能定义反也不能都定义成uint或uchar  否则就无法出数据呢?还有读一个字节这个地方为什么程序中那个函数可以,  但是我自己写的上面的那个程序就不行啊?眼都看瞎了都不知道怎么回事  谢谢大神了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top