|
分享一个18年做的 ,定时插座,掉电可以保存上次设置的定时时间,显示为数码管显示,驱动继电器吸合。附上源程序代码。
单片机源程序如下:
#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
{
//小时计数器
char Hour;
//分钟计数器
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) //主函数
{
TimeDef setting = { 0,0}; //小时分钟位分离
unsigned char KeyCode;
static char LedFlag = 0;
//保存时间数据
static unsigned int SaveData = 0;
//static int TimVar = 0;
//开始启动打开电源
SupplyPower = OpenPower;
InitUART(); //串口初始化
SendStr("\r\n定时器插座启动" );
// SendU16(24856);
TimerInit() ;//定时器初始化
InitButtonVar(); //按钮初始化
//读取保存的数据
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();
//读取按键值,读一个数据,会自动移位一次
KeyCode = GetKey();
//大于零表示有按钮按下
if (KeyCode > 0)
{
//组合短按
if(KeyCode == K1AndK2_Choose)
{
//设置循环
LedFlag++;
if(LedFlag >= 3 )
{
//Led_Flicker_Minute_Dis 这个状态的下一个状态,保存数据
if(LedFlag == Led_Flicker_Minute_Dis + 1)
{
//保存数据
SaveData = ((unsigned int)setting.Minute) + ((unsigned int)setting.Hour) * 100;
/*第一扇区其实地址 0000h 结束地址1ffh
必须要先删除扇区才能写入 */
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 启动定时器倒计时状态下按了组合按键
//溢出判断,由倒计时状态变成停止状态
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; //定时时间到,进入到循环等待
//定时时间到,关闭数码管,关闭继电器
CloseLed(); //关闭数码管
//关闭电源供电
SupplyPower = ShutPower;
}
else
//定时 时间 没有到 继续定时
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); //扫描显示
}
}
|
评分
-
查看全部评分
|