📄 text1.c
字号:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define N 40 //闪烁频率控制
uchar tab[12]={0x88,0xEB,0x4C,0x49,0x2B,0x19,0x18,0xCB,0x08,0x09,0xFF,0x0A};
uchar sec=0,min=0,hou=0;
uchar chouse_display_B=0; //显示时选择哪一位闪烁
uchar on_off=0; //闪烁时亮/灭
uint sec_count=0; //判断是否到一秒记数器
uchar alarm_tab[4][2]={{0,0},{0,0},{0,0},{0,0}}; //定时数据
uchar sound;
sbit P1_6=P1^6; //调整时间按键2
sbit P1_7=P1^7; //调整时间按键1
sbit P1_0=P1^0; //开关灯控制位
sbit P1_1=P1^1; //声音开关控制
sbit P1_2=P1^2; //手动开灯
sbit P3_7=P3^7; //手动关灯
sbit P3_5=P3^5; //低功耗控制位
void delay(uint m); //声明延时函数(m*1000个机器周期时长)
void key(void); //键盘扫描函数声明
void display_2b(uchar a); //显示一位函数声明
void display_B(void); //显示一遍数据函数声明
void action_2(void); //加时调时函数声明
void action_1(void); //秒增加函数
void initiat(void); //定时器初始化函数
void clock_go(void); //记数走时函数
void alarm(void); //判断定时是否到来函数
void action_1_1(void); //定时调整函数
void light_0n_0ff_scan(void); //手动开关灯按键扫描函数
//延时函数
void delay(uint m)
{
uint i,j;
for(i=0;i<m;i++)
for(j=0;j<1000;j++); //m*1000个机器周期延时
}
//显示一位函
void display_2b(uchar a)
{
SBUF=tab[(0x0F&a)]; //送显示每位低位
while(TI==0);
TI=0;
a=(a>>4);
SBUF=tab[a]; //送显示每位高位
while(TI==0);
TI=0;
}
//显示6位函数--有闪烁第几位
void display_B(void)
{ on_off++;
if(on_off>=N*2)
on_off=0;
if(chouse_display_B<=3)
{
if(chouse_display_B==3)
if(on_off<N)
display_2b(0xAA);
else
display_2b(sec);
else
display_2b(sec);
if(chouse_display_B==2)
if(on_off<N)
display_2b(0xAA);
else
display_2b(min);
else
display_2b(min);
if(chouse_display_B==1)
if(on_off<N)
display_2b(0xAA);
else
display_2b(hou);
else
display_2b(hou);
}
else if((chouse_display_B>3)&&(chouse_display_B<=11)) //调定时时显示
{
if(chouse_display_B%2==1)
if(on_off<N)
display_2b(0xAA);
else
display_2b(alarm_tab[(chouse_display_B-4)/2][1]);
else
display_2b(alarm_tab[(chouse_display_B-4)/2][1]);
if(chouse_display_B%2==0)
if(on_off<N)
display_2b(0xAA);
else
display_2b(alarm_tab[(chouse_display_B-4)/2][0]);
else
display_2b(alarm_tab[(chouse_display_B-4)/2][0]);
display_2b(0xB0|((chouse_display_B-4)/2+1));
}
delay(2);
}
//键盘扫描函数
void key(void)
{
if(P1_7==0)
{
delay(10);
if(P1_7==0)
{
while(!P1_7);
chouse_display_B++;
if(chouse_display_B>=12)
chouse_display_B=0;
}
}
if((P1_6==0)&&(chouse_display_B)!=0) //是否处于调时状态&&加时键按下
{
delay(10);
if(P1_6==0)
{
while(!P1_6);
if(chouse_display_B<=3)
{
action_1(); //时钟增时函数
}
else if(chouse_display_B>3)
action_1_1(); //定时增时函数
}
}
}
//手动开关灯键盘扫描函数
void light_0n_0ff_scan(void)
{
if(P1_2==0)
{
delay(10);
if(P1_2==0)
{
while(!P1_2);
P1_0=0;
}
}
if(P3_7==0)
{
delay(10);
if(P3_7==0)
{
while(!P3_7);
P1_0=1;
}
}
}
//各位调时函数
void action_1(void)
{
if(chouse_display_B==1)
{
hou++;
if((hou&0x0F)>=10)
{
hou&=0xF0;
hou+=0x10;
}
if(hou>=0x24)
hou=0;
}
else if(chouse_display_B==2)
{
min++;
if((min&0x0F)>=10)
{
min&=0xF0;
min+=0x10;
}
if(min>=0x60)
{
min=0;
}
}
else if(chouse_display_B==3)
sec=0;
else
;
}
//定时调时函数
void action_1_1(void)
{
if(chouse_display_B%2==1)
{
alarm_tab[(chouse_display_B-4)/2][1]++;
if((alarm_tab[(chouse_display_B-4)/2][1]&0x0F)>=10)
{
alarm_tab[(chouse_display_B-4)/2][1]&=0xF0;
alarm_tab[(chouse_display_B-4)/2][1]+=0x10;
}
if(alarm_tab[(chouse_display_B-4)/2][1]>=0x60)
alarm_tab[(chouse_display_B-4)/2][1]=0;
}
else if(chouse_display_B%2==0)
{
alarm_tab[(chouse_display_B-4)/2][0]++;
if((alarm_tab[(chouse_display_B-4)/2][0]&0x0F)>=10)
{
alarm_tab[(chouse_display_B-4)/2][0]&=0xF0;
alarm_tab[(chouse_display_B-4)/2][0]+=0x10;
}
if(alarm_tab[(chouse_display_B-4)/2][0]>=0x24)
{
alarm_tab[(chouse_display_B-4)/2][0]=0;
}
}
}
//加时函数
void action_2(void)
{
//sec++;
if((sec&0x0F)>=10)
{
sec&=0xF0;
sec+=0x10;
}
if(sec>=0x60)
{
sec=0;
min++;
}
if((min&0x0F)>=10)
{
min&=0xF0;
min+=0x10;
}
if(min>=0x60)
{
min=0;
hou++;
}
if((hou&0x0F)>=10)
{
hou&=0xF0;
hou+=0x10;
}
if(hou>=0x24)
hou=0;
}
//时钟增时函数
void clock_go(void) //(修改原因:修改前为每运行一遍判断一次是否到达一秒和是否需要进位
// 修改后为每次中断判断是否到达一秒,每运行一次判断是否需要进位)
{
//if(sec_count>=4950) //修改前不准确,调整时依然无效,原因:程序运行一遍的时间太长,后一次判断sec_count时的值远大于前一次加1。
//{
action_2();
//sec_count=0;
//}
}
//记时中断函数
void sec_add() interrupt 1 using 1
{
sec_count++;
if(sec_count>=5000)
{
sec++;
sec_count=0;
}
}
//计数器初始化函数
void initiat(void)
{
TMOD=(TMOD&0xF0)|0x02; //设置方式(带重装8位定时器)
TH0=256-200; //记数200个时钟周期
TL0=TH0;
ET0=1; //允许定时器0中断-
TR0=1; //启动定时器0
EA=1; //全部中断允许
}
//定时查询函数
void alarm(void)
{
if((alarm_tab[0][1]==min)&&(alarm_tab[0][0]==hou)) //第一次定时(早上开灯)
{if(P1_0!=0) P1_0=0;}
if((alarm_tab[1][1]==min)&&(alarm_tab[1][0]==hou)) //第二次定时(早上关灯)
{if(P1_0!=1) P1_0=1;}
if((alarm_tab[2][1]==min)&&(alarm_tab[2][0]==hou)) //第三次定时(晚上开灯)
{if(P1_0!=0) P1_0=0;}
if((alarm_tab[3][1]==min)&&(alarm_tab[3][0]==hou)) //第四次定时(晚上关灯)
{if(P1_0!=1) P1_0=1;}
}
//主函数
void main(void)
{
P1_0=1;
initiat(); //定时器初始化函数
P1_1=0;
delay(10);
P1_1=1;
P1_0=1; //预先关灯
P3_5=1; //低功耗开关控制位初始化
while(1)
{
clock_go();
if(P3_5==0) //判断是否有市电供电
{
if(sec>(sound+1))
P1_1=1;
alarm(); //扫描是否定时到时
display_B(); //显示一遍数据
key(); //键盘扫描函数
light_0n_0ff_scan(); //扫描是否有手动开关灯按键按下
}
else
{
display_2b(0xAA); //低供耗时全灭显示
P1_0=1; //低供耗时禁止开灯
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -