小弟用的是STC89C52单片机,DS18B20传感器...做测温体统~但由于C语言代码的问题,特来求助各位!!!代码在最下面,按照原理图,希望各位大哥给加点针对这个点哭显示温度的代码。由于C语言的有限,拜托各位了!!
代码如下----------------------------------------------------------------------
#include
#include
unsigned char DA0[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x00,0xff}; //第0位数码管对应的编码
unsigned char DA1[12]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x00,0xff}; //第1位数码管对应的编码
unsigned char showcount=0; //显示计数
unsigned int Tempture=0; //保存当前温度的变量
unsigned char TempBuf=0; //按键码对应的缓冲区空间
unsigned char ScanCount=0; //键盘扫描对应的扫描次数
unsigned char DisBuf[3]={11,11,11}; //数码管显示区域
unsigned char BeepBufUp[3]={0,0,3}; //报警对应的上限值,初始为30.0度
unsigned char BeepBufDown[3]={0,0,1}; //报警对应的下限值,初始为10.0度
unsigned char DisBufBit=0; //对当前操作的位置
sbit DQ =P2^7; //定义通信端口
sbit CLK=P1^5; //时钟信号输出端
sbit DATA=P1^3; //数据输出
sbit KEY0=P2^0; //以下为四个键所对应的管脚
sbit KEY1=P2^1;
sbit KEY2=P2^2;
sbit KEY3=P2^3;
sbit BEEP=P2^4; //峰鸣器对应的开关键
sbit CONUP=P2^5; //超出上限值时的开关
sbit CONDOWN=P2^6; //低于下限温度值时的开关
bit TempShowFlag=0; //温度显示标志位
bit KeyPushFlag=0; //键盘有按下标志位
bit BlinkFlag=0; //闪动标志位
bit KeyPushDeal=1; //键盘命令处理与否标志位
bit KeyDownPushFlag=0; //有设置下限温度键按下
bit KeyUpPushFlag=0; //有设置上限温度键按下
#define COMMANDENTER1 0X03 //四个按键对应的编码值信息
#define COMMANDUP 0X02
#define COMMANDDOWN 0X01
#define COMMANDENTER2 0X00
#define BeepOn() BEEP=0 //打开蜂鸣器开关
#define BeepOff() BEEP=1 //关闭蜂鸣器开关
#define up() {CLK=0;CLK=1; } //产生一个正脉冲
#define OnConUp() CONUP=1; //打开上限温度的开关
#define OffConUp() CONUP=0; //关闭上限温度的开关
#define OnConDown() CONDOWN=1; //打开下限温度开关
#define OffConDown() CONDOWN=0; //关闭下限温度开关
//延时函数
void delay(unsigned int i) //延时程序,大约为1时延时15US,2时为20US
{
while(i--);
}
//初始化函数
void INITDS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //将DQ拉低
delay(80); //保持大于 480us
DQ = 1; //拉高总线
delay(14); //延时处理
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(20);
}
//读一个字节
unsigned char ReadOneChar(void)
{
unsigned char i=0; //用来作计数用
unsigned char dat = 0; //存放读取到的数
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay(4); //两次读出的数的间隔要大于60US
}
return(dat);
}
//写一个字节
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0; //拉低总线
DQ = dat&0x01; //阖家写入的数
delay(5); //使延时大于45US
DQ = 1; //拉高总线
dat>>=1; //下一个字符
}
}
//读取当前的温度
unsigned int ReadTemperature(void)
{ //对于初始化的操作,在每一次的读或写操作都要进行初始化
unsigned char a=0; //读取温度的低位数据
unsigned char b=0; //读取温度的高位数值
unsigned int t=0; //最终得到的温度值
float temp=0; //用于温度计算的变量
INITDS18B20(); //启动初始化操作
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
INITDS18B20(); //读数前初始化操作
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //读取低字节的温度
b=ReadOneChar(); //读取温度的高字节
t=b;
t<<=8;
t+=a; //把高字节移到高位上
//t=t|a; //把低字节放到低位上
temp=t*0.0625; //使小数点移到最后
t=(unsigned int)(temp*100+0.5); //对结果进行4舍5入,t为一个一位数或是两位数的操作
return(t);
}
//显示子程序,对数码进行操作,一次为显示一个字节的数据
void show(unsigned char Data)
{
unsigned char i,a;
for(i=0;i<8;i++)
{
a= Data & 0x80;
if(a==0)
{
DATA=0;
up();
}
else
{
DATA=1;
up();
}
Data<<=1;
}
}
//输出到数码管区域
void DisReflash()
{
EA=0; //断开当前的中断,使显示无中断
show(DA0[DisBuf[0]]);
show(DA1[DisBuf[1]]);
show(DA0[DisBuf[2]]);
EA=1;
}
void Init()
{
TMOD=0X11; //以方式1进行显示与扫描
TH0=0X3c;
TL0=0Xb5;
TH1=0X4C;
TL1=0X04;
EA=1; //初始化各个中断标志位
ET0=1;
ET1=1;
ES=0;
TR0=1;
TR1=1;
KEY0=1;
KEY1=1;
KEY2=1;
KEY3=1;
DisReflash(); //刷新显示空间
BeepOff(); //正常范围里,关闭蜂鸣器
OffConUp(); //关闭上限温度的开关
OffConDown(); //关闭下限温度的开关
}
void JudgeTempture()
{
if((DisBuf[2]*100+DisBuf[1]*10+DisBuf[0])>=(BeepBufUp[2]*100+BeepBufUp[1]*10+BeepBufUp[0])) //大于上限值
{
BeepOn(); //打开蜂鸣器
OnConUp(); //打开上限温度的开关
OffConDown(); //关闭下限温度的开关
}
else if((DisBuf[2]*100+DisBuf[1]*10+DisBuf[0])<=(BeepBufDown[2]*100+BeepBufDown[1]*10+BeepBufDown[0])) //小于下限值
{
BeepOn(); //打开蜂鸣器
OnConDown(); //打开下限温度的开关
OffConUp(); //关闭上限温度的开关
}
else
{
BeepOff(); //正常范围里,关闭蜂鸣器
OffConUp(); //关闭上限温度的开关
OffConDown(); //关闭下限温度的开关
}
}
//中断处理子程序1
void ServiceT0(void) interrupt 1 using 2
{
unsigned int Temp[3]={0,0,0}; //临时变量,用来保存信息,防止丢失数据
TR0=0; //每隔0.05s进行一个刷新显示操作
TH0=0X3d;
TL0=0X32;
TR0=1;
showcount++;
if(showcount==6) //0.3秒时间
{
showcount=0;
ET0=0; //屏蔽中断
ET1=0;
if(KeyPushFlag==0) //当前没有键按下
JudgeTempture(); //启动扫描开关
else
{
OffConUp(); //有键按下时关闭所有的开关
OffConDown();
BeepOff();
}
Temp[0]=DisBuf[0]; //保存数据
Temp[1]=DisBuf[1];
Temp[2]=DisBuf[2];
if(KeyPushFlag==1 && BlinkFlag==0) //有按键按下时,为一闪一闪的状态
{
BlinkFlag=1; //闪动--亮
TempShowFlag=1;
}
else if(KeyPushFlag==1 && BlinkFlag==1)
{
BlinkFlag=0; //闪动--灭
DisBuf[DisBufBit-1]=11;
TempShowFlag=1; //闪动标志位
}
if(TempShowFlag==1) //可以对当前的进行刷新操作
{
DisReflash();
TempShowFlag=0;
}
DisBuf[0]=Temp[0]; //恢复数据
DisBuf[1]=Temp[1];
DisBuf[2]=Temp[2];
ET0=1; //开中断
ET1=1;
}
}
//检查当前的四个键有无按下
bit CheckButton()
{
if(!(KEY0 && KEY1 && KEY2 && KEY3)) {return 1;}
else return 0;
}
//键盘扫描处理程序,每隔0。3秒左右扫描一次,中间使用了查询方式来等待结束
void ServiceT1(void) interrupt 3 using 3
{
TH1=0X00;
TL1=0X00;
ScanCount++;
if(ScanCount==3)
{
ScanCount=0;
if(CheckButton() && KeyPushDeal==1)
{
TR1=0;
if(!KEY0) {TempBuf=COMMANDENTER2;} //读出各个按键对应的编码值
else if(!KEY1) TempBuf=COMMANDDOWN;
else if(!KEY2) TempBuf=COMMANDUP;
else TempBuf=COMMANDENTER1;
while(!(KEY0 && KEY1 && KEY2 && KEY3)) { ;} //等待结束
KeyPushDeal=0; //表示还没有处理当前的按键信息
KeyPushFlag=1; //按键按下的标志位置1
}
}
}
//按键命令处理程序
void CommandDeal()
{
switch(TempBuf)
{ //对应为四个按键对应的命令操作
case COMMANDENTER1:
if(KeyUpPushFlag==1) break;
KeyDownPushFlag=1; //设置下限温度键按下
DisBufBit++; //三次按确认键后退出当前的操作,表示确认了当前的输入
if(DisBufBit==1)
{
DisBuf[0]=BeepBufDown[0];
DisBuf[1]=BeepBufDown[1];
DisBuf[2]=BeepBufDown[2];
}
if(DisBufBit==4 && TempShowFlag==0)
{ DisBufBit=0;
BeepBufDown[0]=DisBuf[0];
BeepBufDown[1]=DisBuf[1];
BeepBufDown[2]=DisBuf[2];
KeyPushFlag=0;
KeyDownPushFlag=0; //清除下限温度标志位
}
break;
case COMMANDUP : DisBuf[DisBufBit-1]=(DisBuf[DisBufBit-1]+1)%10; break;
case COMMANDDOWN: DisBuf[DisBufBit-1]=(DisBuf[DisBufBit-1]-1+10)%10;break;
case COMMANDENTER2:
if(KeyDownPushFlag==1) break;
KeyUpPushFlag=1;
DisBufBit++; //三次按确认键后退出当前的操作,表示确认了当前的输入
if(DisBufBit==1)
{
DisBuf[0]=BeepBufUp[0];
DisBuf[1]=BeepBufUp[1];
DisBuf[2]=BeepBufUp[2];
}
if(DisBufBit==4 && TempShowFlag==0) //等待刷新完成
{ DisBufBit=0;
BeepBufUp[0]=DisBuf[0];
BeepBufUp[1]=DisBuf[1];
BeepBufUp[2]=DisBuf[2];
KeyPushFlag=0;
KeyUpPushFlag=0;
}
break;
}
TempShowFlag=1; //要刷新显示区
TR1=1; //开启扫描键盘
}
//主函数,只是一个循环,为查看键盘与显示的状态
void main()
{
unsigned int i=0; //读取温度的值
Init();
while(1)
{
if(TempShowFlag==0 && KeyPushFlag==0) //要显示的为当前的温度值
{
ET0=0; //关中断1
Tempture=ReadTemperature();
DisBuf[0]=(Tempture/10)%10; //有两位小数
DisBuf[1]=(Tempture/100)%10;
DisBuf[2]=(Tempture/1000)%10;
ET0=1;
TempShowFlag=1;
}
if(KeyPushFlag==1 && KeyPushDeal==0) //有键按下,处理按键
{
CommandDeal();
KeyPushDeal=1;
}
}
}