打印
[STC单片机]

STC15单片机想实现一线多点DS18B20

[复制链接]
2016|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yl616768|  楼主 | 2018-5-9 17:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
yl616768|  楼主 | 2018-5-9 17:25 | 只看该作者
//#include "stc15.h"
//#include "intrins.h"
//sbit a=P0^1;
//
//void Delay_DS18B20(unsigned char n)
//{   
//        while(n--);
//}
//
//void main()
//{       
////        CLK_DIV=0X03;
//        while(1)
//        {
//               
//                a=1;
//                Delay_DS18B20(80);
//                a=0;
//                Delay_DS18B20(80);
//       
//        }
//
//}
#include<STC15.H>
#include "stdio.h"
#include "intrins.h"
#define ulong unsigned long
#define uchar unsigned char     
#define uint unsigned int
#define MAXNUM 5
sbit temp=P5^5;       //18B20
sbit t1=P0^1;
sbit t2=P0^0;
sbit t3=P0^5;
uchar ID[MAXNUM][8]={0};
uchar test_k;
void UartInit(void)                //9600bps@11.0592MHz
{
        SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //设定定时器1为16位自动重装方式
        TL1 = 0xE0;                //设定定时初值
        TH1 = 0xFE;                //设定定时初值
        ET1 = 0;                //禁止定时器1中断
        TR1 = 1;                //启动定时器1
        TI= 1;
}
void Delay_DS18B20(ulong n)
{   
        while(n--);
}
/*****初始化DS18B20*****/
void Init_DS18B20(void)
{   
        unsigned char x=0;   
        temp = 1;          //temp复位   
        Delay_DS18B20(2);   //稍做延时4us   
        temp = 0;          //单片机将temp拉低   
        Delay_DS18B20(90); //精确延时,大于480us  
        temp = 1;          //拉高总线   
        Delay_DS18B20(20);  
        x = temp;            //稍做延时后,如果x=0则初始化成功,x=1则初始化失败   
        Delay_DS18B20(20);
}

/*****读一个字节*****/
unsigned char ReadOneChar(void)
{   
        unsigned char i=0,j=0;   
        unsigned char dat = 0;  
        for (i=8;i>0;i--)   
        {   
        temp = 0;     // 给脉冲信号
        j++;j++; j++;j++;  
        dat>>=1;
        j++;j++; j++;j++;   
        temp = 1;     // 给脉冲信号
                j++;j++; j++;j++;
        if(temp)   
        dat|=0x80;  
        Delay_DS18B20(8);  
}   
        return(dat);
}

/*********读一位***********/


//bit read1bit(void)
//{     
//        bit dat = 0;  
//
//        temp = 0;     // 给脉冲信号   
//        Delay_DS18B20(1);   
//        temp = 1;     // 给脉冲信号
//        Delay_DS18B20(1);
//        if(temp)   
//        dat|=0x01;  
//        Delay_DS18B20(5);
//        return dat;  
//}


/********读两位************/
unsigned char Read2Bit(void)
{   
        unsigned char i=0,j=0;   
        unsigned char dat = 0;  
        for (i=2;i>0;i--)   
        {   
        temp = 0;     // 给脉冲信号
        j++;j++; j++;j++;  
        dat>>=1;
        j++;j++; j++;j++;   
        temp = 1;     // 给脉冲信号
                j++;j++; j++;j++;
        if(temp)   
        dat|=0x80;  
        Delay_DS18B20(8);  
}   
        dat>>=6;
        return(dat);
}

//uchar  Read2Bit(void)
//{
//        uchar i,dat=0;
//        for(i=0;i<2;i++)
//        {
//                dat<<=1;
//                if(read1bit())
//                dat|=1;
//       
//        }
//       
//        return dat;
//}



/*****写一个字节*****/
void WriteOneChar(unsigned char dat)
{   
        unsigned char i=0,j=0;;  
        for (i=8; i>0; i--)  
        {  
                temp = 0;
                j++;j++;j++;j++;
                temp = dat&0x01;  
                Delay_DS18B20(10);  
                temp = 1;  
                dat>>=1;
                j++;j++;j++;  
        }
}

