STC89C52单片机数字温度传感器设计 (温度传感器是DS18B20) 寻高手帮在C语言程序中加个报警程序。急需。

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-06-28
STC89C52单片机数字温度传感器设计 (温度传感器是DS18B20) 寻高手帮在C语言程序中加个报警程序。急需。

我有做过这个,你把邮箱留下,我发给你。程序加PROTEUS的图

//DS18B20的读写程序,数据脚P2.7 //
//温度传感器18B20汇编程序,采用器件默认的12位转化 //
//最大转化时间750微秒,显示温度-55到+125度,显示精度 //
//为0.1度,显示采用4位LED共阳显示测温值 //
//P0口为段码输入,P34~P37为位选 //
/***************************************************/

#include "reg51.h"
#include "intrins.h" //_nop_();延时函数用
#define Disdata P0 //段码输出口
#define discan P2 //扫描口
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P1^2; //温度输入口
sbit DIN=P0^7; //LED小数点控制
uint h;
uint temp;
//
//
//**************温度小数部分用查表法***********//
uchar code ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//
uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"
uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; //列扫描控制字
uchar data temp_data[2]={0x00,0x00}; //读出温度暂放
uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个运算暂用

//
//
//
/*****************11us延时函数*************************/
//
void delay(uint t)
{
for (;t>0;t--);
}
//

/****************显示扫描函数***************************/
scan()
{
char k;
for(k=0;k<4;k++) //4位LED扫描控制
{
Disdata=dis_7[display[k]]; //数据显示
if (k==1){DIN=0;} //小数点显示
discan=scan_con[k]; //位选
delay(300);
P2=0xff;
}
}
//
//
/****************DS18B20复位函数************************/
ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();//从高拉倒低
DQ=0;
delay(50); //550 us
DQ=1;
delay(6); //66 us
presence=DQ; //presence=0 复位成功,继续下一步
}
delay(45); //延时500 us
presence=~DQ;
}
DQ=1; //拉高电平
}
//
//
/****************DS18B20写命令函数************************/
//向1-WIRE 总线上写1个字节
void write_byte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_(); //从高拉倒低
DQ=0;_nop_();_nop_();_nop_();_nop_(); //5 us
DQ=val&0x01; //最低位移出
delay(6); //66 us
val=val/2; //右移1位
}
DQ=1;
delay(1);
}
//
/****************DS18B20读1字节函数************************/
//从总线上取1个字节
uchar read_byte(void)
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;_nop_();_nop_();_nop_();_nop_(); //4 us
DQ=1;_nop_();_nop_();_nop_();_nop_(); //4 us
if(DQ)value|=0x80;
delay(6); //66 us
}
DQ=1;
return(value);
}
//
/****************读出温度函数************************/
//
read_temp()
{
ow_reset(); //总线复位
delay(200);
write_byte(0xcc); //发命令
write_byte(0x44); //发转换命令
ow_reset();
delay(1);
write_byte(0xcc); //发命令
write_byte(0xbe);
temp_data[0]=read_byte(); //读温度值的第字节
temp_data[1]=read_byte(); //读温度值的高字节
temp=temp_data[1];
temp<<=8;
temp=temp|temp_data[0]; // 两字节合成一个整型变量。
return temp; //返回温度值
}
//
/****************温度数据处理函数************************/

//二进制高字节的低半字节和低字节的高半字节组成一字节,这个
//字节的二进制转换为十进制后,就是温度值的百、十、个位值,而剩
//下的低字节的低半字节转化成十进制后,就是温度值的小数部分

/********************************************************/
work_temp(uint tem)
{
uchar n=0;
if(tem>6348) // 温度值正负判断
{tem=65536-tem;n=1;} // 负温度求补码,标志位置1
display[4]=tem&0x0f; // 取小数部分的值
display[0]=ditab[display[4]]; // 存入小数部分显示值
display[4]=tem>>4; // 取中间八位,即整数部分的值
display[3]=display[4]/100; // 取百位数据暂存
display[1]=display[4]%100; // 取后两位数据暂存
display[2]=display[1]/10; // 取十位数据暂存
display[1]=display[1]%10;
/******************符号位显示判断**************************/
if(!display[3])
{
display[3]=0x0a; //最高位为0时不显示
if(!display[2])
{
display[2]=0x0a; //次高位为0时不显示
}
}
if(n){display[3]=0x0b;} //负温度时最高位显示"-"
}
//
//
/****************主函数************************/
main()
{
Disdata=0xff; //初始化端口
discan=0xff;
for(h=0;h<4;h++) //开机显示"0000"
{display[h]=0;}
ow_reset(); //开机先转换一次
write_byte(0xcc); //Skip ROM
write_byte(0x44); //发转换命令
for(h=0;h<100;h++) //开机显示"0000"
{scan();}
while(1)
{
work_temp(read_temp()); //处理温度数据
scan(); //显示温度值
}
}
//
//***********************结束**************************//

