#pragma small
#include <reg52.h>
#include <ABSACC.H>
#include <intrins.h> //包含了_nop_()
//*************************************************************************
//以下为常量定义
//*************************************************************************
//键值列表
#define Key1 0xE7
#define Key2 0xEB
#define Key3 0xED
#define Key4 0xEE
#define Key5 0xD7
#define Key6 0xDB
#define Key7 0xDD
#define Key8 0xDE
#define Key9 0xB7
#define Key10 0xBB
#define Key11 0xBD
#define Key12 0xBE
#define Key13 0x77
#define Key14 0x7B
#define Key15 0x7D
#define Key16 0x7E
//*************************************************************************
//以下为函数声明
//*************************************************************************
void key_scan(void);
void clock24(void);
void clock12(void);
void disp_h(void);
void disp_m(void);
//*************************************************************************
//以下为变量等定义
//*************************************************************************
//代码(MOVC结构)
code unsigned char led_seg[] ={ //LED显示段码
0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,
0x40,0x79,0x24,0x30,0x19,
0x12,0x02,0x78,0x00,0x10,
0x88,0x8c}; //A&P
code unsigned char led_seg_fan[]={ //LED显示段码_反
0xc0,0xf9,0x64,0x70,0x59,
0x52,0x42,0xf8,0x40,0x50,
0x80,0xb9,0x24,0x30,0x19,
0x12,0x02,0xb8,0x00,0x10};
code unsigned char led_loc[] ={ //LED显示位码
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char alarm_m[16]={ //闹钟时间点
99,99,99,99,99,99,99,99,
99,99,99,99,99,99,99,99};
unsigned char alarm_h[16]={
99,99,99,99,99,99,99,99,
99,99,99,99,99,99,99,99};
//------------------------------------------------------------------------
//变量定义
unsigned char disp_buf[8]; //显示缓存第0位为最低位
unsigned char disp_cnt; //显示刷新位置计数,0~8
unsigned char cnt_2500us,cnt_100ms,cnt_500ms;
unsigned int cnt_1s,cnt_800ms;cnt_5s; //定时器计数单元
unsigned char s_buf; //秒寄存器
unsigned char m_buf; //分寄存器
unsigned char h_buf; //小时寄存器
unsigned char m_tmp; //分暂存器
unsigned char h_tmp; //小时暂存器
unsigned char key_buf; //键值缓存
unsigned char status; //状态字
unsigned char status_buf;
//------------------------------------------------------------------------
//位操作标志定义
bdata unsigned char flag1; //为标志集合1
sbit flag_2500us = flag1^0; //2500us定时器标志
sbit flag_100ms = flag1^1; //100ms定时器标志(键延迟)
sbit flag_500ms = flag1^2; //500ms定时器标志
sbit flag_1s = flag1^3; //1s定时器标志
sbit key_press = flag1^4; //键已被按下标志
sbit key_acpt = flag1^5; //键值已接受标志
sbit a = flag1^6; //交替标志
sbit flag_800ms = flag1^7;
sbit P3_7 = P3^7;
bdata unsigned char flag2;
sbit b = flag2^0;
sbit flag_5s = flag2^1;
//*************************************************************************
//以下为子程序模块
//*************************************************************************
void Time_0(void) interrupt 1 //T0中断(定时中断)
{
if(++cnt_2500us>8) //2.5ms基础定时器
{
cnt_2500us=0;
P0 =0x00;
P2 =disp_buf[disp_cnt&0x07];
P0 =led_loc[disp_cnt&0x07];
disp_cnt++;
//------------------------------------------------------------------------
if(!flag_100ms) //100ms定时器
{
if(++cnt_100ms>39)
{
cnt_100ms=0;
flag_100ms=1;
}
}
//------------------------------------------------------------------------
if(!flag_500ms) //500ms定时器
{
if(++cnt_500ms>199)
{
cnt_500ms=0;
flag_500ms=1;
}
}
//-----------------------------------------------------------------------
if(!flag_800ms) //500ms定时器
{
if(++cnt_800ms>319)
{
cnt_800ms=0;
flag_800ms=1;
}
}
//-----------------------------------------------------------------------
if(!flag_5s)
{
if(++cnt_5s>1999)
{
cnt_5s=0;
flag_5s=1;
}
}
//-----------------------------------------------------------------------
if(!flag_1s) //1s定时器
{
if(++cnt_1s>399)
{
cnt_1s=0;
flag_1s=1;
}
}
} //2.5ms基础定时器结束
}
//*************************************************************************
//键扫描子程序
void key_scan(void)
{
P1 =0x0f; //读键
if((P1|0xf0)==0xff) //是否有键按下
{ //无键按下
key_press=0; //清键已被按下标志
key_acpt=0; //清键值已接受标志
}
else
{ //有键按下
if(!key_press) //是否已置键已被按下标志
{
key_press=1; //置键已被按下标志
flag_100ms=0; //置100ms键延迟标志
}
else
{
if(flag_100ms) //100ms键延迟是否到
{
if(!key_acpt) //键值是否被接受
{
key_buf =P1&0x0f; //读低4位
P1 =0xf0; //读高4位
key_buf=(P1&0xf0)|key_buf; //接受键值
key_acpt=1; //置键值已接受标志
}
}
}
}
}
//*************************************************************************
//时钟子程序
void clock24(void)
{
if(flag_1s)
{
flag_1s=0;
if(s_buf<59)
s_buf++;
else
{
s_buf=0;
if(m_buf<59)
{
m_buf++;
}
else
{
m_buf=0;
if(h_buf<23)
h_buf++;
else
h_buf=0;
}
}
}
if(flag_500ms)
{
flag_500ms=0;
if(a==0)
{
disp_buf[1]=led_seg[h_buf%10+10];
disp_buf[2]=led_seg_fan[m_buf/10+10];
a=1;
}
else
{
disp_buf[1]=led_seg[h_buf%10];
disp_buf[2]=led_seg_fan[m_buf/10];
a=0;
}
}
if(h_buf/10)
disp_buf[0]=led_seg[h_buf/10];
else
disp_buf[0]=0xff;
disp_buf[3]=led_seg[m_buf%10];
disp_buf[4]=led_seg[s_buf/10];
disp_buf[5]=led_seg[s_buf%10];
disp_buf[6]=0xff;
}
void clock12(void)
{
if(flag_1s)
{
flag_1s=0;
if(s_buf<59)
s_buf++;
else
{
s_buf=0;
if(m_buf<59)
{
m_buf++;
}
else
{
m_buf=0;
if(h_buf<23)
h_buf++;
else
h_buf=0;
}
}
}
if(flag_500ms)
{
flag_500ms=0;
if(a==0)
{
if(h_buf%12==0)
disp_buf[1]=led_seg[12];
else
disp_buf[1]=led_seg[h_buf%12%10+10];
disp_buf[2]=led_seg_fan[m_buf/10+10];
a=1;
}
else
{
if(h_buf%12==0)
disp_buf[1]=led_seg[2];
else
disp_buf[1]=led_seg[h_buf%12%10];
disp_buf[2]=led_seg_fan[m_buf/10];
a=0;
}
}
if(h_buf%12/10==1||h_buf%12==0)
disp_buf[0]=led_seg[1];
else
disp_buf[0]=0xff;
disp_buf[3]=led_seg[m_buf%10];
disp_buf[4]=led_seg[s_buf/10];
disp_buf[5]=led_seg[s_buf%10];
if(h_buf>11)
disp_buf[6]=led_seg[21];
else
disp_buf[6]=led_seg[20];
}
//*************************************************************************
//小时,分钟显示
void disp_h(void)
{
if(status_buf==0)
{
if(h_buf/10)
disp_buf[0]=led_seg[h_buf/10];
else
disp_buf[0]=0xff;
disp_buf[1]=led_seg[h_buf%10];
}
else if(status_buf==1)
{
if(h_buf%12/10==1||h_buf%12==0)
disp_buf[0]=led_seg[1];
else
disp_buf[0]=0xff;
if(h_buf%12==0)
disp_buf[1]=led_seg[2];
else
disp_buf[1]=led_seg[h_buf%12%10];
if(h_buf>11)
disp_buf[6]=led_seg[21];
else
disp_buf[6]=led_seg[20];
}
}
void disp_m(void)
{
disp_buf[2]=led_seg_fan[m_buf/10];
disp_buf[3]=led_seg[m_buf%10];
}
//*************************************************************************
//以下为主程序
//*************************************************************************
void main(void)
{
unsigned char i;
unsigned char j;
//-------------------------------------------------------------------------
//程序初始化
PCON=0x00;
IE=0x00; //禁止全部中断
IP=0x00; //默认优先级
TH1=0xFD; //主频11.0592MHz,波特率=9600
TL1=0xFD;
TH0=0x00; //主频11.0592MHz,定时器0每秒3600次中断
TL0=0x00;
// SCON=0x50; //UART:9600/N/8/1
TMOD=0x22; //设定时器0为8位自动重装载
TCON=0x50; //启动定时器,INT0、INT1电平触发
EA=1; //中断总允许控制位
// EX0=1; //允许外部中断0
ET0=1; //允许T0中断
// EX1=1; //允许外部中断1
// ET1=1; //允许T1中断
// ES=1; //允许UART中断
// EX2=1; //允许外部中断2
// TI=0;
// RI=0;
flag1=0x00; //位标志集合1
flag2=0x00;
key_buf=0; //键值缓存
s_buf=0;
m_buf=0;
h_buf=0;
status =0; //起始状