/*********写一位*********/
void write_bit(unsigned char dat)
{   
        unsigned char i=0,j=0;;  
        for (i=1; i>0; i--)  
        {  
                temp = 0;
                j++;j++;j++;j++;
                temp = dat&0x01;  
                Delay_DS18B20(10);  
                temp = 1;  
                dat>>=1;
                j++;j++;j++;  
        }
}
//void write_bit(unsigned char dat)
//{   
//       
//        unsigned char i=0;  
//        for (i=1; i>0; i--)  
//        {  
//                temp = 0;  
//                temp = dat&0x01;  
//                Delay_DS18B20(10);  
//                temp = 1;  
//                Delay_DS18B20(10);  
//         }
//
// }
/*********************/

void Delay1000ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        _nop_();
        _nop_();
        i = 43;
        j = 6;
        k = 203;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}
uchar search_rom(void)  
{   
    unsigned char k,l,chongtuwei,m,n;  
    unsigned char zhan[(MAXNUM)]={0};  
    unsigned char ss[64];  
    int num = 0;  
    l=0;  
      
    do  
    {  
      Init_DS18B20();
        Delay_DS18B20(100);  
      WriteOneChar(0xf0);
        Delay_DS18B20(100);     
        for(m=0;m<8;m++)  
        {  
            unsigned char s=0;  
            for(n=0;n<8;n++)  
            {           t1=0;
                                 t2=0;
                                 t3=0;
                k=Read2Bit();//读两位数据
                     k=k&0x03;  
                s>>=1;  
                if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应  
                {   t1=1;         
                    write_bit (0);  
                    ss[(m*8+n)]=0;  
                }  
                else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应  
                {  t2=1;
                    s=s|0x80;  
                    write_bit (1);  
                    ss[(m*8+n)]=1;  
                }  
                else if(k==0x00)//00,判断冲突位 冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写1  
                {    t3=1;            
                    chongtuwei=m*8+n+1;                  
                    if(chongtuwei>zhan[l])  
                    {                        
                        write_bit (0);  
                        ss[(m*8+n)]=0;                                                
                        zhan[++l]=chongtuwei;                        
                    }  
                    else if(chongtuwei<zhan[l])  
                    {  
                        s=s|((ss[(m*8+n)]&0x01)<<7);  
                        write_bit (ss[(m*8+n)]);  
                    }  
                    else if(chongtuwei==zhan[l])  
                    {  
                        s=s|0x80;  
                        write_bit (1);  
                        ss[(m*8+n)]=1;  
                        l=l-1;  
                    }  
                }  
                else  
                {  
                    return num; //搜索完成,//返回搜索到的个数  
                }
                         
            }
                         
            ID[num][m]=s;        
        }  
        num=num+1;  
    }  
    while(zhan[l]!=0&&(num<MAXNUM));   
      
    return num;     //返回搜索到的个数  
}


void main()
{

        unsigned char a=0;  
        unsigned char b=0;   
        unsigned int t=0;
        unsigned char flag;   
        float tt=0;
//        uchar f;
//         uchar u,n;
        uchar r;
        uchar  N;
        UartInit();
       
//
while(1)   
{         
        N=search_rom();
        printf("number of ds18b20:%d\r\n",N);
        for(r=0;r<8;r++)
        {
                printf("%x\r\n",ID[0][r]);
        }


//       
       
///*
//        Delay_DS18B20(1);
//        WriteOneChar(0x55);
//        for(f=0;f<8;f++)
//        {
//        WriteOneChar(ID[1][f]);       
//       
//        }
//  */


        Init_DS18B20();
        WriteOneChar(0xCC); //跳过读序号列号的操作   
        WriteOneChar(0x44); //启动温度转换   
        Delay_DS18B20(20);  
        Init_DS18B20();   
        WriteOneChar(0xCC); //跳过读序号列号的操作
        WriteOneChar(0xBE); //读取温度寄存器  
        a=ReadOneChar();    //读低8位
        printf("%x\r\n",a);

        b=ReadOneChar();    //读高8位
        printf("%x\r\n",b);  
        t=b;   
        t<<=8;  
        t=t|a;
        printf("%x\r\n",t);
        if((t&0xf800)==0xf800)
{
        t = ~t;
        t = t + 1;
        flag = 1;
        tt=t*0.0625*10 + 0.5;
        tt=tt*(-1);  
                 //放大10倍输出并四舍五入
}  
  else
  {
          tt = t*0.0625*10 + 0.5;
  }
  if(flag == 0)
{        printf("temp = %.1f\r\n",tt/10); }
else
{
        printf("temp = %.1f\r\n",tt/10);       
}
        Delay1000ms();
  }
}

