|
分享一個18年做的 ,定時插座,掉電可以保存上次設置的定時時間,顯示為數(shù)碼管顯示,驅動繼電器吸合。附上源程序代碼。
主體流程圖.jpg.jpeg (157.83 KB, 下載次數(shù): 35)
下載附件
2020-6-15 12:55 上傳
單片機源程序如下:
#include <stdio.h>
#include <Key.h>
#include <Usart.h>
#include <Timer.h>
#include "Led.h"
#include "eeprom.h"
sbit SupplyPower = P3^3;
#define OpenPower 0
#define ShutPower 1
typedef struct
{
//小時計數(shù)器
char Hour;
//分鐘計數(shù)器
char Minute;
//volatile char Seconds;
}TimeDef;
/*
void delay( void )
{
unsigned int x;
unsigned int y;
for(x= 0; x<400;x++)
for(y= 0;y<2000;y++);
}*/
void main(void) //主函數(shù)
{
TimeDef setting = { 0,0}; //小時分鐘位分離
unsigned char KeyCode;
static char LedFlag = 0;
//保存時間數(shù)據(jù)
static unsigned int SaveData = 0;
//static int TimVar = 0;
//開始啟動打開電源
SupplyPower = OpenPower;
InitUART(); //串口初始化
SendStr("\r\n定時器插座啟動" );
// SendU16(24856);
TimerInit() ;//定時器初始化
InitButtonVar(); //按鈕初始化
//讀取保存的數(shù)據(jù)
SaveData = ( ( (unsigned int)IapReadByte(0) ) << 8 ) + IapReadByte(1) ;
SendStr("\r\n啟動讀取上次存儲的值SaveData = " );
SendU16(SaveData);
SendStr(";" );
//初次更新顯示
setting.Hour = SaveData/100;
setting.Minute = SaveData % 100;
if(setting.Hour > 99)
setting.Hour = 0;
if(setting.Minute > 59)
setting.Minute = 0;
Led_Dis_Var = setting.Minute + setting.Hour*100;
while(1)
{
Timer_Shaft_Increasing(); //計時器更新時間
//按鍵掃描
KeyPro();
//讀取按鍵值,讀一個數(shù)據(jù),會自動移位一次
KeyCode = GetKey();
//大于零表示有按鈕按下
if (KeyCode > 0)
{
//組合短按
if(KeyCode == K1AndK2_Choose)
{
//設置循環(huán)
LedFlag++;
if(LedFlag >= 3 )
{
//Led_Flicker_Minute_Dis 這個狀態(tài)的下一個狀態(tài),保存數(shù)據(jù)
if(LedFlag == Led_Flicker_Minute_Dis + 1)
{
//保存數(shù)據(jù)
SaveData = ((unsigned int)setting.Minute) + ((unsigned int)setting.Hour) * 100;
/*第一扇區(qū)其實地址 0000h 結束地址1ffh
必須要先刪除扇區(qū)才能寫入 */
IapEraseSector(IAP_ADDRESS); //Erase current sector
//0地址寫入高8位
IapProgramByte(0, (unsigned char)(SaveData>>8) );
//1地址寫入低8位
IapProgramByte(1,(unsigned char)(SaveData) );
}
//Led_Flicker_Second_Dis 啟動定時器倒計時狀態(tài)下按了組合按鍵
//溢出判斷,由倒計時狀態(tài)變成停止狀態(tài)
if( (LedFlag == Led_Flicker_Second_Dis + 1) || (LedFlag == Time_Go + 1) )
{
//重新賦予新值
setting.Hour = SaveData/100;
setting.Minute = SaveData % 100;
}
LedFlag = 0;
}
}
else
if(KeyCode == K1_DataAdd)
{
if(LedFlag == Led_Flicker_Hour_Dis) //進入到這個設置界面按鈕才有效
{
++setting.Hour;
if(setting.Hour > 99)
{
setting.Hour = 0;
}
}
else
if( LedFlag == Led_Flicker_Minute_Dis) //進入到這個設置界面按鈕才有效
{
++setting.Minute;
if(setting.Minute > 59)
{
setting.Minute = 0;
}
}
}
else
if(KeyCode == K2_DataSubtract)
{
if(LedFlag == Led_Flicker_Hour_Dis) //進入到這個設置界面按鈕才有效
{
--setting.Hour ;
if(setting.Hour < 0)
{
setting.Hour = 99;
}
}
else
if( LedFlag == Led_Flicker_Minute_Dis) //進入到這個設置界面按鈕才有效
{
--setting.Minute;
if(setting.Minute < 0)
{
setting.Minute = 59;
}
}
}
else
//組合長按
if(KeyCode == K1AndK2_LongChoose)
{
if(LedFlag == Led_Flicker_No_Dis ) //表示在不閃爍界面
{
//將需要計時的時間計算成秒
Count_Second_Sys = ((long)setting.Hour) * 60 * 60 + ((long)setting.Minute) * 60; //需要強制轉換,不然計算出來的值 是char型
if(Count_Second_Sys > 0) //設置的時間大于0
{
LedFlag = Led_Flicker_Second_Dis ; //秒點閃爍倒計時開
//設置Count_Second_Sys初始時間
}
}
}
//更新顯示
Led_Dis_Var = setting.Minute + setting.Hour*100;
}
//定時器啟動,倒計時計時
if(LedFlag == Led_Flicker_Second_Dis)
{
//if(Count_mS )
//設置的定時時間到,啟動的時候必須Count_Second_Sys > 0;
if(Count_Second_Sys == 0)
{
Count_Second_Sys = 0; //清除計時器
LedFlag = Time_Go; //定時時間到,進入到循環(huán)等待
//定時時間到,關閉數(shù)碼管,關閉繼電器
CloseLed(); //關閉數(shù)碼管
//關閉電源供電
SupplyPower = ShutPower;
}
else
//定時 時間 沒有到 繼續(xù)定時
if(Count_Second_Sys != 0)
{
setting.Hour = Count_Second_Sys/60/60;
setting.Minute = Count_Second_Sys/60%60;
}
Led_Dis_Var = setting.Minute + setting.Hour*100;
}
Led_Dis(LedFlag); //掃描顯示
}
}
Snipaste_2020-06-15_13-35-10.jpg (23.52 KB, 下載次數(shù): 29)
下載附件
2020-6-15 13:35 上傳
|
-
51hei.png
(10.17 KB, 下載次數(shù): 32)
下載附件
2020-6-15 18:16 上傳
-
-
keil.zip
2020-6-15 12:57 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
2 MB, 下載次數(shù): 44, 下載積分: 黑幣 -5
51單片機定時插座,帶記憶設置
評分
-
查看全部評分
|