温度值通过串口助手得到,但是串口助手上一直显示FE或者FF,也不会随温度变化,请高手指导下
#include <STC12C5A60S2.H> //单片机头文件
#include <intrins.h> //51基本运算(包括_nop_空函数)
sbit DQ=P0^0;
unsigned char tem[5]={0};
void delay_us(unsigned char times)
{
unsigned char i=times;
for(;i>0;i--) _nop_();
}
void delay1ms(unsigned int t) //误差 -0.018084490741us
{
unsigned char a,b;
unsigned int j;
for(j=t;j>0;j--)
for(b=21;b>0;b--)
for(a=130;a>0;a--);
}
void Init_serial()
{
SCON=0x50;//串口1工作方式1
AUXR|=0x40; //Timer1 speed 12 of MCU
AUXR&=0xFE;//use T1 as baud sender
TMOD=0x20;
TL1 = 0xF7;//设定定时初值
TH1 = 0xF7;//设定定时器重装值
//ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
//ES = 1; //允许串行中断
//EADC=1;
//EA=1; //开总中断
IE=0xA0;
}
void SendData(unsigned char dat)
{
SBUF = dat;
while (!TI);
TI = 0;
}
void Send_String(unsigned char *p)
{
unsigned char i;
for(i=0;i<5;i++)
{
SendData(*p++);
}
}
//DS18B20复位
void DS18B20_Reset()
{
bit presence=1;
while(presence)
{
delay_us(2);
DQ=0;
delay_us(480);
DQ=1; //DQ=1表示释放总线
delay_us(50);
if(!DQ) presence=0;
delay_us(430);
}
}
//写DS18B20数据线从高到低写时序开始
void DS18B20_Write(unsigned char wDate)
{
unsigned int i;
for(i=0;i<8;i++)
{
DQ=0;
delay_us(1);
DQ=wDate&0x01; //将数据的最低位传到数据总线DQ
delay_us(60);
DQ=1; //释放总线
delay_us(1);
wDate=wDate>>1;
}
}
//读ds18b20
unsigned char DS18B20_Read()
{
unsigned char j,Dat=0;
for(j=0;j<8;j++)
{
Dat>>=1;
DQ=0;
delay_us(1);
DQ=1;
delay_us(6);
if(DQ) Dat|=0x80;
delay_us(60);
}
return (Dat);
}
void Get_Temp()
{
/*12位转化后得到的12位数据存储在18B20的两个8比特的RAM中,二进制中的前面5位是符
号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625 即可得到实际温度;
如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。 */
unsigned char i,temp_date;
unsigned int wendu;
unsigned char temp[1]={0};
float tt;
DQ=1;
DS18B20_Reset();
DS18B20_Write(0xCC); //忽略ds18b20的ROM检查
DS18B20_Write(0x44); //开始温度转换
//delay_us(500);
DS18B20_Reset(); //再复位依次,ds18b20每次操作必须先复位下
DS18B20_Write(0xCC); //发送读数据指令
DS18B20_Write(0xBE); //发送读数据指令
for(i=0;i<2;i++) temp[i]=DS18B20_Read(); //开始读取数据
DS18B20_Reset(); //结束读取操作
temp_date=temp[1];
temp_date&=0xf8;
if(temp_date==0xf8) //判断高5位是否为1 即温度是正是负
{
if(temp[0]==0)
{
temp[0]=~temp[0]+1;
temp[1]=~temp[1]+1;
}
else
{
temp[0]=~temp[0]+1;
temp[1]=~temp[1];
}
}
wendu=temp[1];
wendu<<=8;
wendu=wendu|temp[0];
tt=wendu*0.0625;
wendu=tt*10; //温度值放大十倍,因为我要测的温度为0-99度之间,如果要测超过99度可做适当改动
tem[0]=wendu/100+*0*; //取温度的十位
tem[1]=wendu%100/10+*0*; //去个位
tem[2]=*.*;
tem[3]=wendu%10+*0*;
tem[4]=*\n*;
Send_String(tem);
}
void main()
{
Init_serial();
while(1)
{
Get_Temp();
delay1ms(1000);
}
}
#include <STC12C5A60S2.H> //单片机头文件
#include <intrins.h> //51基本运算(包括_nop_空函数)
sbit DQ=P0^0;
unsigned char tem[5]={0};
void delay_us(unsigned char times)
{
unsigned char i=times;
for(;i>0;i--) _nop_();
}
void delay1ms(unsigned int t) //误差 -0.018084490741us
{
unsigned char a,b;
unsigned int j;
for(j=t;j>0;j--)
for(b=21;b>0;b--)
for(a=130;a>0;a--);
}
void Init_serial()
{
SCON=0x50;//串口1工作方式1
AUXR|=0x40; //Timer1 speed 12 of MCU
AUXR&=0xFE;//use T1 as baud sender
TMOD=0x20;
TL1 = 0xF7;//设定定时初值
TH1 = 0xF7;//设定定时器重装值
//ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
//ES = 1; //允许串行中断
//EADC=1;
//EA=1; //开总中断
IE=0xA0;
}
void SendData(unsigned char dat)
{
SBUF = dat;
while (!TI);
TI = 0;
}
void Send_String(unsigned char *p)
{
unsigned char i;
for(i=0;i<5;i++)
{
SendData(*p++);
}
}
//DS18B20复位
void DS18B20_Reset()
{
bit presence=1;
while(presence)
{
delay_us(2);
DQ=0;
delay_us(480);
DQ=1; //DQ=1表示释放总线
delay_us(50);
if(!DQ) presence=0;
delay_us(430);
}
}
//写DS18B20数据线从高到低写时序开始
void DS18B20_Write(unsigned char wDate)
{
unsigned int i;
for(i=0;i<8;i++)
{
DQ=0;
delay_us(1);
DQ=wDate&0x01; //将数据的最低位传到数据总线DQ
delay_us(60);
DQ=1; //释放总线
delay_us(1);
wDate=wDate>>1;
}
}
//读ds18b20
unsigned char DS18B20_Read()
{
unsigned char j,Dat=0;
for(j=0;j<8;j++)
{
Dat>>=1;
DQ=0;
delay_us(1);
DQ=1;
delay_us(6);
if(DQ) Dat|=0x80;
delay_us(60);
}
return (Dat);
}
void Get_Temp()
{
/*12位转化后得到的12位数据存储在18B20的两个8比特的RAM中,二进制中的前面5位是符
号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625 即可得到实际温度;
如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。 */
unsigned char i,temp_date;
unsigned int wendu;
unsigned char temp[1]={0};
float tt;
DQ=1;
DS18B20_Reset();
DS18B20_Write(0xCC); //忽略ds18b20的ROM检查
DS18B20_Write(0x44); //开始温度转换
//delay_us(500);
DS18B20_Reset(); //再复位依次,ds18b20每次操作必须先复位下
DS18B20_Write(0xCC); //发送读数据指令
DS18B20_Write(0xBE); //发送读数据指令
for(i=0;i<2;i++) temp[i]=DS18B20_Read(); //开始读取数据
DS18B20_Reset(); //结束读取操作
temp_date=temp[1];
temp_date&=0xf8;
if(temp_date==0xf8) //判断高5位是否为1 即温度是正是负
{
if(temp[0]==0)
{
temp[0]=~temp[0]+1;
temp[1]=~temp[1]+1;
}
else
{
temp[0]=~temp[0]+1;
temp[1]=~temp[1];
}
}
wendu=temp[1];
wendu<<=8;
wendu=wendu|temp[0];
tt=wendu*0.0625;
wendu=tt*10; //温度值放大十倍,因为我要测的温度为0-99度之间,如果要测超过99度可做适当改动
tem[0]=wendu/100+*0*; //取温度的十位
tem[1]=wendu%100/10+*0*; //去个位
tem[2]=*.*;
tem[3]=wendu%10+*0*;
tem[4]=*\n*;
Send_String(tem);
}
void main()
{
Init_serial();
while(1)
{
Get_Temp();
delay1ms(1000);
}
}