#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define upzero 1
#define downzero 0
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar code seg[]={0xfe,0xfd,0xfb}; //加了PNP的情况下的段选
sbit DQ=P3^3;
sbit led=P1^1;
sbit DIN=P0^7;//小数点
//sbit LE=P3^0;
uint temperature;
uint wendu,flag=0;

void delay(uchar k)
{
while(--k);
}

void delay1(uint k)
{
uint i,j;
for(i=0;i<k;i++)
for(j=0;j<121;j++);
}

void time0_init()
{
TMOD=0x01;
EA=1;
ET0=1;
TR0=1;
TH0=-30000/256;//定时50毫秒
TL0=-30000%256;
}

/*void init_display()//上电时数码管的显示
{

P2=0xff;
delay(3);
} */

void display(uint k)//显示温度
{
uchar ge,shi,bai;
ge=k%10;
shi=k/10%10; //shiwei
bai=k/100;

if(!flag)//温度为负数
{
P2=seg[0];
P0=0xbf;//负号 显示"-"
delay1(4);
P2=0xff;

P2=seg[1];
P0=tab[k/10%10];
delay1(4);
P2=0xff;

P2=seg[2];
P0=tab[k%10];
//DIN=0;
delay1(4);
P2=0xff;

/*P2=seg[3];
P0=tab[0];
delay1(4);
P2=0xff;
*/
}
if(flag)//温度为正数 由于实际的焊的板子只有三个数码管 所以,没加“+” 了。如 45.0度
{
//DIN=1;
P2=0xff;
P2=seg[0];
P0=tab[0];
delay1(4);
P2=0xff;

P2=seg[1];
P0=tab[ge];
DIN=0; // 问题问什么 加小数点要在P2口上加才能正常显示。
delay1(4);

DIN=1;
P2=0xff;
P2=seg[2];
P0=tab[shi];
delay1(4);
P2=0xff;

}
}
/*
每次读写前对DS18B20进行复位初始化。复位要求主CPU将数据线下拉500μ
,然后释放,DS18B20收到信号后等待16 - 60us然后60-240us的存在低脉冲
脉冲,主CPU收到此信号后表示复位成功。
*/
initial_ds18b20()//返回为0表示初始化成功
{
uchar j=0;
DQ=1;//这两条语句用不用不关紧要
delay(4);
DQ=0;
delay(180);//精确延时 730us 检测总线上是否有480-960微秒的低电平出现
delay(200);
DQ=1;
delay(15);//35us 如果有总线转为高电平后等待15-60微秒自动将总线电平拉低60-240微秒做出响应存在脉冲
j=DQ;
delay(50);//105us 至少要100秒以上
//return(j);
}

uchar read_byte(void)
{
uchar i=0,dat;
for(i=0;i<8;i++)
{
DQ=0;
delay(5);//15us
DQ=1;
if(DQ)
dat=(dat>>1)|0x80;//读1
else
dat=((dat>>1))|0x00;//读0
delay(25);
}
return(dat);
}

void write_byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0;
delay(5);//15us
DQ=dat&0x01;//从低位到高位 一位一位的写入DS18B20,即控制它的工作方式
delay(10);//写所需时间
DQ=1;
dat>>=1;
delay(2);
}
delay(1);
}

uchar readwendu(void)
{

//float tt;
uint j=200;
uchar templ=0,temph=0;

initial_ds18b20();
write_byte(0xcc);//跳过ROM
write_byte(0x44);
while(--j);
initial_ds18b20();
write_byte(0xcc);
write_byte(0xbe);
templ=read_byte();//低位
temph=read_byte();//高位

if(temph>0x7f)//处理数据 负数
{
temph=~temph;
templ=~templ+1;
flag=downzero;
temph<<=4; //
temph+=(templ&0xf0)>>4;//
wendu=temph;//
delay(10);
}
else //正数
{
flag=upzero;
temph<<=4; // 左移四位 留一位符号位 因为高五位为符号位
temph+=(templ&0xf0)>>4;//低八位的高四位 即低八位的整数部分 再与temph相加得到一个新的八位
wendu=temph;
delay(10);
}
return(wendu);
}

void main()
{
time0_init();
//init_display();
while(1)
{

temperature=readwendu();
display(temperature);
TR0=1;

}
}