使用特权

评论回复
板凳
yl616768|  楼主 | 2018-5-9 17:26 | 只看该作者
我觉得主要是搜索ROM那个地方,可是一直查不出原因

使用特权

评论回复
地板
xyz549040622| | 2018-5-9 20:00 | 只看该作者
主要就是延时函数,网上找找例程,18b20的例子不少的。

使用特权

评论回复
5
dirtwillfly| | 2018-5-10 08:27 | 只看该作者
光看程序看不出问题的,建议用逻辑分析仪或示波器观察下时序。时序最直观

使用特权

评论回复
6
cactus0117| | 2018-5-10 23:00 | 只看该作者
单片机与电子技术 QQ778917832

使用特权

评论回复
7
ayb_ice| | 2018-5-11 08:32 | 只看该作者
yl616768 发表于 2018-5-9 17:26
我觉得主要是搜索ROM那个地方,可是一直查不出原因

搜索算法还是有点复杂,美信官网有详细资料,以前搞过的

使用特权

评论回复
8
yl616768|  楼主 | 2018-5-11 10:07 | 只看该作者
xyz549040622 发表于 2018-5-9 20:00
主要就是延时函数,网上找找例程,18b20的例子不少的。

嗯,单个器件延时的话没有问题的,可以出来温度值

使用特权

评论回复
9
yl616768|  楼主 | 2018-5-11 10:09 | 只看该作者
dirtwillfly 发表于 2018-5-10 08:27
光看程序看不出问题的,建议用逻辑分析仪或示波器观察下时序。时序最直观 ...

看了时序,读写复位啥的都没问题,还特意把时序尽可能调到了中间位置,怕边缘会引起误差导致时序不对,可是这样还是不行,哎

使用特权

评论回复
10
yl616768|  楼主 | 2018-5-11 10:10 | 只看该作者
cactus0117 发表于 2018-5-10 23:00
单片机与电子技术 QQ778917832

加不了,麻烦你加一下我吧943487409

使用特权

评论回复
11
dirtwillfly| | 2018-5-11 15:57 | 只看该作者
yl616768 发表于 2018-5-11 10:09
看了时序,读写复位啥的都没问题,还特意把时序尽可能调到了中间位置,怕边缘会引起误差导致时序不对,可 ...

有没有照片,贴出来看看

使用特权

评论回复
12
yl616768|  楼主 | 2018-5-11 20:12 | 只看该作者
dirtwillfly 发表于 2018-5-11 15:57
有没有照片,贴出来看看

时序有点长啊,不好贴

使用特权

评论回复
13
yl616768|  楼主 | 2018-5-11 20:16 | 只看该作者
dirtwillfly 发表于 2018-5-11 15:57
有没有照片,贴出来看看

复位时序661us,两次写间隔94us,每个字节里面每位之间间隔1.8us;读时序之间间隔84us

使用特权

评论回复
14
coody| | 2018-5-11 22:38 | 只看该作者
按时序写,什么MCU都可以访问的,你先调好一个点的访问。

使用特权

评论回复
15
yl616768|  楼主 | 2018-5-12 08:52 | 只看该作者
coody 发表于 2018-5-11 22:38
按时序写,什么MCU都可以访问的,你先调好一个点的访问。

一个点的已经没问题了,多个的可能时序受到了干扰还是怎么的,出不来

使用特权

评论回复
16
donghp1979| | 2018-5-19 12:19 | 只看该作者
读取温度时为什么跳过rom?这不就时序冲突了吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

12

帖子

0

粉丝