//本程序是12位温度传感器的驱动程序,已经实现了大部分功能,只有几个部分未完成,可在使用时简单修正就课使用,包括:
//1.温度值的显示部分,当温度低于1摄氏度而又高于0摄氏度时的显示部分;2.设定温度的上下限值。
#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
unsigned char code wei[]={0xC0,0xf9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98};
sbit SCL= P3^6;
sbit SDA= P3^7;
unsigned char SystemError;
unsigned int Temperature; //温度
unsigned char ZorF; //正还是负
unsigned int Temp;
void Delay(unsigned char Time)
{
unsigned char i=0;
for(;Time>0;Time--)
{ for(;i<128;i++)
{;;}
}
}
//延时函数(I2C内部函数调用),可以更具系统时钟的不同更改延迟时间i的值
void delay()
{
unsigned int i=10;
while(i--);
}
/*--------------------------------------------------------------------------------
调用方式:void I2CStart(void)
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
void I2CStart(void)
{
// EA=0;
SDA=1; SCL=1; delay();//INI
SDA=0; delay();//START
SCL=0; delay();
}
/*--------------------------------------------------------------------------------
调用方式:void I2CStop(void)
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
void I2CStop(void)
{
SDA=0;
SCL=1;
delay();//INI
SDA=1;
delay();//STOP
// EA=1;
}
/*--------------------------------------------------------------------------------
调用方式:I2CAck(void)
函数说明:私有函数,I2C专用,等待从器件接收方的应答
---------------------------------------------------------------------------------*/
void WaitAck(void)
{
unsigned char errtime=255;//因故障接收方无ACK,超时值为255。
SDA=1;delay();
SCL=1;delay();
SystemError=0x10;
while(SDA)
{ errtime--;
if(!errtime)
{ I2CStop();
SystemError=0x11;
return;
}
}
SCL=0; delay();
}
/*--------------------------------------------------------------------------------
调用方式:void SendAck(void)
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,非应答信号。
---------------------------------------------------------------------------------*/
void SendNotAck(void)
{
SDA=1; delay();
SCL=1; delay();
SCL=0; delay();
}
/*--------------------------------------------------------------------------------
调用方式:void I2CSend(unsigned char ch)
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
/*void I2CSendByte(unsigned char ch)
{
unsigned char i=8;
while(i--)
{
SCL=0;_nop_(); delay();
SDA=(bit)(ch&0x80); ch<<=1; delay();
SCL=1; delay();
}
SCL=0; delay();
}
*/void I2CSendByte(char dat)
{
unsigned char t = 8;
do
{
SDA = (bit)(dat & 0x80);
dat <<= 1;
SCL = 1;
delay();
SCL = 0;
delay();
} while ( --t != 0 );
}
/*--------------------------------------------------------------------------------
调用方式:unsigned char I2CReceive(void)
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
/*
unsigned char I2CReceiveByte(void)
{
unsigned char i=8;
unsigned char dat=0;
SDA=1;
SCL=1;
while(i--)
{
dat<<=1;
SCL=0;delay();
SCL=1;delay();
dat|=SDA;
}
SCL=0; delay();
return(dat);
}
*/
char I2CReceiveByte()
{
char dat;
unsigned char t = 8;
SDA = 1; //在读取数据之前,要把SDA拉高
do
{
SCL = 1;
delay();
dat <<= 1;
if ( SDA ) dat |= 0x01;
SCL = 0;
delay();
} while ( --t != 0 );
return dat;
}
////////////////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------------------------
ACK BY MASTER 有CPU给传感器一个低,所以这个ACK是来自CPU的。
---------------------------------------------------------------------------*/
void bitout()
{
SDA=0; delay();
SCL=0; delay();
// SDA=0; delay();
SCL=1; delay();
SCL=0; delay();
}
//读温度传感器,温度值是由h的高字节和低字节的高四位组成,其中负温度值是由补码形式
void Read(uchar address)
{
unsigned char h,l,temp,c;
int wendu;
I2CStart();
I2CSendByte(address); //写
WaitAck();
I2CSendByte(0x00); //指向温度寄存器
SendNotAck();
I2CStop();
I2CStart();
I2CSendByte(address+1); //读
WaitAck();
h=I2CReceiveByte(); //读高8位
bitout(); //CUP送低
l=I2CReceiveByte(); //读低8位
SendNotAck();
I2CStop();
c=4; //循环4次
wendu=h;temp=l;
//将高8位和低8位的前4位连接
while(c--)
{
if(temp&0x80)
{
wendu<<=1;
wendu|=0x0001;
}
else
{
wendu<<=1;
}
temp<<=1;
}
//判断温度正负
// if(h&0x80) //负
// {
// wendu=wendu-0x01;//变成反码
// wendu=~wendu; //变回原码
// wendu=wendu&0x03FF;
// wendu=wendu*0.0625;
// Temperature=wendu;
// ZorF=0;
// }
// else //正
// {
wendu=wendu&0x03FF;
wendu=wendu*0.625;
Temperature=wendu;
// ZorF=1;
// }
// Temperature*=10;
// return(Temperature);
// display(Temperture);
}
/*设定adt75的OTI和HYST
----------------------------------------------------------------------------
OTI为上限 HYST为下限
adt75做为恒温器使用 OTI必须低有效。当温度高于OTI值时由OTI脚发出低,直到温度低于
HYST值OTI脚才发出高。
-----------------------------------------------------------------------------
void SetupOTI(int OTI,int HYST,unsigned char address)
{
unsigned char a,b;
a=(uchar)(OTI>>8); //温度转换
// a=a*4;
// a>>=2;
b=(uchar)(HYST>>8); //温度转换
// b=b*4;
// b>>=2;
I2CStart();
I2CSendByte(address); //写
WaitAck();
I2CSendByte(0x01); //指向状态寄存器
WaitAck();
I2CSendByte(0x18);
SendNotAck();
I2CStop();
I2CStart();
I2CSendByte(address); //写
WaitAck();
I2CSendByte(0x03); //指向OTI存器
WaitAck();
I2CSendByte(a); //送温度高8位
WaitAck();
I2CSendByte((uchar)OTI); //送温度低8位
SendNotAck();
I2CStop();
I2CStart();
I2CSendByte(address); //写
WaitAck();
I2CSendByte(0x02); //指向HYST寄存器
WaitAck();
I2CSendByte(b); //送温度高8位
WaitAck();
I2CSendByte((uchar)HYST); //送温度低8位
SendNotAck();
I2CStop();
}
*/
void display(unsigned int n)
{
unsigned char bai,shi,ge;
n&=0x0fff;
// if(n>99)
// {
bai=n/100;
shi=(n-bai*100)/10;
ge=n%10;
P0=0xFB;
P1=wei[bai];
Delay(255);
P0=0xFD;
P1=wei[shi]&0x7f;
Delay(255);
P0=0xFE;
P1=wei[ge];
Delay(255);
// }
/* else if(n>9)
{
shi=n/10;
ge=n%10;
P0=0xFD;
P1=wei[shi]&0x7f;
Delay(10);
P0=0xFE;
P1=wei[ge];
Delay(10);
}
else
{
P0=0xFE;
P1=wei[n];
Delay(10);
}
*/
}
void main()
{
// uchar i;
TMOD=0x01;
TH0=0x02;TL0=0x18;
TR0=1;
Delay(100);
Delay(100);
while(1)
{
while(!TF0);
{
Read(0x90);
TR0=0;
TH0=0x02;TL0=0x18;
Delay(100);
}
// Delay(100);
display(Temperature);
}
}
adt75.rar_1-wire_adt 75 i2c_adt75_adt每摄氏度_温度传感器
版权申诉
189 浏览量
2022-09-21
05:10:25
上传
评论 1
收藏 3KB RAR 举报
JonSco
- 粉丝: 70
- 资源: 1万+