void time0() interrupt 2 //50毫秒判断 温度
{

TR0=0;
TH0=-30000/256;
TL0=-30000%256;

if(temperature>25 || temperature<30)
led=~led;
delay(10);

}
这是我做的 能用。 用LED报警 你也可以添加个声音报警,温度都读出来了,加个报警那是很容易的事,真心怀疑这个程序是不是你自己写的

好像已经有报警的功能了吧

太简单 没意思

  • STC89C52单片机数字温度传感器设计 (温度传感器是DS18B20) 寻高手帮...
    答:if(flag)//温度为正数 由于实际的焊的板子只有三个数码管 所以,没加“+” 了。如 45.0度 { //DIN=1;P2=0xff;P2=seg[0];P0=tab[0];delay1(4);P2=0xff;P2=seg[1];P0=tab[ge];DIN=0; // 问题问什么 加小数点要在P2口上加才能正常显示。delay1(4);DIN=1;P2=0xff;P2=...
  • 求STC89C52单片机和DS18B20温度传感器的程序代码,用四位共阴数码管显示...
    答://最大转化时间750微秒,显示温度-55到+125度,显示精度 // //为0.1度,显示采用4位LED共阳显示测温值 // //P0口为段码输入,P34~P37为位选 // /***/ include "reg51.h"include "intrins.h" //_nop_();延时函数用 define Disdata P0 //段码输出口 define discan ...
  • DHT11温湿度传感器内部用到的8位单片机型号是多少?
    答:DHT11温湿度传感器内部使用的是一个自主研发的8位单片机,型号不是公开的。DHT11传感器可以通过单一总线数字接口与微处理器连接,使用简单,可广泛应用于测量环境温度和湿度。传感器测量结果通过传输数据的方式输出,数据传输格式是二进制,需要通过程序进行解析。
  • STC89C52单片机如何读取PT100的温度值?及硬件电路?谢谢了
    答:这个就是PT100采集信号使用的(三线制的), 可以将ADC_PT100输入到ADC0809里进行信号采集,PT100-1接信号,其他两端接地使用即可。然后ADC0809的输出端接您的单片机就可以了。
  • DHT11温湿度传感器如何把温湿度数据传给单片机STC89C52
    答:DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。
  • ...基于STC89c52单片机 烟雾传感器MQ2 温度传感器DS18B20 ADC0832 数 ...
    答:我提供您主要思路好了:ADC0832可以同时采集两路AD。对于DS18B20来讲,它是单总线的,可以数据口直接挂单片机就OK了,MQ2是模拟信号输出,需要接ADC0832的一个输入口,如IN0,然后输出给单片机即可。至于数码管,兄弟总知道怎么做了吧。如果实在不知道,请加我吧:417179642 ...
  • 关于《基于STC89C52单片机的智能温控系统》,求大神帮忙写一下代码...
    答:write_data(0x30+shi);write_data(0x30+ge);} 给你贴一个LCD的控制程序,其余的还是自己做吧,没用过你那个温度传感器,你看一下它给的时序图,再查一下资料,写一个读温度传感器串口数据的程序就行了,把数据直接赋给我程序中的num,就可以显示了。至于温度报警,你自己写个if之类的就行了 ...
  • 18b20温度传感器与STC89C52RC单片机之间:DQ与单片机IO口之间需要接电阻...
    答:温度方面工作由数字式温度传感器DS18B20来完成,这款温度传感器是具有线路简单,体积小,方便易用等特点,温度测量范围为-55℃~+125℃,可编程为9位~12位A/D转换精度,测温分辨率可达0.0625℃,被测温度用符号扩展的16位数字量方式串行输出。选用这个芯片使电路简化,提高了效率。HS1101 是基于独特工...
  • 求单片机温湿度报警运行代码
    答:以下是简单的基于STC89C52单片机和SHT11温湿度传感器的温湿度报警运行代码的示例。c include <reg52.h> include <intrins.h> sbit SDA = P2^0; // SHT11数据线 sbit SCK = P2^1; // SHT11时钟线 sbit ALARM = P2^2; // 报警输出 unsigned char TempData_H, TempData_L, HumiData_H, ...
  • stc89c52 接一个红外传感器(E18-D80NK),怎么把信号输到单片机?
    答:在硬件接线上找原因,首先保证传感器电源负极和单片机系统的电源负极要短接,然后P0.1作为输入的话,P0口引线要接上拉电阻(每个引脚接电阻一端,另一端接电源正),1K-10K就够了,时间久了,记不大请了,你查查。可以这么定义输入引脚吗?有哪些引脚是可以定义用来输入输出的?没有问题,可以这么定义...