A. ds18b20温度报警程序
#include <reg52.h>
#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=temp*0.0625; //得到真实十进制温度值,因为DS18B20
//可以精确到0.0625度,所以读回数据的最低位代表的是
//0.0625度。
temp=tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入操作。
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-a*10;
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);
}
B. 单片机温度报警器的温度上下限按键调控的C语言程序怎么编
温度报警器就是需要温度传感器不停地对监控的对象进行检测,例如pt100温度传感器,pt100传感器是不同温度下,阻值会不同,在同一温度下,阻值是相同的。根据这个原理通过电路转换成电压,然后模拟量转换成数字量输入到单片机,单片机根据读取到的电压值判断实际温度值,然后根据设定的报警值比较,如果超过 就进行报警动作。
在实际设计过程中那个报警温度的设定,可以直接对那个变量进行加减的,例如
void actfuntion(unsigned char temp)
{
temp++;
}
然后在检测到按键有电平跳变的时候,就调用这个含参子函数对定义的温度设定值进行加操作,减操作也是一样,还可以在调用的后面进行最大值或者最小值的判断。
如果觉得这样一下一下的按太麻烦了,可以对按键进行长按连续触发进行判断,就是在定时器里进行判断按下时间,然后不停的调用这个子函数。
当然这个设定值是需要考虑掉电保存的,或者是按键保存。可以在设定好温度值之后,在按下其他的按键,进行把温度设定值 保存到单片机内部eeprom就可以了,不需要保存太多数据的情况下,现在市面上很多单片机都有的内部eeprom就够用的了,不需要进行外部扩展。
然后在单片机上电,也就是主函数的开头进行读取eeprom中保存的设定值。
C. 基于AT89C51和DS18B20制作的温度报警器原理图和单片机内部程序
#include <reg52.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds=P2^2; //温度传感器信号线
sbit la=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=temp*0.0625; //温度在寄存器中为12位 分辨率位0.0625°
temp=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5是四舍五入
f_temp=f_temp+0.05;
return temp; //temp是整型
}
////////////////////显示程序//////////////////////////
void display(uchar num,uchar dat)
{
uchar i;
la=0;
P0=table[dat];
la=1;
la=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;
la=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;
la=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());}
}
}
D. 关于C51单片机温度报警程序的问题 谁能帮我在每段程序后加汉字解释 及怎么实现温度显示及蜂鸣器报警的
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define out P0 ;
#define INT8U unsigned char //宏定义
#define INT16U unsigned int
sbit smg1=P2^0;
sbit smg2=P2^1;
sbit smg3=P2^2;
sbit smg4=P2^3;
sbit Beep=P1^5; //蜂鸣器引脚定义
sbit led=P1^6;
sbit led1=P1^7; //设置灯光报警键
sbit DQ=P2^4; //ds18b20端口
void init_ds18b20(void); //ds18b20初始化子程序
void delay(uchar); //ds18b20工作延时子程序
uchar readbyte(void);//向ds18b20读一个字节数据
/*******************************************************************************/
void writebyte(uchar);//向ds18b20写一个字节数据
uint retemp();//计数变量
uchar key;
uchar a,b,c,d; //计数变量
uchar x[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uint retemp()
{
uint a,b,t;
init_ds18b20(); //初始化ds18b20
writebyte(0xcc); // 跳过读序列号的操作
writebyte(0x44); // 启动温度转换
init_ds18b20();
writebyte(0xcc); //跳过读序号列号的操作
writebyte(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=readbyte(); //读出温度低位LSB
b=readbyte(); //读出温度高位MSB
t=b; //将温度高八位送t
t<<=8; //乘以256移到高八位
t=t|a; //高低八位组合成温度值
if(t<0x8000) //如果温度为正计算正温度值
{
key=0;
t=t*0.625;
}
else //否则温度为负,取反
{
key=1;
t=(~t+1)*0.625;
}
return(t); //返回温度值
}
void main()
{
uint i,t;
EA = 1; //开总中断
TMOD = 0x01; //定时器0工作方式1
TR0=1;
delay(100);
while(1)
{
t=retemp(); 读温度值
a=x[t/1000]; //温度千位数
b=x[t/100%10]; //温度百位数
c=x[t/10%10]-0x80; //温度十位数
d=x[t%10]; //温度个位数
if(key==1) //如果key=1
a=0xbf; //a为“负号"
if((key==0)&&(t>320)) //如果key=0 且t大于320
{
led1=0; //点亮led1
ET0=1; //开启定时器0中断
}
else if(t<290) //如果温度小于290
{
led=0; //点亮led
ET0=1; //开启定时器0中断
}
else //否则
{
led1=1; //关闭led1
led=1; //关闭led
ET0=0; //关闭定时器0中断
}
for(i=0;i<50;i++) //循环50次
{smg1=1;P0=a;delay(100);smg1=0; //显示千位
smg2=1;P0=b;delay(100);smg2=0; //显示百位
smg3=1;P0=c;delay(100);smg3=0; //显示十位
smg4=1;P0=d;delay(100);smg4=0; //显示个位
}
}
}
/*ds18b20工作延时子程序*/
void delay (uchar i)
{
do
{_nop_();
_nop_();
_nop_();
i--;
}
while(i);}
/*ds18b20初始化子程序*/
void init_ds18b20()
{
uchar x=0;
DQ=0; //单片机将DQ拉低
delay (120);
DQ=1; //拉高总线
delay(16);
delay(80);
}
/*读一个字节*/
uchar readbyte ()
{uchar i=0,date=0;
for(i=8;i>0;i--)
{
DQ=0; // 给脉冲信号
delay(1);
DQ=1; // 给脉冲信号
date>>=1;
if(DQ)date|=0x80;
delay(11);
}
return(date);
}
/*写一个字节*/
void writebyte(uchar dat)
{uchar i=0;
for(i=8;i>0;i--) //写8位数
{
DQ=0;
DQ=dat&0x01; //写dat的D0位
delay(12);
DQ=1;
dat>>=1;
delay(5);
}
}
/**************************************************
*函数名:中断函数
*描 述:产生矩形脉冲使蜂鸣器发声
**************************************************/
void BeepTimer0(void) interrupt 1
{
Beep = ~Beep;
TH0 = 65335 / 256; //定时器赋初值
TL0 = 65335 % 256;
}