游客
主题
回帖0
积分27
阅读权限1
注册时间2011-4-5
最后登录1970-1-1
在线时间 小时
|
本帖最后由 power_peng 于 2011-5-14 15:14 编辑
今天很充实,困扰了我几天的单总线器件的读写终于搞定了,其实回头想想真的不是很困难啊。在操作单总线器件的时候,首先发送64位地址吧、码,然后发送命令。从机接受的时候只有当自己的地址码与主机匹配之后,才响应主机的命令。就这么点事折腾了我好久,闲话少说,直接上图
注:这里面用的是湿度传感器HM1500,二氧化碳传感器MG811液晶显示屏用的是金鹏的OCMJ8*15B(这个液晶的操作比较麻烦)
#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);
}
|
-
-
DS2450工作电路
|