while(1){
18b20检测程序();
显示程序();
if(wdz>25){
fmq=1;//或fmq=0;具体看电路
}else{
fmq=0;//或fmq=1;具体看电路
}
}
#include <reg52h>
#include <stdioh>
#define uchar unsigned char
#define uint unsigned int
sbit ds=P2^2; //温度传感器信号线
sbit dula=P2^6; //数码管段选线
sbit wela=P2^7; //数码管位选线
sbit beep=P2^3; //蜂鸣器
uint temp;
float f_temp;
uint warn_l1=260;
uint warn_l2=250;
uint warn_h1=300;
uint warn_h2=320;
sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0xbf,0x86,
0xdb,0xcf,0xe6,0xed,
0xfd,0x87,0xff,0xef}; //不带小数点的编码
void delay(uint z)//延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void dsreset(void) //18B20复位,初始化函数
{
uint i;
ds=0;
i=103;
while(i>0)i--;
ds=1;
i=4;
while(i>0)i--;
}
bit tempreadbit(void) //读1位函数
{
uint i;
bit dat;
ds=0;i++; //i++ 起延时作用
ds=1;i++;i++;
dat=ds;
i=8;while(i>0)i--;
return (dat);
}
uchar tempread(void) //读1个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tempreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
void tempwritebyte(uchar dat) //向18B20写一个字节数据
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //写 1
{
ds=0;
i++;i++;
ds=1;
i=8;while(i>0)i--;
}
else
{
ds=0; //写 0
i=8;while(i>0)i--;
ds=1;
i++;i++;
}
}
}
void tempchange(void) //DS18B20 开始获取温度并转换
{
dsreset();
delay(1);
tempwritebyte(0xcc); // 写跳过读ROM指令
tempwritebyte(0x44); // 写温度转换指令
}
uint get_temp() //读取寄存器中存储的温度数据
{
uchar a,b;
dsreset();
delay(1);
tempwritebyte(0xcc);
tempwritebyte(0xbe);
a=tempread(); //读低8位
b=tempread(); //读高8位
temp=b;
temp<<=8; //两个字节组合为1个字
temp=temp|a;
f_temp=temp00625; //温度在寄存器中为12位 分辨率位00625°
temp=f_temp10+05; //乘以10表示小数点后面只取1位,加05是四舍五入
f_temp=f_temp+005;
return temp; //temp是整型
}
////////////////////显示程序//////////////////////////
void display(uchar num,uchar dat)
{
uchar i;
dula=0;
P0=table[dat];
dula=1;
dula=0;
wela=0;
i=0XFF;
i=i&(~((0X01)<<(num)));
P0=i;
wela=1;
wela=0;
delay(1);
}
void dis_temp(uint t)
{
uchar i;
i=t/100;
display(0,i);
i=t%100/10;
display(1,i+10);
i=t%100%10;
display(2,i);
}
//////////////////////////////////////////////
void warn(uint s,uchar led) //蜂鸣器报警声音 ,s控制音调
{
uchar i;i=s;
dula=0;
wela=0;
beep=0;
P1=~(led);
while(i--)
{
dis_temp(get_temp());
}
beep=1;
P1=0XFF;
i=s;
while(i--)
{
dis_temp(get_temp());
}
}
void deal(uint t)
{
uchar i;
if((t>warn_l2)&&(t<=warn_l1)) //大于25度小于27度
{
warn(40,0x01);
}
else if(t<=warn_l2) //小于25度
{
warn(10,0x03);
}
else if((t<warn_h2)&&(t>=warn_h1)) //小于32度大于30度
{
warn(40,0x04);
}
else if(t>=warn_h2) //大于32度
{
warn(10,0x0c);
}
else
{
i=40;
while(i--)
{
dis_temp(get_temp());
}
}
}
void init_com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
void comm(char parr)
{
do
{
SBUF = parr++; //发送数据
while(!TI); //等待发送完成标志为1
TI =0; //标志清零
}while(parr); //保持循环直到字符为'\0'
}
void main()
{
uchar buff[4],i;
dula=0;
wela=0;
init_com();
while(1)
{
tempchange();
for(i=10;i>0;i--)
{
dis_temp(get_temp());}
deal(temp);
sprintf(buff,"%f",f_temp);
for(i=10;i>0;i--)
{
dis_temp(get_temp());}
comm(buff);
for(i=10;i>0;i--)
{
dis_temp(get_temp());}
}
}
给你提一个小建议,但是不会帮你写程序,我看你把温度放到了数组,你可以通过判断数组来开启报警啊,例如:
if()
{
-----------
}
利用if语句判断温度的各位和十位,如果相等就开启蜂鸣器,就这么简单!
参考一下下面的报警器程序吧,这是《PROTEUS仿真100例》中的。
//名称:按键发音
#include<reg51h>
#define uchar unsigned char
#define uint unsigned int
sbit SPK=P1^0;
sbit K1=P1^7;
void Alarm(uchar t)
{
uchar i,j;
for(i=0;i<200;i++)
{
SPK=~SPK;
for(j=0;j<t;j++);
}
}
void main()
{
while(1)
{
if(K1==1) {Alarm(90);Alarm(120);}
}
}
你可以试着改一下ALARM()函数的数字试试。
/
主函数
/
void main()
{
init();//单片机初始化
while(1)//以下执行无限循环
{
keyscan();//调用键盘扫描得到键值"Key"
if(key==1)//如果键值为1
{Shiwei++;//则温度阀值的十位累加1
key=0;//当次事件处理完后将按键键值清零
if(Shiwei==10) Shiwei=0;//如果温度阀值的十位累加到10,立即将其清零,所以数值只能设置在0-9之间
}
if(key==2)//如果键值为2
{ Gewei++;//则温度阀值的个位累加1
key=0;//当次事件处理完后将按键键值清零
if(Gewei==10) Gewei=0;//如果温度阀值的个位累加到10,立即将其清零,所以数值只能设置在0-9之间
}
if(key==3)//如果键值为3
{
TR0=1;//则启动T0(开始计时,准备温度转换)
S=Shiwei10+Gewei;//将温度阀值的十位和个位合并成一个数值S(个位十位分开是为了方便显示,合并是为了方便数值比较)
key=0;//当次事件处理完后将按键键值清零
}
for(i=0;i<5;i++)//以下是5位数码管的的动态扫描
{
if(i==0)//扫描到第0号数码管
{ PB8255=poly[3];//将"位码表"第3位数值家在到8255的B端口上(PB6写0,而B口其它位写1)
PA8255=table[Shiwei];//取温度阀值的十位值所对应的段码值送给当前被使能的数码管显示
delay(1000);//短暂延时使数码管当前位的显示停留一段时间,实现人眼的惰性效应
}
if(i==1)//扫描到第1号数码管
{
PB8255=poly[4];//将"位码表"第4位数值加载到8255的B端口上(PB7写0,而B口其它位写1)
PA8255=table[Gewei]; //取温度阀值的个位值所对应的段码值送给当前被使能的数码管显示
delay(1000);//原理同上
}
if(i==2)//扫描到第2号数码管
{
PB8255=poly[2];//将"位码表"第2位数值加载到8255的B端口上(PB1写0,而B口其它位写1)
PA8255=table[temp/10]; //取温度值的十位值所对应的段码值送给当前被使能的数码管显示
delay(1000);//原理同上
}
if(i==3)//扫描到第3号数码管
{
PB8255=poly[1];//将"位码表"第1位数值加载到8255的B端口上(PB2写0,而B口其它位写1)
PA8255=table[temp%10]; //取温度值的个位值所对应的段码值送给当前被使能的数码管显示
delay(100);//原理同上
}
if(i==4)//扫描到第4号数码管
{ PB8255=poly[0];//将"位码表"第0位数值加载到8255的B端口上(PB3写0,而B口其它位写1)
PA8255=0xc6;//取符号"C"所对应的段码值0xc6送给当前被使能的数码管显示
delay(100);//原理同上
}
}
if(flag_get==1) //定时读取当前温度(40个定时器中断周期flag_get才被置一次1)
{
temp=ReadTemperature();//将转换后的温度值送入temp暂存器
flag_get=0;//等待40个定时器中断周期
}
if(temp<S)//如果当前温度小于阀值温度
{
di=1;
delay(500) ;//则“di”端口输出一个500延时单位的高电平脉冲
di=0; //效果:如果该端口接的是一个发光管,只要temp<S(当前温度值小于设定温度值),发光管就闪烁。
}
if(temp>S)//如果当前温度值大于设定的温度阀值
{
gao=1;
delay(500) ;//则“gao”端口输出一个500延时单位的高电平脉冲
gao=0; //效果:如果该端口接的是一个发光管,只要temp>S(当前温度值大于设定温度值),发光管就闪烁。
}
if(temp>40)//当前温度值超过40则蜂鸣器发声报警
{
for(j=0;j<20;j++)//喇叭发声的时间循环,改变大小可以改变发声时间长短
{
delay(200);//参数决定发声的频率,估算值
SPK=!SPK;//蜂鸣器取反,间歇发声
}
SPK=1; //喇叭停止工作,间歇的时间,可更改
}
if(temp<20)//当前温度值低于20则蜂鸣器发声报警
{
for(j=0;j<20;j++)//喇叭发声的时间循环,改变大小可以改变发声时间长短
{
delay(20);//参数决定发声的频率,估算值
SPK=!SPK;//蜂鸣器取反,间歇发声
}
SPK=1; //喇叭停止工作,间歇的时间,可更改
}
}
}
/
// 定时器中断T0
实现功能:控制温度定时转换
/
void tim(void) interrupt 1 using 1//使用1号高速寄存器区做堆栈区
{
TH0=0xef;//定时器重装初值
TL0=0xf0;
num++;//每中断一次num累加一次
if (num==50) //如果中断累加到50次
{num=0; //num累加器清零
flag_get=1;//标志位被置1
//每50个中断周期flag_get被置1一次,
//如果发现flag_get=1则执行温度转换,转换完后flag_get标志会被清零(在主程序中)
//所以上面程序实现功能是:每50个中断周期,进行一次温度转换
}
}
#include<reg52h>
#define
uchar
unsigned
char
#define
uint
unsigned
int
sbit
dq
=
p3^3;
//ds18b20数据口
uchar
code
table[10]
=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void
delay(uint
a)
//延时
{
while(a--);
//为了精准控制
}
void
reset()
//复位
{
dq=0;
delay(50);
dq=1;
delay(50);
}
void
write_bit(uchar
a)
//写一位
{
dq=0;
if(a)
dq=1;
delay(5);
dq=1;
}
uchar
read_bit()
//读一位
{
dq=0;
dq=1;
delay(0);
//需要非常准确控制时间
5us左右
return
dq;
}
void
write_byte(char
k)
//写一个字节
{
uchar
i,b;
for(i=0;i<8;i++)
{
b=k;
b=b>>i;
//位 *** 作
用于除2计算
write_bit(b&0x01);
delay(5);
}
}
uchar
read_byte()
//读一个字节
{
uchar
i,m=1,s=0;
for(i=0;i<8;i++)
{
if(read_bit())
s+=m<<i;
//位 *** 作
用于乘2计算
delay(5);
}
return
s;
}
void
display_smg(uint
temp)
//驱动数码管
{
uint
i;
for(i=7;i>=0;i--)
{
p2=i;
//位选
p0=table[temp%10];
//段选
temp/=10;
delay(500);
if(temp==0)
break;
//消零
}
}
main()
{
uchar
temp_h,temp_l;
uint
temp;
p0=0x00;
p2=0x00;
while(1)
{
reset();
//复位
write_byte(0xcc);
//跳过搜索
write_byte(0x44);
//温度转换
reset();
//复位
write_byte(0xcc);
//跳过搜索
write_byte(0xbe);
//要求读出数据
temp_l=read_byte();
//读出低八位
temp_h=read_byte();
//读出高八位
reset();
//终止读数
temp=temp_h16+temp_l/16;//转换低位和高位之和
display_smg(temp);
//驱动数码管
}
}
#include <reg52h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P3^7; //define interface 定义DS18B20接口
uint temp; // variable of temperature
uchar flag1; // sign of the result positive or negative
sbit p0_5=P0^5;
sbit p2_7=P2^7;
sbit p2_4=P2^4;
sbit p2_5=P2^5;
sbit p2_6=P2^6;
unsigned char code TABLE[]={
0xd7,0x11,0xcd,0x5d,0x1b,
0x5e,0xde,0x15,0xdf,0x5f,
0x9f,0xdf,0xc6,0xd7,0xce,0x8e};
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
void dsreset(void) //send reset and initialization command
{
uint i; //DS18B20初始化
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit 读一位
{
uint i;
bit dat;
DS=0;i++; //i++ for delay 小延时一下
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //read a byte date 读一个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好
//一个字节在DAT里
}
return(dat); //将一个字节数据返回
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{ //写一个字节到DS18B20里
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1 写1部分
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0 写0部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //DS18B20 begin change 发送温度转换命令
{
dsreset(); //初始化DS18B20
delay(1); //延时
tmpwritebyte(0xcc); // 跳过序列号命令
tmpwritebyte(0x44); //发送温度转换命令
}
uint tmp() //get the temperature 获得温度
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe); //发送读取数据命令
a=tmpread(); //连续读两个字节数据
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a; //两字节合成一个整型变量。
tt=temp00625; //得到真实十进制温度值,因为DS18B20
//可以精确到00625度,所以读回数据的最低位代表的是
//00625度。
temp=tt10+05; //放大十倍,这样做的目的将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入 *** 作。
return temp; //返回温度值
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
void display(uint temp)
{
uchar a,b,c,d;
a=temp/100;
b=temp/10-a10;
d=temp%10;
c=(temp%100-d)/10;
P0=TABLE[d];
p0_5=0;
p2_7=0;
delay(1);
p2_7=1;
P0=TABLE[c];
p2_4=0;
delay(1);
p2_4=1;
P0=TABLE[b];
p0_5=1;
p2_5=0;
delay(1);
p2_5=1;
P0=TABLE[a];
p2_6=0;
delay(1);
p2_6=1;
}
void main() //主函数
{
uchar a;
Init_Com(); //初始化串口
do
{
tmpchange(); //温度转换
for(a=10;a>0;a--)
{
display(tmp()); //显示十次
}
}
while(1);
}
以上就是关于ds18b20收集温度并显示的c程序已写好,求当温度高于25度时蜂鸣器报警的主函数语句,全部的内容,包括:ds18b20收集温度并显示的c程序已写好,求当温度高于25度时蜂鸣器报警的主函数语句,、基于AT89C51和DS18B20制作的温度报警器原理图和单片机内部程序、DS18B20显示温度报警程序怎么写等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)