📄 temperature.c
字号:
/***********************************************************************************
**模块名称:实时温度计
**创建人:陈华伟
**日 期:6月9日
**修改人:
**日 期:
**功能描述: 显示当前温度,并每隔一个小时保存一次当时温度,保存的数据可以用数码管显示
************也可以在超级终端里查询
**************************************************************************************/
#include "reg52.h"
#include "intrins.h"
#include "stdio.h"
#define uchar unsigned char
#define uint unsigned int
code unsigned char seg7code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90,0xff}; //共阳数码管段码
sbit DQ=P3^4; //数据传输线接单片机的相应的引脚
unsigned char tempL=0; //设全局变量
unsigned char tempH=0;
unsigned int sdata;//测量到的温度的整数部分
unsigned int xiaoshu1;//小数第一位
unsigned int xiaoshu2;//小数第二位
bit fg; //温度正负标志
uint us1,a,b,c,d,e;
uint suba,sum,rdat;
sbit SDA=P3^7;
sbit SCL=P3^6;
bit flag;
uint idata ucSendBuffer[1]=0;
uint idata ucReceData;
void ACK();
int hour,min,sec;
sbit P1_0=P1^0;
sbit P1_6=P1^6;
sbit P1_7=P1^7;
sbit P3_2=P3^2;
sbit P3_3=P3^3;
void inc_sec();
void inc_min();
void inc_hour();
/**************************************************************************************
**函数名:延时函数
**输 入:
**输 出:
***************************************************************************************/
void delay(unsigned char i)
{
for(i;i>0;i--);
}
void delay1(void)
{
uint i;
for(i=100;i>0;i--)
_nop_();
}
void delay2()
{
uchar j;
for(j=0;j<128;j++);
}
void delay3(uint j)
{
uchar i;
for(j;j>0;j--)
for(i=124;i>0;i--); //延时124*8+10=1002us
}
//*************************************以下为温度检测函数******************************
/**************************************************************************************
**函数名:Init_DS18B20()
**输 入:
**输 出:
**说 明:初始化程序
***************************************************************************************/
Init_DS18B20(void)
{
unsigned char x=0;
DQ=1; //DQ先置高
delay(8); //稍延时
DQ=0; //发送复位脉冲
delay(80); //延时(>480us)
DQ=1; //拉高数据线
delay(5); //等待(15~60us)
x=DQ; //用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1
delay(20);
}
/***************************************************************************************
**函数名:ReadOneChar()
**输 入:
**输 出:
**说 明:读一个字节
*****************************************************************************************/
ReadOneChar(void) //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
{
unsigned char i=0; //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期
unsigned char dat=0;
for (i=8;i>0;i--) //一个字节有8位
{
DQ=1;
delay(1);
DQ=0;
dat>>=1;
DQ=1;
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
}
/*****************************************************************************************
**函数名:WriteOneChar()
**输 入:
**输 出:
**说 明:写一个字节
******************************************************************************************/
WriteOneChar(unsigned char dat)
{
unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,
for(i=8;i>0;i--) //在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。
{
DQ=0; //在开始另一个写周期前必须有1us以上的高电平恢复期。
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
delay(4);
}
/*****************************************************************************************
**函数名:ReadTemperature(void)
**输 入:
**输 出:
**说 明:读温度值(低位放tempL;高位放tempH;)
******************************************************************************************/
ReadTemperature(void)
{
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳过读序列号的操作
WriteOneChar(0x44); //启动温度转换
delay(125); //转换需要一点时间,延时
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳过读序列号的操作
WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
tempL=ReadOneChar(); //读出温度的低位LSB
tempH=ReadOneChar(); //读出温度的高位MSB
if(tempH>0x7f) //最高位为1时温度是负
{
tempL=~tempL+1; //补码转换,取反加一
tempH=~tempH;
fg=0; //读取温度为负时fg=0
}
else fg=1;
sdata = tempL/16+tempH*16; //整数部分
xiaoshu1 = (tempL&0x0f)*10/16; //小数第一位
xiaoshu2 = (tempL&0x0f)*100/16%10;//小数第二位
}
//*********************以下为24c08运行函数**************************************************
/*******************************************************************************************
**名称:I2C_Start
**功能:启动I2C
**输入:无
**返回:无
********************************************************************************************/
void I2C_Start()
{
SDA=1;
delay1();
SCL=1;
delay1();
SDA=0;
delay1();
SCL=0; //钳位I2C总线,准备发送数据
}
/********************************************************************************************
**名称:I2C_Stop
**功能:停止I2C
**输入:无
**返回:无
**********************************************************************************************/
void I2C_Stop()
{
SDA=0;
delay1();
SCL=1;
delay1();
SDA=1;
delay1();
}
/*********************************************************************************************
**名称:Ack
**功能:应答信号
**输入:无
**返回:无
**********************************************************************************************/
void Ack()
{
SDA=0;
delay1();
SCL=1;
delay1();
SCL=0;
delay1();
SDA=1;
delay1();
}
/*********************************************************************************************
**名称:NoAck
**功能:发送非应答信号
**输入:无
**返回:无
**********************************************************************************************/
void NoAck()
{
SDA=1;
delay1();
SCL=1;
delay1();
SCL=0;
delay1();
SDA=0;
delay1();
}
/*********************************************************************************************
**名称:Test_Ack()
**功能:检测应答位
**输入:无
**返回:flag,有应答时flag为0,无应答时flag为1
**********************************************************************************************/
bit Test_Ack()
{
SCL=0;
SDA=1;//读入数据
_nop_();_nop_();_nop_();_nop_();
SCL=1;
_nop_();_nop_();_nop_();_nop_();
if(SDA==0)
flag=1;
else flag=0;
SCL=0;
return(flag);
}
/**********************************************************************************************
**名称:SendData()
**功能:发送一字节数据
**输入:buffer
**返回:
***********************************************************************************************/
void SendData(uint buffer)
{
uint BitCnt=8;//一字节8位
uint temp=0;
do
{
temp=buffer;
SCL=0;
delay1();
if((temp&0x80)==0) //判断最高位是0还是1
SDA=0;
else
SDA=1;
delay1();
SCL=1;
temp=_crol_(buffer,1);//将buffer中的数据左移一位
buffer=temp;
BitCnt--;
}
while(BitCnt);
SCL=0;
}
/***********************************************************************************************
**名称:uint ReceiveData()
**功能:接收一字节数据
**输入:
**返回:ucReceData
**说明:将接收的数据存放在ucReceData中
************************************************************************************************/
uint ReceiveData()
{
uint BitCnt=8;
uint temp=0;
SDA=1;//读入数据
do
{
SCL=0;
delay1();
SCL=1;
delay1();
if(SDA==1)
ucReceData=ucReceData|0x01; //低位置1
else
ucReceData=ucReceData&0x0fe; //低位清0
if(BitCnt-1)
{
temp=_crol_(ucReceData,1); //数据左移一位
ucReceData=temp;
}
BitCnt--;
}
while(BitCnt);
SCL=0;
return(ucReceData);
}
/************************************************************************************************
**名称:bit WriteNByte()
**功能:主机向24C02中写入多字节数据
**输入:
**返回:
**说明:sla-器件地址 suba-数据地址,*s-写入的数据,n-写入的字节数(n<=8)
*************************************************************************************************/
bit WriteNByte(uint sla,uint suba,uint *s,uint n)
{
uint i;
I2C_Start();//启动I2C
SendData(sla);//发送器件地址
Test_Ack();
if(flag==0) return(0);
SendData(suba);
Test_Ack();
if(flag==0) return(0);
for(i=0;i<n;i++)//写入8字节数据
{
SendData(*(s+i));
Test_Ack();
if(flag==0) return(0);
}
I2C_Stop();
return(1);
}
/*************************************************************************************************
**名称:bit ReadNByte()
**功能:主机从24C02中读出N字节数据(n<=8)
**输入:
**返回:
**说明:随机地址读操作
***************************************************************************************************/
bit ReadNByte(uint sla,uint suba,uint *p,uint n)
{
uint i;
I2C_Start();//启动I2C
SendData(sla);//发送器件地址
Test_Ack();
if(flag==0) return(0);
SendData(suba);//发送器件内部地址
Test_Ack();
if(flag==0) return(0);
I2C_Start();
SendData(sla+1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -