我现在做一个温度控制器,现在没有C程序。我 用的是AT89S52和DS18B20。谁能帮我设计个?

 我来答
在知识的田野上耕耘
2010-12-26
知道答主
回答量:6
采纳率:0%
帮助的人:1万
展开全部
好的,程序如下:
#include <REGX52.H>
#define uint unsigned int
#define ulong unsigned long
#define uchar unsigned char //宏定义
sbit DQ=P3^6 ; //定义DS18B20总线I/O
sbit SET=P3^1; //定义调整键
sbit DEC=P3^2; //定义减少键
sbit ADD=P3^3; //定义增加键
sbit BEEP=P3^7; //定义蜂鸣器
bit shanshuo_st; //闪烁间隔标志
bit beep_st; //蜂鸣器间隔标志
uchar x=0; //计数器
signed char m; //温度值全局变量
uchar n; //温度值全局变量
uchar set_st=0; //状态标志
uchar shangxian=38; //上限报警温度,默认值为38
uchar xiaxian=5; //下限报警温度,默认值为5
uchar tmpbuf[5];
sbit Sign_Port =P3^0;
sfr Dat_Port =0x80;
sfr Cs_Port =0xa0;
bit fu;
uint ReadTemperature(void) ;
uchar code table[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x00,0x40};

/*****延时子程序*****/
void Delay_DS18B20(int num)
{
while(num--) ;
}

/*****初始化DS18B20*****/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
Delay_DS18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
Delay_DS18B20(80); //精确延时,大于480us
DQ = 1; //拉高总线
Delay_DS18B20(14);
x = DQ; //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
Delay_DS18B20(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_DS18B20(4);
}
return(dat);
}
/*****写一个字节*****/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delay_DS18B20(5);
DQ = 1;
dat>>=1;
}
}
/*****读取温度*****/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
Init_DS18B20();
Delay_DS18B20(100);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
a=ReadOneChar(); //读低8位
b=ReadOneChar(); //读高8位
t=b;
t<<=8;
t=t|a;
return(t);
}

void Display(void)
{
uchar i,j,temp=0xef;
for(i=0;i<5;i++)
{
Cs_Port=0xff;
j=tmpbuf[i];
if(temp==0xFB)
Dat_Port=(table[j]|0x80);
else
Dat_Port=table[j];
Cs_Port=temp;
Delay_DS18B20(5);
Cs_Port=0xff;
temp=temp>>1;
temp=temp|0x80;
}
}
Disp_Temperature(uint k)
{
uchar i,tmph,tmpl,sign;

k=ReadTemperature( );
sign=(uchar)((k>>8)&0xf0);
if(sign==0xf0)
{
k=(~k)+1;
Sign_Port=0;
fu=1;
}
else {Sign_Port=1,fu=0;}
tmpl=(uchar)(k&0x0f);
tmph=(uchar)((k>>4)&0xff);
tmpl=tmpl*6.25;
tmpbuf[4]=tmpl%10;
tmpbuf[3]=tmpl/10;
tmpbuf[2]=tmph%10;
tmpbuf[1]=(tmph%100)/10;
tmpbuf[0]=tmph/100;
if(fu==1)
{if (tmpbuf[1]==0)
{tmpbuf[1]=11,tmpbuf[0]=10;}
else
tmpbuf[0]=11;
}
else

{if(tmpbuf[0]==0)
{
tmpbuf[0]=10;
if(tmpbuf[1]==0)
tmpbuf[1]=10;
}}
for(i=0;i<40;i++)
{
Display();

}

}
/*****初始化定时器0*****/
void InitTimer(void)
{
TMOD=0x1;
TH0=0x3c;
TL0=0xb0; //50ms(晶振12M)
}
/*****定时器0中断服务程序*****/
void timer0(void) interrupt 1
{
TH0=0x3c;
TL0=0xb0;
x++;
}
/*****外部中断0服务程序*****/
void int0(void) interrupt 0
{

EX0=0; //关外部中断0
if(DEC==0&&set_st==1)
{
shangxian--;
if(shangxian<xiaxian)shangxian=xiaxian;
}
else if(DEC==0&&set_st==2)
{
xiaxian--;
if(xiaxian<0)xiaxian=0;
}
}
/*****外部中断1服务程序*****/
void int1(void) interrupt 2
{
EX1=0; //关外部中断1
if(ADD==0&&set_st==1)
{
shangxian++;
if(shangxian>99)shangxian=99;
}
else if(ADD==0&&set_st==2)
{
xiaxian++;
if(xiaxian>shangxian)xiaxian=shangxian;
}
}

/*****显示开机初始化等待画面*****/
Disp_init()
{
P0 = 0x40; //显示-
P2 = 0xFE;
Delay_DS18B20(200);
P2 = 0xFD;
Delay_DS18B20(200);
P2 = 0xFB;
Delay_DS18B20(200);
P2 = 0xF7;
Delay_DS18B20(200);

}

/*****显示报警温度子程序*****/
Disp_alarm(uchar baojing)
{
P0 =0x39; //显示C
P2 = 0xFE;
Delay_DS18B20(500);
P2 = 0xFF;
P0 =table[baojing%10]; //显示十位
P2 = 0xFD;
Delay_DS18B20(500);
P2 = 0xFF;
P0 =table[baojing%100/10]; //显示百位
P2 = 0xFB;
Delay_DS18B20(500);
P2 = 0xFF;
if(set_st==1) {P0=0x76;}
else if(set_st==2) P0=0x38; //上限H、下限L标示
P2 = 0xF7;
Delay_DS18B20(500);
P2 = 0xFF;
}

