📄 souce.txt
字号:
#include <reg51.h>
#include <intrins.h>
#include <absacc.h>
#define uchar unsigned char
#define PA XBYTE[0x9000]
#define PB XBYTE[0x9100]
#define PC XBYTE[0x9200]
#define PS XBYTE[0x9300]//8255控制口地址
#define PD XBYTE[0x8800]//138地址
#define bell XBYTE[0x8000]
bit zd_flag;//整点报时标志
uchar zd_counter;//整点计数器2秒
bit bell_flag;
bit alarm_d,alarm_flag;
uchar counter_a;//闹钟报警时间计数
uchar alarm_arry[7]={0};
uchar Time[7]={7,8,28,20,50,10,2}; //时间数组
uchar counter_0=0; //调时位计数器
bit Flag; //1秒时间到
bit ren_year; //是否是闰年标志
uchar bcd_arry[2]={0,0};
uchar code_sure;//调时送数码
uchar arry_num;//调时数组号码
sbit RS=P3^2;//LCM控制口
sbit RW=P3^3;
sbit E=P3^4;
sbit P17=P1^7;
uchar s_char3[9]={'f','i','g','h','t','i','n','g','\0'};
uchar s_char1[6]={'h','a','p','p','y','\0'};//字符串
uchar s_char2[5]={'w','e','e','k','\0'};
//***************key
uchar lock_key();
bit key_check();
uchar get_key_code();
bit lock_status=1;
uchar m_code=0;
uchar lock_code;
uchar s_lock_code=17;//密码
//void delay_key(unsigned int N);
//88888888888888 LCM
void lcm_init();
void w_commend(uchar commend);//写入命令
void busy();//忙判断
void w_data(uchar _data);//写数据
void w_s_char(uchar n,uchar char_arry[5]);//写字符串
void r_ac_add();//读取LCM中的ACC地址
void find_add();//查找调时位以闪烁光标提示
//8888888888888888888888
void time_change();
void bcd_turn(uchar x);//BCD转换
void sipo(uchar s_buffer_arry[7]);//输出程序
void timer0();
void counter_0_d();//计数器处理程序
void time_set();
void month_28();
bit year_deal();
uchar month_deal();
void delay50ms();
void time_set();
void time_send();
void time_set_10(uchar i);
void time_set_ge(uchar i);
void alarm_set();
bit time_time();
void alarm_deal();
void main()
{
TMOD=0x22;
TH0=0x1a;
TL0=0x1a;
ET0=1;
EA=1;
TR0=1;//T0初始化
PS=0x9b;//8255初始化
lcm_init();
lcm_init();
for(;;)
{
bell=0xff;
switch(lock_key())
{
case 15:time_set();break;//进入调时
case 19:alarm_set();break;//进入闹钟设置
}
if(time_time()!=1)
alarm_deal();
if(zd_flag==1)
{
if(zd_counter<1)//报时
bell=0;
else
{
zd_counter=0;
zd_flag=0;
bell=0xff;
}
}
w_commend(0x0c);//关光标
sipo(Time);
}
}
/*==================时间更新=====================*/
void time_change()
{
Time[5]=Time[5]+1;
if(Time[5]>59)
{
Time[4]=Time[4]+1;
Time[5]=0;
if(Time[4]>59)
{
Time[3]=Time[3]+1; /*时分秒日进位*/
Time[4]=0;
if(Time[3]>23)
{
Time[2]=Time[2]+1;
Time[3]=0;
if(Time[2]==month_deal()+1)
{
Time[1]=Time[1]+1;
Time[2]=1;
if(Time[1]>12)
{
Time[0]=Time[0]+1;
Time[1]=1;
if(Time[0]>99) Time[0]=0;
}
}
}
}
}
if(Time[5]==59&&Time[4]==59&&Time[3]==23)//week
{
Time[6]=Time[6]+1;
if(Time[6]>7)
Time[6]=1;
}
if(Time[5]==0&&Time[4]==0)
zd_flag=1;
}
/*==========显示程序============*/
void sipo(uchar s_buffer_arry[7])
{
uchar i;
w_commend(0xc9);
w_s_char(5,s_char1);//显示happy
w_commend(0x89);
w_s_char(4,s_char2);//显示字符week
w_commend(0x8d);
w_data(s_buffer_arry[6]+0x30);
//bcd_turn(s_buffer_arry[6]);//先进行BCD转换
//w_data(bcd_arry[1]+0x30);
w_commend(0x80);
for(i=0;i<6;i++)
{
if(i<3)//显示年月日
{
bcd_turn(s_buffer_arry[i]);//先进行BCD转换
w_data(bcd_arry[0]+0x30);
w_data(bcd_arry[1]+0x30);
if(i<2)// 最后一个不显示间隔符
w_data(0x2d);//间隔符
}
else//第二行显示时间
{
if(i==3)
w_commend(0xc0);
bcd_turn(s_buffer_arry[i]);
w_data(bcd_arry[0]+0x30);//先进行BCD转换
w_data(bcd_arry[1]+0x30);
if(i<5)
w_data(0x3a);//间隔符
}
}
}
/*========================T0中断=============================*/
void timer0() interrupt 1
{
unsigned int sndacc; /*秒累加器*/
sndacc=sndacc+1;
if(sndacc==4000)
{
Flag=1;
sndacc=0;
bell_flag=!bell_flag;
if(zd_flag==1)
zd_counter=zd_counter+1;
if(alarm_d==1)
counter_a=counter_a+1;
time_change();
Flag=0;
}
}
/*====================timeset======================*/
void time_set()
{
if(alarm_flag!=1)//如果不是闹钟时间设置,则停止定时器工作
TR0=0;
do
{
while(key_check()==0);/**********等待下一个键按下,避免虚跳********/
switch(get_key_code())
{
case 14:{find_add();time_send();};break;
case 13:counter_0=0;break;
case 15:{counter_0_d();w_commend(0x0e);/*sipo(Time);*/find_add();};break;//关光标闪烁
}
//while(key_check()==0);/**********等待下一个键按下,避免虚跳********/
if(get_key_code()<10)
{
w_commend(0x0e);
code_sure=get_key_code();//对输入调时数字的处理
find_add();
w_data(code_sure+0x30);
}
}
while(counter_0!=0);
TR0=1;
lcm_init();
}
//****************计数器处理counter_0_d******************************
void counter_0_d()
{
counter_0=counter_0+1;
if(counter_0>13)
counter_0=1;
}
/*
//***********************************判断输入数字是否合理
bit judge_time()
{
if((Time[0]>99||Time[1]>12||Time[2]>month_deal()||Time[3]>23||Time[4]>59||Time[5]>59)==1)
return 0;
else
return 1;
}
*/
//********************time_send***************************
void time_send()
{
switch(counter_0)
{
case 1:{arry_num=0;time_set_10(arry_num);};break;
case 2:{arry_num=0;time_set_ge(arry_num);};break;
case 3:{arry_num=1;time_set_10(arry_num);};break;
case 4:{arry_num=1;time_set_ge(arry_num);};break;
case 5:{arry_num=2;time_set_10(arry_num);};break;
case 6:{arry_num=2;time_set_ge(arry_num);};break;
case 7:{arry_num=6;time_set_ge(arry_num);};break;
case 8:{arry_num=3;time_set_10(arry_num);};break;
case 9:{arry_num=3;time_set_ge(arry_num);};break;
case 10:{arry_num=4;time_set_10(arry_num);};break;
case 11:{arry_num=4;time_set_ge(arry_num);};break;
case 12:{arry_num=5;time_set_10(arry_num);};break;
case 13:{arry_num=5;time_set_ge(arry_num);};break;
}
}
//**********************time_set_10(uchar i)***************************
void time_set_10(uchar i) //当调时位为10位时的处理智育
{
if(alarm_flag==1)//进入了设置闹钟时间
alarm_arry[i]=alarm_arry[i]%10+10*code_sure;
else
Time[i]=Time[i]%10+10*code_sure;
}
//********************time_set_ge(uchar i)**********************************
void time_set_ge(uchar i)
{
if(alarm_flag==1)
alarm_arry[i]=alarm_arry[i]-alarm_arry[i]%10+code_sure;
else
Time[i]=Time[i]-Time[i]%10+code_sure;
} //当调时位为个位时的处理智育
//*************************************闹钟***********
void alarm_set()
{
//uchar i;
alarm_flag=1;
//for(i=0;i<7;i++)
//alarm_arry[i]=Time[i];//显示当前时间
sipo(alarm_arry);//显示上次闹钟时间
time_set();
if(time_time()!=1)//如果没有调闹钟,则改变一下时间,避免退出时直接闹钟时间到
alarm_arry[5]=Time[5]-1;
alarm_flag=0;
}
//********************time_time闹钟对时**********
bit time_time()
{
uchar i;
for(i=0;i<6;i++)
{
if(alarm_arry[i]!=Time[i])//比较
{
return 1;
break;
}
}
}
//********************
void alarm_deal()
{
w_commend(0x01);
alarm_d=1;
while(counter_a<10)
{
if(get_key_code()==13)//如果按下退出键,则退出报警
counter_a=10;
if(bell_flag==1)
bell=0;//蜂鸣器响,响一秒,停一秒
else
bell=0xff;
do
{
w_commend(0x80);
w_s_char(8,s_char3);//闹钟报警期间显示字符串,只显示一次,避免屏闪
}
while(counter_a>10);
}
alarm_d=0;
counter_a=0;
}
/*********月处理************/
uchar month_deal()
{
switch(Time[1])
{
case 1:return 31;break;
case 2:{if(year_deal()) return 28;
else return 29;}break;
case 3:return 31;break;
case 4:return 30;break;
case 5:return 31;break;
case 6:return 30;break;
case 7:return 31;break;
case 8:return 31;break;
case 9:return 30;break;
case 10:return 31;break;
case 11:return 30;break;
case 12:return 31;break;
default:return 0;
}
}
/******************闰年判断,是闰年返回1,否则返回0********************/
bit year_deal()
{
unsigned int year;
year=2000+Time[0];
if((year%100!=0)&&(year%4==0)||(year%100==0)&&(year%4==0))
return 1;
else
return 0;
}
/********************BCD转换*************************/
void bcd_turn(uchar x)
{
bcd_arry[0]=x/10;
bcd_arry[1]=x%10;
}
//***********延时程序约10MS***************
void delay50ms()
{
unsigned char i,j;
for(i=0;i<251;i++)
{
for(j=0;j<40;j++);
j=0;
}
i=0;
}
/*8888888888888888 LCM 显示88888888888888888888888888888
888888888888888888888888888888888888888888888888888888*/
void lcm_init()
{
/*清屏并光标肝椿*/
w_commend(0x01);
//w_commend(0x03);
/*设置显示模式:8位2行5x7点阵*/
w_commend(0x3c);
/*显示器开、光标开、光标允许闪烁*/
w_commend(0x0f);
/*文字不动,光标自动右移*/
w_commend(0x06);
}
void w_commend(uchar commend)/******写入命令子程序*****/
{
P1=commend;
RS=0;
RW=0;
E=0;
busy();
E=1;
}
/************延时程序****************/
void busy()
{
P1=0xff;
RS=0;
RW=1;
E=0;
_nop_();
E=1;
while(P17);
}
/************写入数据***************/
void w_data(uchar _data)
{
P1=_data;
RS=1;
RW=0;
E=0;
busy();
E=1;
}
/*********写入字符串*******/
void w_s_char(uchar n,uchar char_arry[16])
{
uchar i;
for(i=0;i<n;i++)
{
w_data(char_arry[i]);
r_ac_add();/*调用换行程序*/
}
}
/************************当写入字符串超过第一行时,进行换行********/
void r_ac_add()
{
uchar temp;
RS=0;
RW=1;
E=0;
_nop_();
E=1;
busy();
temp=P1;
temp=temp&0x7f;
if(temp==0x10)/*换行*/
w_commend(0xc0);
}
//************************查询调时位地址,并使光标移到该位*********
void find_add()
{
w_commend(0x0e);
/*显示器开、光标开、光标不允许闪烁*///????????????????????????????????????????????????????????
switch(counter_0)
{
case 1:w_commend(0x80);break;
case 2:w_commend(0x81);break;
case 3:w_commend(0x83);break;
case 4:w_commend(0x84);break;
case 5:w_commend(0x86);break;
case 6:w_commend(0x87);break;
case 7:w_commend(0x8d);break;//alarm
case 8:w_commend(0xc0);break;
case 9:w_commend(0xc1);break;
case 10:w_commend(0xc3);break;
case 11:w_commend(0xc4);break;
case 12:w_commend(0xc6);break;
case 13:w_commend(0xc7);break;
}
}
//*********************************键盘程序**********************
//**************************键盘密码****************************
uchar lock_key()
{
uchar i;
if(lock_status==1)//*若为1,则需要解码*******
{
m_code=get_key_code();
if(m_code==16)
{
for(i=0;i<3;i++)
{
while(key_check()==0);//**********等待下一个键按下,避免虚跳********
m_code=get_key_code();
lock_code=m_code;//因为下面改变了M_CODE的值,所以要先保存好有效的值
if(lock_code!=s_lock_code)
break;
}
m_code=0;//***************************改变m_code值,避免在if(m_code==0x13)中循环************
if(lock_code==s_lock_code)
{
lock_status=0;
}
}
return 0;
}
else
{
m_code=get_key_code();
if(m_code==16)
{
while(key_check()==0);
m_code=get_key_code();
if(m_code==16) //********按两下锁上键盘**********
{
lock_status=1;
m_code=0;
}
}
return(m_code);
}
}
/*
//*****************延时时间约为(16*N+24)us******************
void delay_key(unsigned int N)
{
int i;
for(i=0;i<N;i++);
}
*/
//**********************key_check*******
bit key_check()
{
uchar PB_temp;
PD=0x0;
_nop_();
PB_temp=PB;
PB_temp=PB_temp&0x0f;
if(PB_temp==0x0f)
{
delay50ms();
PB_temp=PB;
PB_temp=PB_temp&0x0f;
if(PB_temp==0x0f)
return(0);
else
return(1);
}
}
//**********************************uchar get_key_code()************
uchar get_key_code()
{
uchar PD_temp,PB_temp;
uchar PB_code,key_code;
uchar i;
PD_temp=0x7f;
for(i=0;i<5;i++)
{
PD_temp=_crol_(PD_temp,1);
PD=PD_temp;
_nop_();
PB_temp=PB;
PB_temp=PB_temp&0x0f;
if(PB_temp!=0x0f)
{
while(key_check()); /*等待键松开*/
PB_temp=~PB_temp;
switch(PB_temp)
{
case 0xf1:PB_code=0;break;
case 0xf2:PB_code=1;break;
case 0xf4:PB_code=2;break;
case 0xf8:PB_code=3;break;
}
key_code=i*4+PB_code;
}
}
return(key_code);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -