原理图和程序对不上,按键和继电器画错了。
#include <STC8G.H> //此文件中定义了单片机的一些特殊功能寄存器
#include "STC8G_EEPROM.h" //STC8G内部EEPROM驱动
sbit anjian1=P1^7; //按键引脚定义
sbit jidianqi=P1^0; //继电器引脚定义
typedef unsigned char u8; //无符号字符形数据类型进行声明定义 定义名称u8 所占位数8位 范围0~255
typedef unsigned int u16; //无符号整形数据类型进行声明定义 定义名称u16 所占位数16位 范围0~65535
u8 fen,miao; //分 秒 变量
bit ajyxzz1,EP_num; //条件允许终止 用于每次操作只允许执行一次 防止重复执行
u16 weimiao;
/*1T 12M晶振 延时函数 Delay_ms(1)时大约1ms*/
void Delay_ms(u16 ms)
{
u8 i,j;
while(ms--)
{
for(i=0; i<7; i++)
for(j=0; j<99; j++);
}
}
/*io端口配置*/
void STCIO_in()
{
P1M0 = 0x00;
P1M1 = 0x00; //配置P1为准双向输出输入
P3M0 = 0x00;
P3M1 = 0x00; //配置P3为准双向输出输入
//P5M0 = 0x00;
//P5M1 = 0x00; //配置P5为准双向输出输入
}
/*定时计数器配置*/
void Timer0_Init(void) //1毫秒@12.000MHz 16位自动重装
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x20; //设置定时初始值
TH0 = 0xD1; //设置定时初始值
TF0 = 0; //清除TF0标志
//TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA=1; //定时器总开关
}
/*主函数*/
void main()
{
u8 nj_num; //按键累计变量
u16 cn_num; //按键长短按累计变量
u16 fne_num; //分钟累计变量
STCIO_in(); //io端口初始化
jidianqi=1; //关闭继电器 此时断电
P3=0x00; //开机LED全捡 开
Delay_ms(1000); //延时约1秒
P3=0xff; //开机LED全捡 关
Timer0_Init(); //定时计数器初始化
while(1)
{
if(anjian1==0)//判断时加按键是否按下
{
Delay_ms(5); //延时消抖
if(anjian1==0) //再次判断时加按键是否按下
{
ajyxzz1=0; //按键条件复位 等待下一次按键操作
cn_num++; //长按累计器开始计数
if(cn_num>1000) //长按操作 约3秒
{
P3=0xff;
if(EP_num==0) //这里添加一个条件允许终止 不能它一直重复擦除写数据
{
IapErase(0x0400); //擦除EEPROM
IapProgram(0x0400, nj_num); //写数据到EEPROM
EP_num=1; //数据写好了 马上终止 防止程序循环重复执行
}
Delay_ms(200);
}
}
}
else
{
if(cn_num>0&&cn_num<500&&ajyxzz1==0) //短按操作
{
if(nj_num==0)
{
nj_num = IapRead(0x0400); //读EEPROM
nj_num = nj_num-1;
}
if(nj_num<12)nj_num=nj_num+1;
else(nj_num=1);
miao=0; //清零秒
fen=0; //清零分
jidianqi=0; //启动继电器 此时开始通电
TR0 = 1; //定时器开始计数
ajyxzz1=1; //执行完毕 条件终止 防止重复执行
}
cn_num=0; //按键长短按累计变量复位 等待下一次执行
EP_num=0; //EEPROM条件允许终止复位 等待下一次执行
}
if(nj_num>0)
{
switch(nj_num) //显示LED灯与时长选择
{
case 1:P3=0x7f;fne_num=60;break; //0111 1111 1小时
case 2:P3=0xbf;fne_num=120;break; //1011 1111 2小时
case 3:P3=0xdf;fne_num=180;break; //1101 1111 3小时
case 4:P3=0xef;fne_num=240;break; //1110 1111 4小时
case 5:P3=0xf7;fne_num=300;break; //1111 0111 5小时
case 6:P3=0x77;fne_num=360;break; //0111 0111 6小时 5+1
case 7:P3=0xb7;fne_num=420;break; //1011 0111 7小时 5+2
case 8:P3=0xd7;fne_num=480;break; //1101 0111 8小时 5+3
case 9:P3=0xe7;fne_num=540;break; //1110 0111 9小时 5+4
case 10:P3=0x67;fne_num=600;break; //0110 0111 10小时 5+4+1
case 11:P3=0xa7;fne_num=660;break; //1010 0111 11小时 5+4+2
case 12:P3=0xc7;fne_num=720;break; //1100 0111 12小时 5+4+3
}
if(fen==fne_num) //判断时间是否到了
{
TR0 = 0; //关闭定时器
P3 = 0xff; //关闭所有LED灯
jidianqi=1; //关闭继电器 此时断电
weimiao = 0; //毫秒清零
miao = 0; //清零秒
fen = 0; //清零分
nj_num = 0; //按键累计变量清零
}
}
}
}
/*定时器0*/
void Timer0_Isr(void) interrupt 1
{
weimiao++;
if(weimiao==1000) //1000毫秒=1秒
{
miao++; //秒
weimiao=0; //毫秒清零
if(miao==60) //60秒=1分钟
{
fen++; //分
miao=0; //分清零
}
}
} |