一乐电子

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 3326|回复: 9

单总器件操作DS2450、ds2450

[复制链接]
发表于 2011-5-14 14:38 | 显示全部楼层 |阅读模式
本帖最后由 power_peng 于 2011-5-14 15:14 编辑

今天很充实,困扰了我几天的单总线器件的读写终于搞定了,其实回头想想真的不是很困难啊。在操作单总线器件的时候,首先发送64位地址吧、码,然后发送命令。从机接受的时候只有当自己的地址码与主机匹配之后,才响应主机的命令。就这么点事折腾了我好久,闲话少说,直接上图
注:这里面用的是湿度传感器HM1500,二氧化碳传感器MG811液晶显示屏用的是金鹏的OCMJ8*15B(这个液晶的操作比较麻烦)
QQ截图未命名.png
#include <reg52.h>
#include "lcd.h"
#include "wire.h"
#define uchar unsigned char
#define uint unsigned int
uchar l_tmpdate[]={0,0,0,0,0,-48,-48,-48,-48,-48,-48,-48,-48};
uchar code ID_DS18B20[]={ 0x28,0xF9 ,0x20 ,0x7A ,0x00 ,0x00 ,0x00 ,0xB1 };
uchar code ID_DS2450_C[]={0x20 ,0x0D ,0xD2 ,0x09 ,0x00 ,0x00 ,0x00 ,0xEB}; //the hanjie_last
uchar i; float tt;uchar c,b;
int l_tmp;  

void main()               //主函数
{ uint l;
uchar q,i,j,a,b,d  ;
req=0;
busy=1;
IE=0x81;
IT0=0;
set_2450();
stature_2450();
while(1)
   {
  
   IE=0x00;
  SendData(0xf4);
  write_word(0,0,50,26);  //

        write_word(2,0,30, 7);  //
  write_word(4,0,38,33);  //
  write_word(6,0,18,66);  //
  write_word(8,0,42,52);  //
  write_word(10,0,19,41); //
  write_word(12,0,25,6);  //
  write_word(0,1,21,17);  //
  write_word(2,1,39,16);  //
  write_word(4,1,46,34);  //
  write_word(6,1,22,40);  //
     write_char16(14,16,58); //:
  write_word(0,2,21,17);  //

  write_word(2,2,39,16);  //
  write_word(4,2,42,10);  //
  write_word(6,2,22,40);  //
  write_char16(14,32,58); //:
  write_char16(15,16,(l_tmpdate[1]+48));//
温度十位
     write_char16(16,16,(l_tmpdate[2]+48));//温度个位
  write_char16(17,16,46);//温度小数位
     delay(50);
  write_char16(18,16,(l_tmpdate[4]+48));//
温度小数位??
  
  
  check();
  write(0xcc);
   write(0x44);
  check();
  delay(20);
  write(0x55);  //匹配
rom
  for(i=0;i<8;i++)
    write(ID_DS18B20);  //写序列号


  delay(50);
  write (0xbe);
  c = read();
  b = read();
  l_tmp=b;

    l_tmp<<=8;            
    l_tmp=l_tmp|c;           //两字节合成一个整型变量。
         
    tt=l_tmp*0.0625;           //
得到真实十进制温度值,因为DS18B20


    l_tmp=tt*10+0.5;         //
放大十倍,这样做的目的将小数点后第一位
   
     l_tmpdate[0]=l_tmp/1000; //
显示百位,这里用1000,是因为我们之前乖以10了
     if(l_tmpdate[0]==0)  
  l_tmpdate[0]=-48;//
判断温度为正温度且没有上百,前面不显示,查表第12是空

  l_tmp=l_tmp00;
  l_tmpdate[1]=l_tmp/100;//
获取十位
  l_tmp=l_tmp0;
  l_tmpdate[2]=l_tmp/10;//
获取个位
   l_tmpdate[3]=-2;
  l_tmpdate[4]=l_tmp;//
获取小数第一位
  l_tmpdate[5]=0;

   //   delay(50);

  check();
  star2450();
  write(0xcc);
// write(0x44);
  check();
  delay(20);
  write(0x55);  //
匹配 rom
  for(i=0;i<8;i++)
    write(ID_DS2450_C);  //写序列号

   star2450();
   l=readAD2450();
   q=l/10000;
   i=l000/1000;
   j=l00/100;
   a=l0/10;
   b=l/10;
   d=l;
  

   
   write_char16(15,32,(0x30+q));//
温度十位
     write_char16(16,32,(0x30+i));//温度十位
      write_char16(17,32,(0x30+j));//温度十位
       write_char16(18,32,(0x30+a));//温度十位
        write_char16(19,32,(0x30+b));//温度十位
         write_char16(20,32,(0x30+d));//温度十位

      delay(60000);

   }            
}



#include <intrins.h>
#define data_ora   P0              //MCU P1<------> LCM
#define uchar      unsigned char
#define uint       unsigned int

sbit req =P3^0;  //请求信号,H有效  14
sbit busy=P3^1;  //H:已收到数据并在处理中,L:空闲可接收数据 13

sbit INT =P3^2;  //根据用户自己的定义  24
sbit DCLK=P2^7;     //19
sbit CS  =P2^6;     //  20
sbit DIN =P2^5;      // 21
sbit DOUT=P2^3;  //测架
    23
uchar taby[4];
uchar tabx[4];
uint x[6],y[6],xmin,ymin,xmax,ymax;
uint r,q=1;                    

void SendData(uchar content)
{
while(busy==1);
data_ora=content;
req=1;
while(busy==0);
req=0;
}

