先出手寫的代碼,代碼分析還需要一段時間,不難,大家認真寫。
#include <STC15F2K60S2.H>
#include "Seg.h"
#include "LED.h"
#include "Key.h"
#include "DS1302.h"
#include "DS18B20.h"idata unsigned char DS18B20_Flag = 0; //DS18B20采集標志位,為1開始采集
idata unsigned char DS1302_Slow_Down; //DS1302實時時鐘讀取延時
idata unsigned char Seg_Slow_Down; //數碼管延時變量
idata unsigned char Key_Slow_Down; //按鍵延時變量
idata unsigned char Seg_Buf[8]={10,10,10,10,10,10,10,10}; //數碼管顯示內容
idata unsigned char Seg_Scan; //數碼管掃描
idata unsigned char LED_Buf[8]={0,0,0,0,0,0,0,0}; //LED亮滅數據
idata unsigned char Key_Val,Key_Down,Key_Up,Key_Old; //按鍵參數
unsigned char Time[3]={23,59,50}; //存儲時間
idata unsigned char Temper; //溫度unsigned char Seg_Show_Mode; //數碼管顯示模式
idata unsigned char Gather_Time[4] = {1,5,30,60}; //設置采集時間數組
idata unsigned char Gather_Time_Index; //設置采集時間指針,用于變化采集時間
idata unsigned char Real_Gather_Time; //采集時間,將設置值傳給Real_Gather_Timeidata unsigned int Time_1000ms; //計時1s,用于設計時鐘界面1s閃爍
idata unsigned char Time_1000_Flag; idata unsigned char Temper_Gather[10]; //采集溫度數據
idata unsigned char Temper_Gather_Index; //溫度數組指針
idata unsigned int Time_1000_Gather; //用于采集界面計時
idata unsigned char Count; //1s變化一次,相當與秒計時器idata unsigned char LED_Disable_Flag; //按下按鍵6可以開始展示溫度,同時熄滅LED,LED_Disable_Flag == 1時表示熄滅
idata unsigned int Time_1000_LED; //單獨設計LED周期閃爍,防止4T判斷時周期錯誤
idata unsigned char Time_1000_LED_Flag;void System_Init() //系統初始化
{unsigned char temp;//關閉所有LEDP0 = 0xff;temp = P2 & 0x1f;temp = temp | 0x80;P2 = temp;temp = P2 & 0x1f;P2 = temp;//關閉外設P0 = 0x00;temp = P2 & 0x1f;temp = temp | 0xa0;P2 = temp;temp = P2 & 0x1f;P2 = temp;}//定時器一初始化,自己加上EA = 1;ET1 = 1;
void Timer1_Init(void) //1毫秒@12.000MHz
{AUXR &= 0xBF; //定時器時鐘12T模式TMOD &= 0x0F; //設置定時器模式TL1 = 0x18; //設置定時初始值TH1 = 0xFC; //設置定時初始值TF1 = 0; //清除TF1標志TR1 = 1; //定時器1開始計時EA = 1; //打開總中斷ET1 = 1; //打開定時器一中斷允許位
}void Key_Proc() //按鍵處理函數
{if(Key_Slow_Down <20) return; //按鍵減速Key_Slow_Down = 0;Key_Val = Key_Read(); //讀取鍵碼值Key_Down = Key_Val & (Key_Old ^ Key_Val); //判斷按下Key_Up = ~Key_Val & (Key_Old ^ Key_Val); //判斷松開Key_Old = Key_Val; //判斷長按switch(Key_Down){case 4: //切換采集間距按鍵if(Seg_Show_Mode == 0){LED_Disable_Flag = 0; //復位LED_Disable_Flagif(++Gather_Time_Index == 4) //選擇采集時間Gather_Time_Index = 0;}break;case 5: //確定采集時間,開始采集if(Seg_Show_Mode == 0){Real_Gather_Time = Gather_Time[Gather_Time_Index]; //確定采集時間Gather_Time_Index = 0;Seg_Show_Mode = 1; //開始采集}break;case 6: //開始展示數據if(Seg_Show_Mode == 2){LED_Disable_Flag = 1;if(++Temper_Gather_Index == 10)Temper_Gather_Index = 0;}break;case 7: //重新確認采集時間,重新開始采集if(Seg_Show_Mode == 2){Seg_Show_Mode = 0;Temper_Gather_Index = 0;Time_1000_Gather = 0;Count = 0;}break;}
}void Seg_Proc() //數碼管處理函數
{if(Seg_Slow_Down <100) return; //減速Seg_Slow_Down = 0;switch(Seg_Show_Mode){case 0: //采集時間界面Seg_Buf[0] = Seg_Buf[1] = Seg_Buf[2] = Seg_Buf[3] = Seg_Buf[4] = 10; //熄滅Seg_Buf[5] = 11; //-Seg_Buf[6] = Gather_Time[Gather_Time_Index]/10%10;Seg_Buf[7] = Gather_Time[Gather_Time_Index]%10;break;case 1: //時間顯示界面(界面二)Seg_Buf[0] = Time[0]/10%10;Seg_Buf[1] = Time[0]%10;Seg_Buf[2] = Time_1000_Flag ? 11:10; //閃爍Seg_Buf[3] = Time[1]/10%10;Seg_Buf[4] = Time[1]%10;Seg_Buf[5] = Time_1000_Flag ? 11:10; //閃爍Seg_Buf[6] = Time[2]/10%10;Seg_Buf[7] = Time[2]%10;break;case 2: //數據顯示界面(界面三)Seg_Buf[0] = 11; //-Seg_Buf[1] = Temper_Gather_Index/10%10; //索引值Seg_Buf[2] = Temper_Gather_Index%10;Seg_Buf[3] = Seg_Buf[4] = 10;Seg_Buf[5] = 11; //-Seg_Buf[6] = Temper_Gather[Temper_Gather_Index]/10%10; //采集數據Seg_Buf[7] = Temper_Gather[Temper_Gather_Index]%10;break;}
}void LED_Proc() //LED處理函數
{LED_Buf[0] = (Seg_Show_Mode == 2) & (LED_Disable_Flag == 0) & (Time_1000_LED_Flag) ;//當處于界面二時采集數據完成,自動跳轉界面三(顯示界面),此時按下S6(LED_Disable_Flag == 1直接熄滅)//Time_1000_LED_Flag閃爍控制//LED亮的條件,處于界面三,未按下S6,Time_1000_LED_Flag條件為真
}void DS1302_Proc() // DS1302處理函數
{if(DS1302_Slow_Down <160) return; //減速DS1302_Slow_Down = 0;DS1302_Read(); //獲取時間
}void DS18B20_Proc()
{if(DS18B20_Flag == 0) return; //未到單次采集時間,不采集DS18B20_Flag = 0; //DS18B20_Flag == 1開始采集一次,復位標志位Temper_Gather[Temper_Gather_Index] = (unsigned char)Temperature_Read(); //開始采集Temper_Gather_Index++;if(Temper_Gather_Index == 10) //采集完成,自動跳轉界面三顯示{Seg_Show_Mode = 2;Temper_Gather_Index = 0;Time_1000_Gather = 0;Count = 0;}
}void main()
{System_Init();Timer1_Init();DS1302_Write();while((unsigned char)Temperature_Read() == 85);while(1){Key_Proc();Seg_Proc();LED_Proc();DS1302_Proc();DS18B20_Proc();}
}//定時器一中斷打開---中斷標志位3
void Timer1_Routine() interrupt 3
{Seg_Slow_Down++;Key_Slow_Down++;DS1302_Slow_Down++;if(Seg_Show_Mode == 2 && (LED_Disable_Flag == 0)) //處于界面三且未按下S6,開始閃爍{if(++Time_1000_LED == 1000){Time_1000_LED = 0;Time_1000_LED_Flag ^=1; }}else //不滿足則清空計時{Time_1000_LED = 0;}if(++Time_1000ms == 1000) //設計時間顯示界面閃爍{Time_1000ms = 0;Time_1000_Flag ^=1; }if(Seg_Show_Mode == 1) //處于時間顯示界面,開始采集數據{if(++Time_1000_Gather == 1000) //計時{Count++; //秒計時器Time_1000_Gather = 0;if(Count == Real_Gather_Time) //當秒計時器達到采集時間間隔{Count = 0;DS18B20_Flag = 1; //開始溫度采集}}}if(++Seg_Scan == 8) Seg_Scan = 0;if(Seg_Buf[Seg_Scan] > 20) //判斷帶小數點的數據Seg_Disp(Seg_Scan,Seg_Buf[Seg_Scan]-',',1);elseSeg_Disp(Seg_Scan,Seg_Buf[Seg_Scan],0);LED_Disp(LED_Buf); //LED掃描
}