下面這個是溫度與煙霧傳感器的程序,可以實現讀取溫度、調溫度的報警值,當溫度或者煙霧傳感器達到設定值后蜂鳴器會報警。現在我想讓他實現報警的時候繼電器也通電,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);//顯示設定溫度
- }
- }
- }
復制代碼
|