下面这个是温度与烟雾传感器的程序,可以实现读取温度、调温度的报警值,当温度或者烟雾传感器达到设定值后蜂鸣器会报警。现在我想让他实现报警的时候继电器也通电,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);//显示设定温度
- }
- }
- }
复制代码
|