📄 18b20.c.bak
字号:
#include <intrins.h>
#include <reg52.h>
#define Uchar unsigned char
#define Uint unsigned int
#define SomeNOP(); _nop_();
sbit DQ = P3^7; //18B20温度传感器
sbit JDQ = P3^6; //继电器输出
//LCD1602的口线接法
sbit E=P2^2;
sbit RW=P2^1;
sbit RS=P2^0;
/*I2C总线要用到的口线定义*/
sbit SDA = P3^4;
sbit SCL = P3^3;
//以下为函数声明
void TempDelay(unsigned char us);
void Ds18b20_rst(void);
void WriteByte(unsigned char wrdat);
unsigned char ReadByte(void);
void Delay(unsigned int t); // delay 40us
void SendCommandByte(unsigned char ch);
void SendDataByte(unsigned char ch);
void InitLcd();
//I2C驱动要用到的一些函数
void Delay_1ms(Uchar time);
void I2CStart(void);
void I2CStop(void);
void AutoACK(void); //在一定的时间内自动确定ACK的信号//
void Writex(Uchar j);
Uchar Readx(void);
void X24_Write(Uchar Addresslow,Uchar Write_date);
Uchar X24_Read(Uchar Addresslow);
void ramini(void);
void time0(void);
union
{
unsigned int iInt;
unsigned char cChar[2];
}TMP;
unsigned int nowwd,highwd; //当前的温度,设定报警
unsigned char keyscan,teml,temh;
unsigned char dssttime,svtime;
unsigned char bdata myflag1;
sbit keybit = myflag1^0; //按键标志
sbit dsokbit = myflag1^1; //DS18B20在线
sbit dsstbit = myflag1^2;
sbit dsfubit = myflag1^3;
sbit newwdbit = myflag1^4;
sbit newjrbit = myflag1^5;
sbit setjrbit = myflag1^6;
void main(void)
{
TH0=0xf8;
TL0=0xce;
TMOD=0x01;
TR0=1;
keyscan=50;
InitLcd();
ramini();
SendCommandByte(0x80); //设置DDRAM地址
SendDataByte('T');
SendDataByte('e');
SendDataByte('m');
SendDataByte('p');
SendDataByte(':');
SendCommandByte(0xC0); //设置DDRAM地址
SendDataByte('S');
SendDataByte('e');
SendDataByte('t');
SendDataByte(' ');
SendDataByte(':');
IE=0x82;
newjrbit=1;
while(1){}
}
void time0(void) interrupt 1
{
unsigned char k,p;
TH0=0xf8; //2ms
TL0=0xce;
if(keyscan--==0)
{
keyscan=50;
k=P1;k=k&0x03;
if(k!=0x03)
{
switch(k)
{
case 0x02:
if(keybit==0){keybit=1;highwd++;setjrbit=1;svtime=30;newjrbit=1;}break;
case 0x01:
if(keybit==0){keybit=1;highwd--;setjrbit=1;svtime=30;newjrbit=1;}break;
}
}
else{keybit=0;}
if(setjrbit==1)
{
if(svtime--==0)
{
TMP.iInt=highwd;
X24_Write(0x10,TMP.cChar[0]);
X24_Write(0x11,TMP.cChar[1]);
setjrbit=0;
}
}
if(dsstbit==0) //采集温度值
{
Ds18b20_rst();
if(dsokbit==1)
{
WriteByte(0xCC); //忽略ROM匹配
WriteByte(0x44); //发送温度转化命令
dsstbit=1;dssttime=0x07;
}
}
else
{
if(dssttime--==0)
{
Ds18b20_rst();
if(dsokbit==1)
{
WriteByte(0xCC);
WriteByte(0xBE);
teml=ReadByte();
temh=ReadByte();
k=temh&0xfc;
if(k!=0xfc)
{
k=(temh<<4)&0xf0;p=(teml>>4)&0x0f;
k=k|p;
nowwd=k*10;
k=teml&0x0f;k=k*10;p=k/16;
if((k%16)>5){p=p+1;}
nowwd=nowwd+p;
dsstbit=0;dsfubit=0;
}
else
{
k=(temh<<4)&0xf0;p=(teml>>4)&0x0f;
k=k|p;
k=(~k);
nowwd=k*10;
k=(teml&0x0f)|0xf0;k=~k;k=k*10;p=k/16;
if((k%16)>5){p=p+1;}
nowwd=nowwd+p;
dsstbit=0;dsfubit=1;
}
newwdbit=1;
}
}
}
}
if(newwdbit==1)
{
newwdbit=0;
if(nowwd<highwd){JDQ=0;}else{JDQ=1;}
SendCommandByte(0x87); //设置DDRAM地址
k=(Uchar)(nowwd/1000);
k=k+0x30;
SendDataByte(k);
k=(Uchar)((nowwd%1000)/100);
k=k+0x30;
SendDataByte(k);
k=(Uchar)((nowwd%100)/10);
k=k+0x30;
SendDataByte(k);
SendDataByte('.');
k=(Uchar)(nowwd%10);
k=k+0x30;
SendDataByte(k);
}
if(newjrbit==1)
{
newjrbit=0;
SendCommandByte(0xc7); //设置DDRAM地址
k=(Uchar)(highwd/1000);
k=k+0x30;
SendDataByte(k);
k=(Uchar)((highwd%1000)/100);
k=k+0x30;
SendDataByte(k);
k=(Uchar)((highwd%100)/10);
k=k+0x30;
SendDataByte(k);
SendDataByte('.');
k=(Uchar)(highwd%10);
k=k+0x30;
SendDataByte(k);
}
}
//18B20要用到的一些函数
void TempDelay(unsigned char us) //延时
{
while(us--);
}
void Ds18b20_rst(void) //18B20复位
{
DQ=1;
_nop_();
DQ=0;
TempDelay(86);
_nop_();
DQ=1;
TempDelay(14);
_nop_();
_nop_();
_nop_();
if(DQ==0){dsokbit=1;}
else{dsokbit=0;}
TempDelay(20);
_nop_();
_nop_();
DQ=1;
}
void WriteByte(unsigned char wrdat) //向18B20写入一字节
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ=0;
_nop_();
DQ=wrdat&0x01;
TempDelay(5);
_nop_();
_nop_();
DQ=1;
wrdat>>=1;
}
}
unsigned char ReadByte(void) //读18B20的一个字节
{
unsigned char i,u=0;
for(i=0;i<8;i++)
{
DQ=0;
u>>=1;
DQ=1;
if(DQ==1)
u|=0x80;
TempDelay(4);
_nop_();
}
return(u);
}
//-------------------------------------
void Delay(unsigned int t) // delay 40us
{
for(;t!=0;t--) ;
}
//=============================================
void SendCommandByte(unsigned char ch)
{
RS=0;
RW=0;
P0=ch;
E=1;
Delay(1);
E=0;
Delay(100); //delay 40us
}
//-------------------------------------------------------
void SendDataByte(unsigned char ch)
{ RS=1;
RW=0;
P0=ch;
E=1;
Delay(1);
E=0;
Delay(100); //delay 40us
}
//-------------------------------------------------
void InitLcd()
{SendCommandByte(0x30);
SendCommandByte(0x30);
SendCommandByte(0x30);
SendCommandByte(0x38); //设置工作方式
SendCommandByte(0x0c); //显示状态设置
SendCommandByte(0x01); //清屏
SendCommandByte(0x06); //输入方式设置
}
/*----------------------I2C要用到的一些子程序---------------------------------*/
/***********************以下为一些用到的子程序*********************************/
/*延时子程序*/
void Delay_1ms(Uchar time)
{
Uchar j;
while(time--)
{
for(j=163;j!=0;j--)
{;}
}
}
/*I2C的起动程序*/
void I2CStart(void)
{
SDA = 1;
SomeNOP();
SCL = 1;
SomeNOP();
SDA = 0;
SomeNOP();
SCL = 0;
SomeNOP();
}
/*I2C的停止程序*/
void I2CStop(void)
{
SDA = 0;
SomeNOP();
SCL = 1;
SomeNOP();
SDA = 1;
SomeNOP();
}
/*
void I2CACK(void) //Acknowledge信号
{
SDA = 0;
SomeNOP();
SCL = 1;
SomeNOP();
SCL = 0;
SomeNOP();
}
void I2CNACK(void) //没有Acknowledge信号
{
SDA = 1;
SomeNOP();
SCL = 1;
SomeNOP();
SCL = 0;
SomeNOP();
}
*/
void AutoACK(void) //在一定的时间内自动确定ACK的信号//
{
Uchar i = 0;
SCL = 1;
SomeNOP();
while((SDA == 1)&&(i<255))i++;
SCL = 0;
SomeNOP();
}
/*I2C写数据程序(向数据线上写一个BYTE)*/
void Writex(Uchar j)
{
Uchar i,temp;
temp = j;
for (i=0;i<8;i++) //串行移位,先送高位,再送低位//
{
temp =temp<<1;
SCL = 0;
SomeNOP();
SDA = CY;
SomeNOP();
SCL = 1;
SomeNOP();
}
SCL = 0;
SomeNOP();
SDA = 1;
SomeNOP();
}
/*I2C读数据程序(从数据线上读出一个BYTE)返回值为读出的数据(BYTE型)*/
Uchar Readx(void)
{
Uchar i,j,k=0;
SCL = 0;
SomeNOP();
SDA = 1;
for (i=0;i<8;i++) // 串行移位,先读出高位,后读出低位//
{
SomeNOP();
SCL = 1;
SomeNOP();
if(SDA ==1) j=1;
else j=0;
k =(k<<1)|j;
SCL = 0;
}
SomeNOP();
return(k); //返回读出的值//
}
//******************以下为对24CXX系列的读写程序******************************//
//*************24CXX的device address 为写0A0H,读为0A1H*********************//
/*某个地址写数据*/
void X24_Write(Uchar Addresslow,Uchar Write_date)
{
I2CStart();
Writex(0xA0);
AutoACK();
Writex(Addresslow);
AutoACK();
Writex(Write_date);
AutoACK();
I2CStop();
Delay_1ms(10);
}
/*对某个地址读操作,函数值为读出的数据*/
Uchar X24_Read(Uchar Addresslow)
{
Uchar i;
I2CStart();
Writex(0xA0);
AutoACK();
Writex(Addresslow);
AutoACK();
I2CStart();
Writex(0xA1);
AutoACK();
i =Readx();
//ACK(); //注意:这里不能有ACK应答信号//
I2CStop();
Delay_1ms(0);
return(i);
}
/*对内存中的数据块写入,入口为写EEPROM的地址,内存缓冲中的数据的起始地址(是IDATA的数据)*/
/*
void X24_WritePage(Uchar Addresshigh,Uchar Addresslow,Uchar idata *Writeip)
{
Uchar i;
I2CStart();
Writex(0xA0);
AutoACK();
Writex(Addresshigh);
AutoACK();
Writex(Addresslow);
AutoACK();
for(i=0;i<16;i++)
{
Writex(*Writeip++);
AutoACK();
}
I2CStop();
}
*/
/*把EEPROM中的数据读出来存放在内存缓冲中,起始地址为(是IDATA的数据)*/
/*
void X24_ReadPage(Uchar Addresshigh,Uchar Addresslow,Uchar idata *Readip)
{
Uchar i;
I2CStart();
Writex(0xA0);
AutoACK();
Writex(Addresshigh);
AutoACK();
Writex(Addresslow);
AutoACK();
I2CStart();
Writex(0xA1);
AutoACK();
for(i=0;i<16;i++) //PAGE读的时候最后一个BYTE不要ACK信号//
{
*Readip = Readx();
Readip = Readip++;
I2CACK();
}
*Readip = Readx();
I2CNACK();
I2CStop();
Delay_1ms(0);
}
*/
void ramini(void)
{
TMP.cChar[0]=X24_Read(0x10);
TMP.cChar[1]=X24_Read(0x11);
highwd=TMP.iInt;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -