基于51单片机RS485总线的远距离温度监控系统程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P1^0; //DS18B20接入口sbit segd=P1^1; //段控制74573锁存使能
sbit segw=P1^2; //位控制74573锁存使能
uchar code tab[]={
0x3f,0x06,0x5b,0x4f, //0~3
0x66,0x6d,0x7d,0x07, //4~7
0x7f,0x6f,0x77,0x7c, //8~b
0x39,0x5e,0x79,0x71, //c~f
0x00 //灭
};
uchar tem[7];
uchar T_num=200;
/************************函数声明***********************/
void delay(uint n); //延时函数
void init_uart(void); //串口初始化
void init_T0(); //定时器T0初始化
void Init_DS18B20(void); //DS18b20初始化函数
uchar ReadOneChar(void); //DS18b20读一个字节
void WriteOneChar(uchar dat); //DS18b20写一个字节
int ReadTemperature(void); //DS18b20读取温度
void disp_dat(uchar x,uchar y); //单个数码管显示函数
void disp(void); //温度显示函数
uchar sum(uchar *dat,uchar n); //求和校验函数
uchar get_adress(void); //获取从机地址函数
void change(void); //数据调整函数
void send_dat(void); //串行数据发送函数
/**********************主函数***********************/
void main()
{
init_T0();
init_uart(); //初始化串口
while(1)
{
change(); //调整数据
disp();
//进行显示
}
}
/**********************延时函数**********************/
void delay(uint n)
{
while(n--) ;
}
/********************定时器T0初始化******************/
void init_T0()
{
TMOD=0x01; //工作方式1
定时50ms
TL0=0x00;
ET0=1;
//允许定时器T0中断
EA=1; / /开总中断
TR0=1;
//启动定时器T0
}
/*********************串口初始化*********************/
void init_uart(void)
{
SCON=0x40; //工作方式1
TMOD=TMOD|0x20; //T 1为工作方式2
TH1=0xFD; //设置T1
TL1=0xFD;
TR1=1;
//启动定时器T1
}
/*****************DS18b20初始化函数******************/
void Init_DS18B20(void)
{
uchar x=0;
DQ=1; / /DQ复位
delay(10); //延时
DQ=0; / /将DQ拉低
delay(80); //精确延时约480us
/DQ线拉高总线
delay(20);
while(!DQ); / /等待初始化结束
delay(30);
}
/****************DS18b20读一个字节*******************/
uchar ReadOneChar(void)
{
uchar i=0;
uchar dat=0;
for (i=8;i>0;i--)
{
DQ=0;
//给脉冲信号
dat>>=1;
DQ=1;
//给脉冲信号
if(DQ)dat|=0x80; //读入值是否为1
delay(8);
}
return(dat);
}
/***************DS18b20写一个字节********************/
void WriteOneChar(uchar dat)
{
uchar i=0;
for (i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay(10);
DQ=1;
dat>>=1;
}
delay(8);
}
/*****************DS18b20读取温度********************/
int ReadTemperature(void)
{
uchar dat_L=0,dat_H=0;
int temper=0;
float temp1=0;
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
dat_L=ReadOneChar(); //低位
dat_H=ReadOneChar(); //高位
temper=dat_H;
temper<<=8;
temper=temper|dat_L;
temp1=temper*0.0625;
temper=temp1*10+0.5; //计算温度值
return(temper);
}
/****************获取从机地址函数*******************/
uchar get_adress(void)
{
uchar ad;
ad=P1;
ad>>=4;
//获取地址
return(ad);
}
/******************求和校验函数**********************/
uchar sum(uchar *dat,uchar n)
{
uchar i;
uchar s_dat=0x00;
for(i=2;i<n+1;i++) //对十位、个位和小数位上的数据求和
{
s_dat+=dat[i];
}
return(s_dat); //返回求和值
}
/*******************数据调整函数********************/
void change(void)
{
int temp;
temp=ReadTemperature(); //读温度
tem[0]=0x24; //发送起始标志$
tem[1]=get_adress(); //获取从机地址
tem[2]=temp%1000/100; //存十位上的数据
tem[3]=temp%100/10; //存个位上的数据
tem[4]=temp%10; //存小数位上的数据
tem[5]=sum(tem,3); //存校验和
tem[6]=0x23; //发送结束标志#
}
/***************单个数码管显示函数*******************/
void disp_dat(uchar x,uchar y)
{
segw=1;
//74HC573开锁存
P0=~(0x01<<x); //送位选
segw=0;
segd=1;
if(x==1)
P0=tab[y]|0x80; //若是个位送显示小数点
else
P0=tab[y]; //送显示数据
segd=0;
}
/******************温度显示函数**********************/
void disp(void)
{
disp_dat(0,tem[2]); //显示十位上的数据
delay(200);
disp_dat(1,tem[3]); //显示个位上的数据
delay(200);
disp_dat(2,tem[4]); //显示小数点后第一位数据
delay(200);
disp_dat(3,16); //清零段位74HC573中的数据
}
/****************串行数据发送函数*******************/
void send_dat(void)
{
uchar i;
for(i=0;i<7;i++)
{
SBUF=tem[i];
while(TI==0); //等待发送结束
TI=0;
}
}
/*******************定时T0中断程序*****************/
void senddat_T0(void) interrupt 1
{
TH0=0x4c; //重载定时器初值
TL0=0x00;
if(--T_num==0)
{
send_dat(); / /发送数据
T_num=200; //恢复计数值
}
}
文档已经阅读完毕,请返回上一页!。