/*****报警子程序*****/
Alarm()
{
if(x>=10){beep_st=~beep_st;x=0;}
if((m>=shangxian&&beep_st==1)||(m<xiaxian&&beep_st==1))BEEP=0;
else BEEP=1;
}
/*****主函数*****/
void main(void)
{
uint i,z;
InitTimer(); //初始化定时器
EA=1; //全局中断开关
TR0=1;
ET0=1; //开启定时器0
IT0=1;
IT1=1;
//check_wendu();
for(z=0;z<300;z++)
{
Disp_init();
}
while(1)
{
if(SET==0)
{
Delay_DS18B20(2000);
do{}while(SET==0);
set_st++;x=0;shanshuo_st=1;
if(set_st>2)set_st=0;
}
if(set_st==0)
{
EX0=0; //关闭外部中断0
EX1=0; //关闭外部中断1
//check_wendu();
i=ReadTemperature();
Disp_Temperature(i);
Alarm(); //报警检测
}
else if(set_st==1)
{
BEEP=1; //关闭蜂鸣器
EX0=1; //开启外部中断0
EX1=1; //开启外部中断1
if(x>=10){shanshuo_st=~shanshuo_st;x=0;}
if(shanshuo_st) {Disp_alarm(shangxian);}
}
else if(set_st==2)
{
BEEP=1; //关闭蜂鸣器
EX0=1; //开启外部中断0
EX1=1; //开启外部中断1
if(x>=10){shanshuo_st=~shanshuo_st;x=0;}
if(shanshuo_st) {Disp_alarm(xiaxian);}
}
}
}
/*****END*****/
oqlpn67
2010-12-25 · TA获得超过362个赞
知道答主
回答量:284
采纳率:0%
帮助的人:67.2万
展开全部
52单片机 18b20温度传感器程序2009-11-05 18:20
#include<reg52.h>
#include<math.h>
#include<INTRINS.H>

#define uchar unsigned char
#define uint unsigned int

sbit DQ=P1^3; //ds18b20 端口

uchar Temp_Integer=0;
uchar Temp_Decimal=0;
uchar fg=0;

void delay2(uint us)
{
while(us--);
}

uchar Init_DS18B20(void)
{
uchar x=0;
DQ = 1; //DQ复位
delay2(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay2(80); //精确延时 大于480us
DQ = 1; //拉高总线
delay2(10);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay2(5);
return x;
}

uchar ReadOneChar(void) //读一个字节,"LSB"
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay2(5);
}
return(dat);
}

void WriteOneChar(unsigned char dat) //写一个字节
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay2(5);
DQ = 1;
dat>>=1;
}
delay2(5);
}

/**********************DS18b20读取主函数,整个流程5ms左右************************/
uchar ReadTemperature(void) //读取温度
{

uchar L_18B20=0;
uchar H_18B20=0;

Init_DS18B20();
WriteOneChar(0xCC); // skip:跳过读序号列号的操作
WriteOneChar(0x44); // convert:启动温度转换
delay2(200);

Init_DS18B20();
WriteOneChar(0xCC); //skip:跳过读序号列号的操作
WriteOneChar(0xBE); //read:读取温度寄存器,前两个就是温度

L_18B20=ReadOneChar(); //读取温度低八位数据
H_18B20=ReadOneChar(); //读取温度高八位数据

if(H_18B20>0x7f) //最高位为1时温度是负
{
L_18B20=~L_18B20+1; //补码转换,取反加一
H_18B20=~H_18B20;
fg=1; //读取温度为负时fg=1
}
Temp_Decimal=L_18B20&0x0f; //取温度小数部分二进制
L_18B20=L_18B20>>4; //取温度整数部分二进制
H_18B20=H_18B20<<4;
Temp_Integer=H_18B20|L_18B20;
}

/***********************串口通信***************************/
0 外部中断0
1 定时器1
2 外部终端1
3 定时器1
4 串行口中断

RCAP2H = 0xff;
RCAP2L = 0xd9;
TCLK = 1;
RCLK = 1;
SCON = 0x50;//模式1异步传输模式
PCON = 0x00;

IE |= 0x90; //Enable Serial Interrupt

TR2=1//开中断

void serial() interrupt 4
{
if(RI == 1)
{
tempnum = SBUF;
RI = 0;
}
TI = 0;
}
void receiveinfo()
{
convert();
return;
}
void sendinfo()
{
SBUF = 100*displaynum[2] + 10*displaynum[1] + displaynum[0];
return;
}
void convert()
{
displaynum[0] = tempnum%10;
tempnum /= 10;
displaynum[1] = tempnum%10;
tempnum /= 10;
displaynum[2] = tempnum;
return;
}

void main()
{
while(1)
{
sendinfo();
receiveinfo();
}
return;
}
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
洛翠佛Bf
2010-12-24 · 超过29用户采纳过TA的回答
知道答主
回答量:216
采纳率:0%
帮助的人:108万
展开全部
我能
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式