当前位置:文档之家› 51单片机热敏电阻测温程序

51单片机热敏电阻测温程序

//本程序是通过热敏电阻测温度(30c-50c),采用六位串行数码管显示,前三位显示ds18b20测得数据,后三位是热敏电阻测得数据
#include<reg51.h>
#include<math.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar smg[]={0x88,0xeb,0x4c,0x49,0x2b,0x19,0x18,0xcb,0x08,0x09};
uchar b,d;
uint shuju;
int a,temp;
sbit start=P2^7;
sbit ale=P2^7;
sbit addc=P2^6;
sbit addb=P2^5;
sbit adda=P2^4;
sbit eoc=P2^3;
sbit oe=P2^2;
sbit clk=P3^2;//0809时钟脚
sbit dat=P3^0; //串行数码管数据端
sbit clock=P3^1; //串行数码管时钟端
sbit DQ=P2^0;
/******************delay**************************/
void delay(uint x)
{
while(x--);
}
void delay1(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<110;j++);
}
/*******************ds18b20***********************/
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);
}
/******************************从18B20中读一个字节****************************/ uchar Read_OneChar(void)
{
uchar i = 0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat >>= 1;
DQ = 1; // 给脉冲信号
if(DQ)
dat |= 0x80;
delay(8);
}
return(dat);
}
/******************************向18B20中写一个字节****************************/ void Write_OneChar(uchar dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(10);
DQ = 1;
dat >>= 1;
}
delay(8);
}
/***********************************读取温度**********************************/ uchar Read_Temperature(void)
{
uchar i = 0,t = 0;
Init_DS18B20();
Write_OneChar(0xcc); // 跳过读序号列号的操作
Write_OneChar(0x44); // 启动温度转换
Init_DS18B20();
Write_OneChar(0xcc); //跳过读序号列号的操作
Write_OneChar(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度
i = Read_OneChar(); //读取温度值低位
t = Read_OneChar(); //读取温度值高位
b = t;
d = 0x88;
/* if(b&0x80==0x80) //显示负数
{
t = ~t;
// t += 1;
i = ~i;
i += 1;
d = 0xbf;
} */
a = i & 0x0f;
i = i >> 4; //低位右移4位,舍弃小数部分
t = t << 4; //高位左移4位,舍弃符号位
t = t | i;
if(t>=100)
d=smg[t/100%10];
return(t);
}
/******************串行发送显示******************/ void send(uchar x)
{
uchar temp,i;
temp=x;
for(i=0;i<8;i++)
{
temp=temp<<1;
clock=0;
dat=CY;
clock=1;
}
}
void send1(uchar x)
{
uchar temp,i;
temp=x&0xf7;
for(i=0;i<8;i++)
{
temp=temp<<1;
clock=0;
dat=CY;
clock=1;
}
}
/******************adc0809***************************/
void adc0809()
{
start=0;
start=1;
_nop_();
start=0;
while(eoc==0);
oe=1;
shuju=P0;
oe=0;
shuju=shuju*1.96079;
if(shuju<=445&&shuju>=437)
shuju=((445-shuju)/2+30)*10;
else if(shuju<437&&shuju>=427) //if语句主要是通过采集30-50c之间的数据,看出热敏电阻两端电压与温度之间关系,
shuju=((445-shuju)/2+29)*10; //我把这些数据通过微分方法分成四段,然后在每段近视看成线性关系,最后算出温度
else if(shuju<427&&shuju>=317)
shuju=((445-shuju)/2+28)*10;
else if(shuju<417&&shuju>=407)
shuju=((445-shuju)/2+27)*10;
else if(shuju<407&&shuju>=397)
shuju=((445-shuju)/2+25)*10;
else if(shuju<497&&shuju>=387)
shuju=((445-shuju)/2+23)*10;
send(smg[shuju%10]);
send1(smg[shuju/10%10]);
send(smg[shuju/100%10]);
send(smg[a*10/16]);
send1(smg[temp%10]);
send(smg[temp/10%10]);
delay1(1000);
}
/******************中断***************************/
void timer_init()
{
TMOD=0x01;
TH0=(65536-200)/256;
TL0=(65536-200)%256;
TR0=1;
ET0=1;
EA=1;
}
void timer() interrupt 1
{
TR0=0;
TH0=(65536-200)/256;
TL0=(65536-200)%256;
clk=~clk;
TR0=1;
}
/******************main****************************/ void main()
{
addc=0;
addb=0;
adda=0;
// ale=1;
timer_init();
while(1)
{
temp=Read_Temperature();
adc0809();
}
}。

相关主题