发表于:2008/5/18 15:03:00
#0楼
这是我做的一个温度计,但老师还要我加PC机通信,就是采集一些温度,再把数据送PC机,我不太会,请那位高手帮我加加.大恩大德莫齿难忘!!!
/****************************************/
// DS18B20温度计C程序 //
/***************************************/
//使用89C51单片机,用共阴LED数码管
//P0口输出段码,P2口扫描(P2.4~p2.7)
#include "reg51.h"
#include "intrins.h" //-nop;延时函数用
#define Disdata P0 //段码输出口
#define discan P2 //扫描口
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^0; //温度输入口
sbit DIN=P0^7; //LED小数点控制
uint h;
//
//**************温度小数部分用查表法********************//
//uchar code scan_con[4]={0xef,0xdf,0xbf,0x7f}; //列扫描控制字
uchar code scan_con[4]={0xef,0xdf,0xbf,0x7f}; //列扫描控制字
uchar data temp_data[2]={0x0,0x0}; //读出温度暂放
uchar data dis_buffer[4]={0};
uchar code table[20]={0x3f,0x06,0x5B,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x7c,0x39,0x5e,0x79,0x71};
void del_ms(uchar d);
void display1(void);
void disp( uchar numh,uchar numl);
void ow_reset(void);
/*************11微妙延时函数*******************/
void delay(uint t)
{
for(;t>0;t--);
}
//
/**********显示扫描函数*********/
void display1(void)
{
uchar i,sel;
// sel=0xFE;
for(i=0;i<=2;i++)
{
P0=table[dis_buffer[i]];
if(i==1) { DIN=1;}
//P1=sel&0xff;
P2=scan_con[i]&0xff;
del_ms(20);
//sel=sel<<1;
}
}
//
/***********DS18B20复位函数*********/
void ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();
DQ=0;
delay(50); //550us
DQ=1;
delay(6); //66us
presence=DQ; //presence=0继续下一步
}
delay(45); //延时500us
presence=~DQ;
}
DQ=1;
}
//
/***********DS18B20写命令函数**************/
//向1-WIRE 总线上写1个字节
void write_byte(uchar val)
{
uchar i;
for (i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_(); //5us
DQ=val&0x01; //最低位移出
delay(6); //66us
val=val/2; //右移1位
}
DQ=1;
delay(1);
}
//
/**********DS18B20读1字节函数********/
//从总线上读取1个字节
uchar read_byte(void)
{
uchar i;
uchar value=0;
for (i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;
_nop_();_nop_();_nop_();_nop_(); //4us
DQ=1;_nop_();_nop_();_nop_();_nop_(); //4us
if(DQ) value|=0x80;
delay(6); //66us
}
DQ=1;
return(value);
}
//
/***********读出温度函数*********/
//
read_temp()
{
ow_reset(); //总线复位
write_byte(0xCC); //发Skip ROM命令
write_byte(0xBE); //发读命令
temp_data[0]=read_byte(); //温度低8位
temp_data[1]=read_byte(); //温度高8位
ow_reset();
write_byte(0xCC); //Skip ROM
write_byte(0x44); //发转换命令
}
/***********主函数**********/
main()
{
Disdata=0x00; //出始化断口
discan=0x00;
ow_reset(); //开机先转换一次
write_byte(0xCC); //Skip ROM
write_byte(0x44); //发转换命令
while(1)
{
read_temp(); //读出DS18B20温度数据
for(h=0;h<1000;h++)
disp(temp_data[1],temp_data[0]);
//disp();
// display1();
}
}
//
//*****************结束***********************//
void del_ms(uchar d)
{ uchar ii;
while(d)
{
for(ii=0;ii<=1;ii++);
d--;
}
}
//**********************************************
void disp(uchar numh, uchar numl)
{
uchar i=0;
uint num;
num=(int)((numh*256+numl)*5/8);//温度处理
//num=4321;
while(num>0)
{
dis_buffer[i]=num%10;
num=num/10;
i++;
}
display1();
}
/****************************************/
// DS18B20温度计C程序 //
/***************************************/
//使用89C51单片机,用共阴LED数码管
//P0口输出段码,P2口扫描(P2.4~p2.7)
#include "reg51.h"
#include "intrins.h" //-nop;延时函数用
#define Disdata P0 //段码输出口
#define discan P2 //扫描口
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^0; //温度输入口
sbit DIN=P0^7; //LED小数点控制
uint h;
//
//**************温度小数部分用查表法********************//
//uchar code scan_con[4]={0xef,0xdf,0xbf,0x7f}; //列扫描控制字
uchar code scan_con[4]={0xef,0xdf,0xbf,0x7f}; //列扫描控制字
uchar data temp_data[2]={0x0,0x0}; //读出温度暂放
uchar data dis_buffer[4]={0};
uchar code table[20]={0x3f,0x06,0x5B,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x7c,0x39,0x5e,0x79,0x71};
void del_ms(uchar d);
void display1(void);
void disp( uchar numh,uchar numl);
void ow_reset(void);
/*************11微妙延时函数*******************/
void delay(uint t)
{
for(;t>0;t--);
}
//
/**********显示扫描函数*********/
void display1(void)
{
uchar i,sel;
// sel=0xFE;
for(i=0;i<=2;i++)
{
P0=table[dis_buffer[i]];
if(i==1) { DIN=1;}
//P1=sel&0xff;
P2=scan_con[i]&0xff;
del_ms(20);
//sel=sel<<1;
}
}
//
/***********DS18B20复位函数*********/
void ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();
DQ=0;
delay(50); //550us
DQ=1;
delay(6); //66us
presence=DQ; //presence=0继续下一步
}
delay(45); //延时500us
presence=~DQ;
}
DQ=1;
}
//
/***********DS18B20写命令函数**************/
//向1-WIRE 总线上写1个字节
void write_byte(uchar val)
{
uchar i;
for (i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_(); //5us
DQ=val&0x01; //最低位移出
delay(6); //66us
val=val/2; //右移1位
}
DQ=1;
delay(1);
}
//
/**********DS18B20读1字节函数********/
//从总线上读取1个字节
uchar read_byte(void)
{
uchar i;
uchar value=0;
for (i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;
_nop_();_nop_();_nop_();_nop_(); //4us
DQ=1;_nop_();_nop_();_nop_();_nop_(); //4us
if(DQ) value|=0x80;
delay(6); //66us
}
DQ=1;
return(value);
}
//
/***********读出温度函数*********/
//
read_temp()
{
ow_reset(); //总线复位
write_byte(0xCC); //发Skip ROM命令
write_byte(0xBE); //发读命令
temp_data[0]=read_byte(); //温度低8位
temp_data[1]=read_byte(); //温度高8位
ow_reset();
write_byte(0xCC); //Skip ROM
write_byte(0x44); //发转换命令
}
/***********主函数**********/
main()
{
Disdata=0x00; //出始化断口
discan=0x00;
ow_reset(); //开机先转换一次
write_byte(0xCC); //Skip ROM
write_byte(0x44); //发转换命令
while(1)
{
read_temp(); //读出DS18B20温度数据
for(h=0;h<1000;h++)
disp(temp_data[1],temp_data[0]);
//disp();
// display1();
}
}
//
//*****************结束***********************//
void del_ms(uchar d)
{ uchar ii;
while(d)
{
for(ii=0;ii<=1;ii++);
d--;
}
}
//**********************************************
void disp(uchar numh, uchar numl)
{
uchar i=0;
uint num;
num=(int)((numh*256+numl)*5/8);//温度处理
//num=4321;
while(num>0)
{
dis_buffer[i]=num%10;
num=num/10;
i++;
}
display1();
}