先出手写的代码,代码分析还需要一段时间,不难,大家认真写。
#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扫描
}