标题:
这个烟雾传感器的单片机程序我想加一个继电器带风扇 怎么做?
[打印本页]
作者:
wang1195
时间:
2018-5-22 20:59
标题:
这个烟雾传感器的单片机程序我想加一个继电器带风扇 怎么做?
下面这个是温度与烟雾传感器的程序,可以实现读取温度、调温度的报警值,当温度或者烟雾传感器达到设定值后蜂鸣器会报警。现在我想让他实现报警的时候继电器也通电,8颗流水灯快速闪烁。我的实验板继电器是P1.4口,八颗led灯是P2口。请教大神该怎么改啊。
#include <reg52.h>
#include "18b20.h"
#include <intrins.h>
#define uint unsigned int//宏定义
#define uchar unsigned char//宏定义
#define date P0 //数码管段选
uint temp,alarm_temp;//定义温度,设定温度
bit key_lock,chang_flag;
bit zerotemp_flag; //负温度标志位
uchar code LED[] = {0xC0,0xF9,0xA4,
0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //三位共阳极数码管0~9的断码
//数码管位定义
sbit ge = P1^3;//个位
sbit shi = P1^2;//十位
sbit bai = P1^1;//百位
sbit bell = P1^5;//蜂鸣器定义
sbit MQ = P1^6;//MQ-2定义
sbit DQ = P3^2;//18B20定义
//按键定义
sbit key0 = P3^2;
sbit key1 = P3^3;
sbit key2 = P3^4;
sbit key3 = P3^5;
void delay_ms(uint xms)
{//延时子程序
uint i,j;
for(i=xms;i>0;i--)//i=xms即延时约xms;
for(j=110;j>0;j--);
}
void delay_us(uint z)
{//微妙级延时
while(z--)
_nop_();
}
void display(uint x)
{//数码管显示子程序
//取一温度值x
uint temp1;
temp1 = x;
temp1 = temp1%1000;//使温度值不超过三位有效数
//动态显示
//显示个位
ge = 0;//开显示
date = LED[temp1%10];//将temp1的个位显示出来
delay_ms(2);//延时2ms
ge = 1;//关显示
//显示十位
shi = 0;//开显示
date = LED[temp1%100/10]&0x7f; //将temp1的十位显示出来,并显示小数点dp位
delay_ms(2);//延时2ms
shi = 1;//关显示
//显示百位
bai = 0;//开显示
date = LED[temp1/100];//将temp1的百位显示出来
delay_ms(2);//延时2ms
bai = 1; //关显示
}
void alarm(void)
{//报警子程序
if((temp>alarm_temp)|(MQ == 0))//如果温度大于设定值或MQ2=0
{
bell = 0;//蜂鸣器响
}
else
bell = 1;//蜂鸣器不响
}
/*****************18B20程序******************/
void fuwei(void)
{//18B20复位
DQ = 0;
delay_us(50); //600us
DQ = 1;
delay_us(5); //70us
}
uchar read_18B20(void)
{//从18B20读取8位数据
uchar i,dat; //从最低位开始接收
for(i = 0;i<8;i++)
{
dat>>=1; //数据右移一位
DQ = 0;
_nop_(); //延时1us
DQ = 1; //释放总线
_nop_(); //延时2us后在读取,不然读取值会紊乱,很关键!!!
_nop_();
if(DQ)
dat|=0x80; //如果接收到的是1,则最高位置为1
delay_us(2); //延时40us
}
return dat;
}
void write_18B20(uchar dat)
{//对18B20写8位数据
uchar i;
for(i = 0;i<8;i++)
{
DQ = 0;
_nop_();//延时10us
DQ = (bit)(dat&0x01); //从最低位开始发送
dat>>=1; //右移一位
delay_us(1); //延时40us
DQ = 1; //释放总线
}
}
void changetemp(void)
{//温度值转换
uint Temp_L,Temp_H;
Temp_L = read_18B20();//读取低八位
Temp_H = read_18B20();//读取高八位,当温度为负数时 temp(7~4)为1,反之为0
if(((bit)(Temp_H&0x80)))
{
zerotemp_flag = 1; //温度为负数标志位
//负温度计算
Temp_H &= 0x0f;
temp = (Temp_H<<8|Temp_L)*0.625;
}
temp = (Temp_H<<8|Temp_L)*0.625; //保存一位小数
}
void read_temp(void)
{//从18B20读取温度
fuwei(); //复位
delay_us(10); //延时
write_18B20(0xcc);//跳过读取序列号
write_18B20(0x44);//开始转换温度
fuwei(); //复位
delay_us(10); //延时
write_18B20(0xcc);//跳过读取序列号
write_18B20(0xbe);//读暂存指令
changetemp(); //读取转换温度
fuwei(); //复位
}
int main(void)
{//主程序
alarm_temp = 300;//设定温度初始值
read_temp();//18b20测温
delay_ms(500);//延迟500ms
while(1)
{
read_temp();//18b20测温
display(temp);//显示测到的温度
alarm();//报警
if(!key0)//如果key0=0,则进入温度修改状态
{
delay_ms(2);//延迟2ms,消抖
if(!key0)//如果key0=0,则确定键按下,显示温度
chang_flag = 1;
}
while(chang_flag)
{
if(key1&key2)
key_lock = 1;//如果key1&key2=1,则无效
if(!key1)
{
delay_ms(2);//延迟2ms,消抖
if(!key1)
{
if(key_lock)
{
alarm_temp+=10; //alarm_temp+10=alarm_temp(温度加1)
if(alarm_temp>990)//如果数码管前两位大于99,则清零
alarm_temp = 0;
key_lock = 0;
}
}
}
if(!key2)
{
delay_ms(2);//延迟2ms,消抖
if(!key2)
{
if(key_lock)
{
alarm_temp-=10; //alarm_temp+10=alarm_temp(温度减1)
if(alarm_temp>1000)//如果三位数码管都是0,则减一后变为990
alarm_temp = 990;
key_lock = 0;
}
}
}
if(!key3)
{
delay_ms(2);//延迟2ms,消抖
if(!key3)
{
if(key_lock)
{
chang_flag = 0;
key_lock = 0;
}
}
}
display(alarm_temp);//显示设定温度
}
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1