void write_word(uchar xx,uchar yy,uchar qq,uchar ww)
  {
   SendData (0xf0);
   SendData (xx);
   SendData (yy);
   SendData (qq);
   SendData (ww);
  }

void write_char16(uchar xx,uchar yy,uchar as)
{
   SendData(0xf9);
   SendData(xx);
   SendData(yy);
   SendData(as);
}

void write_wei(uchar xx,uchar yy)
{
   SendData(0xf2);
   SendData(xx);
   SendData(yy);
   }


#include <reg52.h>
#include "intrins.h"
#define uint  unsigned int
#define uchar unsigned char
uchar ID[8];//
定义一个数组来存放序列号
uchar sn1,sn2,sn3,sn4,sn5,sn6,sn7,sn8;
sbit ADA = P1^4;
//uchar a=0;
uchar  a[8]={0};


//
延时子程序//
void delay(uint i)
{
   for(i;i>0;i--);
}



uchar read(void)     //单总线器件读函数
{
  uchar d =0;
  uint j;
  for(j=0;j<8;j++)
  {
   ADA=0;
   _nop_();
d>>=1;
ADA=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();  
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  if (ADA)
  d|=0x80;         //
先高后低一位一位传送数据
delay(4);
  }
return (d);

}


void write(uchar ch)      // DS2450写函数
{    uint i;
    for(i=0;i<8;i++)
   { ADA=0;
ADA=ch&0x01;
delay(5);
ADA=1;
ch>>=1;
    }
ADA=1;
}


uchar init(void)          //DS
复位
{ uchar flag;
   ADA=1;
delay(8);
   ADA=0;
   delay(80);
   ADA=1;
   delay(14);
   if(ADA==0)
   {
   flag=1;
   delay(80);
     }
   else
   flag=0;
   ADA=1;
   return (flag);
   }


void check(void)                 //
复位函数
{
uchar flag,j;
do
{
  flag=init();
  }
  while(flag);
  for(j=0;j<0x20;j++);         //
等待
  
}
void readrom() //read the serial
读取温度传感器的序列号子函数
{
init();
delay(4);
write(0x33);
sn1=read();
ID[7]=sn1;
sn2=read();
ID[6]=sn2;
sn3=read();
ID[5]=sn3;
sn4=read();
ID[4]=sn4;
sn5=read();
ID[3]=sn5;
sn6=read();
ID[2]=sn6;
sn7=read();
ID[1]=sn7;
sn8=read();
ID[0]=sn8;
}


void set_2450(void)           //
由于用的是VCC供电,只有给地址0x1c写入0x40才能工作
{
check();
write(0x33);
write(0x55);
write(0x1c);
write(0x00);
write(0x40);
}
void stature_2450()     //
设置各个输入通道的功能
{
  check();
//  Write2450(0xcc);
  write(0x55);
  write(0x08);
  write(0x00);
  write(0xc0);
  read();
  read() ;
  read() ;
  write(0x00);
  read();
  read() ;
  read() ;
  write(0xc0);
  read();
  read() ;
  read() ;        
write(0x00);
  read();
  read() ;
  read() ;
    write(0xc0);
  read();
  read() ;
  read() ;
  write(0x00);
  read();
  read() ;
  read() ;
write(0x00);
  read();
  read() ;
  read() ;
write(0x01);
  read();
  read() ;
  read() ;
}
star2450(void)  //
读数据开始命令
{
  check();
  write(0xcc);
  write(0x3c);
  write(0x08);
  write(0x00);
  read();
  read() ;
  if (read()!=0xff)
  read();
}
readAD2450()  //  
读取转换数据
{
  uchar a=0,b=0,i=0;
  uint t=0;
  check();
  write(0xcc);
  write(0xaa);
  write(0x06);
  write(0x00);
  a=read();
  b=read() ;
  t=b;
  t<<=8;
  t=t|a;
  return(t);

}

1.png

DS2450工作电路

DS2450工作电路
发表于 2011-5-14 14:47 | 显示全部楼层
这是做什么用的
回复

使用道具 举报

发表于 2011-5-14 15:01 | 显示全部楼层
光给程序 也给个原理图呗
回复

使用道具 举报

 楼主| 发表于 2011-5-14 15:08 | 显示全部楼层
这个是用来做温度和湿度检测用的~~要啥原理图啊  我手焊的  等我整理下
回复

使用道具 举报

 楼主| 发表于 2011-5-14 15:10 | 显示全部楼层
这个是用来做温度和湿度检测用的~~要啥原理图啊  我手焊的  等我整理下
稍后上传
回复

使用道具 举报

发表于 2011-5-14 18:27 | 显示全部楼层
恭喜恭喜,器件一小步,技术一大步。。哈哈
回复

使用道具 举报

发表于 2011-5-14 19:30 | 显示全部楼层
楼主也来一乐了。。。惊讶
回复

使用道具 举报

 楼主| 发表于 2011-5-15 08:13 | 显示全部楼层
回复 7# longlong


    你是??为什么这么惊讶??
回复

使用道具 举报

发表于 2011-5-16 21:50 | 显示全部楼层
回复 2# 农村人


    接口图看程序引脚定义不就出来了吗
回复

使用道具 举报

 楼主| 发表于 2011-5-18 18:28 | 显示全部楼层
回复 9# younge


    同意
回复

使用道具 举报

本版积分规则

QQ|一淘宝店|手机版|商店|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2026-4-21 21:15 , Processed in 0.033385 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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