//任务:实现对温度传感器件DS18B20的温度值得读取,并把温度值发送到上位机labview处理
#include <reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ =P3^6; //定义DS18B20通信端口
uchar flag=0;
code uchar table[]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90, //0~9的段码
0x40,0x79,0x24,0x30,0x19,
0x12,0x02,0x78,0x00,0x10, //带小数点0~9的段码
0xbf,0xff}; //"-"和"全灭"的段码
//uchar pc_command; //只要PC有发过来0x0a过来就算是告诉单片机启动发送指令
uchar flag; //正负号标志
void delay(unsigned int i) //延时函数
{
while(i--);
}
//显示程序
void display(uchar bit_count,uchar dat)
{
P2=0x00;
P0=table[dat];
P2=(0x01)<<bit_count;
delay(500);
}
void dis_Temperature(uint t)
{
uchar i;
if(flag==1)
{i=20;}
else
{i=21;}
display(0,i);
i=t/100;
display(1,i);
i=t%100/10;
display(2,i+10);
i=t%100%10;
display(3,i);
}
void Init_DS18B20(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);
}
uchar Read(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);
}
return(dat);
}
void Write(unsigned char dat) //写一个字节
{
unsigned char i;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
delay(4);
}
uint ReadTemperature(void) //读取温度
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float f_t=0;
Init_DS18B20();
Write(0xCC); // 跳过读序号列号的操作
Write(0x44); // 启动温度转换
Init_DS18B20();
Write(0xCC); //跳过读序号列号的操作
Write(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=Read();
b=Read();
if(b<127)
{
t=b;t<<=8;t=t|a;
flag=0;
}
else
{
a=~a;b=~b;
t=b;t<<=8;t=t|a;t=t+1;
flag=1;
}
f_t=t*0.0625; //温度值在寄存器中为11位,分辨率为0.0625
t=f_t*10+0.5; //乘以10表示小数点后面只取1位,加0.5是四舍五入
return(t);
}
void serial_int()
{
//设置定时器1的工作方式为方式2
TMOD=0x20;
//设定定时器1的初值,使串口通讯的波特率为9600bps
TH1=0xfd;
TL1=0xfd;
SCON=0x50;
PCON=0x00;
ES=1;
EA=1;
TR1=1;
}
void com_send_byte(uchar onebyte)
{
ES = 0; //关串口中断
SBUF = onebyte; //把要发送的数据写入SBUF,单片机会自动发送该数据,需要一段时间
while (TI == 0); //等待发送结束
TI = 0; //把发送标志清零
ES=1;
}
/* 当有数据发送到单片机时,会执行以下中断服务函数*/
void uart_int(void) interrupt 4 using 3
{
uchar tmpData;
if (RI == 1) /* 判断是不是接收中断*/
{
RI = 0; /* 清串口接收中断 */
tmpData = SBUF; /* 读取接收到的数据*/
//P0 = LED_TAB[temp];
flag = 1;
if(tmpData == 1) //加热
{
//P1 = 0xf0;
P1 = 0x10;
}
if(tmpData == 3) //加热
{
P1 = 0x30;
}
if(tmpData == 4) //加热
{
P1 = 0x70;
}
else if(tmpData == 2) //正转
{
P1 = 0x09;
}
else
{
P1 = 0x0a;
}
}
}
main()
{
uint Temperature;
uchar Temp_highbyte,Temp_lowbyte;
serial_int();
while(1)
{
Temperature=ReadTemperature();
dis_Temperature(Temperature);
Temp_highbyte=Temperature/256;
Temp_lowbyte=Temperature%256;
com_send_byte(flag);//发送三个字节
com_send_byte(Temp_highbyte);//发送实际温度值乘以10后的整型数据的高字节
com_send_byte(Temp_lowbyte);//发送实际温度值乘以10后的整型数据的低字节
}
}
评论0
最新资源