📄 电子钟c程序.c
字号:
#include "absacc.h"
#include <reg51.h>
#include <stdio.h>
#define uint unsigned int
#define uchar unsigned char
#define c_8155 XBYTE [0x8000]
#define pa_8155 XBYTE [0x8001]
#define pb_8155 XBYTE [0x8002]
#define pc_8155 XBYTE [0x8003]
uchar code TABLE[24]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,
0x82,0xF8,0x80,0x90,0x88,0x83,
0xC6,0xA1,0x86,0x8E,0xFF,0x00,
0x8C,0xC1,0xCE,0x89,0x7F,0x0C};
uchar time,time1 ; // 一秒/半秒 计数
uchar hcq[4]; //显示缓冲
uint fen=60; //用来计数秒。到了60位一分钟
uint gnjc=0;//功能寄存
uint jianpan,jianzhi;//键盘,键值
bit mbzt=0;//秒表状态寄存:0停止计时并清零;1计时过程中;2停止计时
bit bm=0;//半秒取反
uint flashbit=3;//闪烁位选择开始在最高位上
uint i1=0,i2=0,i3=0,i4=0; //时钟,i1最高位
uint s1=0,s2=0,s3=0,s4=0; //秒钟,s1最高位
uchar bdata KEY_HANG;
uchar bdata KEY_LIE;
sbit HANG0=KEY_HANG^0;
sbit HANG1=KEY_HANG^1;
sbit HANG2=KEY_HANG^2;
sbit HANG3=KEY_HANG^3;
sbit LIE0 =KEY_LIE^0;
sbit LIE1 =KEY_LIE^1;
sbit LIE2 =KEY_LIE^2;
sbit p10=P1^0; //定义P1口 0,1,2,管脚
sbit p11=P1^1;
sbit p12=P1^2;
/*******************延时程序*********************/
void del()
{uchar i,j;
for(i=250;i>0;i--)
{for(j=2;j>0;j--)
}
}
/*****************时钟程序*********************/
void biao()//每调用一次都会使钟表走一个字
{if(i4==9)
{i4=0;
if(i3==5)
{i3=0;
if(i2==9)
{i2=0;i1++;}
else if(i1==2&&i2==4)
{i1=0;i2=0;}
else {i2++;}
}
else i3++;
}
else i4++;
}
/***************秒表程序**********************/
void miao()
{
if(s4==9)
{s4=0;
if(s3==9)
{s3=0;
if(s2==9)
{s2=0;
if(s1==9)
s1=0;
else s1++;
}
else {s2++;}
}
else s3++;
}
else s4++;
}
/******************中断程序*****************/
void int_t0() interrupt 1 using 0
{TH0=0x4C; //设置产生中断的时间50毫秒
TL0=0x00;
time--; time1--;
if(gnjc!=0)p11=0;else p11=1; //小灯表示时钟的状态,工作在1秒表状态,灯1亮
if(time==0) //一秒钟到了,要做的事
{ time=20;
p10=~p10;
p12=~p12;
if(gnjc==1&&mbzt==1) /**工作在秒表状态中要做的**/
miao();
fen--;
if (fen==0) //一分钟到了要做的事
{fen=60;
biao();
}
}
if(time1==0) //半分钟到了要做的事
{ time1=10; bm=~bm;}
}
/******************显示程序逐一显示各位******************/
void xian()
{uchar i,sel;
sel=0x01; //从最后一位开始显示
for (i=0;i<4;i++)
{pc_8155=sel;//选位
pa_8155=hcq[i];//选段
del();
pa_8155=0xFF;//去抖
sel=sel<<1; //左移显示下一位
}
}
/*************** 显示子程序 ******************/
void xian()
{
uchar sel, i;
sel=0x01;
for ( i=0 ; i< 4 ; i++ )
{
PB_8155=hcq[i];
PA_8155=sel;
sel=sel<<1;
del();
PA_8155=0x00;
}
}
/*************** 判键子程序 ******************/
uchar KEY_JUDGE( uchar d )
{
uchar a;
PA_8155=d;
a=~PC_8155;
return a;
}
/*************** 求键值子程序 ******************/
uchar KEY_VALUE()
{
uchar a, b, c=0xFF, i, Scan;
if ( ( KEY_JUDGE( 0 ) & 0x07 ) !=0 )
{
xian(); /* 若有键按下则调显示子程序去抖 */
xian();
if ( (KEY_JUDGE( 0 ) & 0x07 ) != 0 )
{
Scan=0xFE; /* 扫描字赋初值 */
for ( i=0 ; i<4 ; i++ )
{
KEY_LIE=KEY_JUDGE( Scan );
if ( ( KEY_LIE & 0x07 ) != 0 ) { i=4 ; KEY_HANG=Scan ; }
else
{
a=Scan>>(8-1);
b=Scan<<1;
Scan=a|b;
}
}
while ( ( KEY_JUDGE( 0 ) & 0x07 ) != 0 ) { xian(); } /* 若键没有被释放,则调显示延时 */
if ( HANG0==0 ) { a=0;}
else if ( HANG1==0 ) { a=1; }
else if ( HANG2==0 ) { a=2; }
else if ( HANG3==0 ) { a=3; }
if ( LIE0==1 ) { b=1; }
else if ( LIE1==1 ) { b=2; }
else if ( LIE2==1 ) { b=3; }
c=a*3+b; /* 计算键值 */
if ( c==11 ) { c=0; } /* 若键值为11,则改为0 */
xian();
}
}
return c;
}
/****************1键处理程序***************/
jianpan1()//功能控制键:0时钟,1秒表,2调表
{
if(gnjc==2)//本来是调表状态,按下变为时钟状态
gnjc=0;
else gnjc++;//按下键后判断是工作在什么方式下了
if(gnjc==1)
{s1=0; s2=0;s3=0;s4=0;mbzt=0;}
if(gnjc==2)
{flashbit=0;}
}
/**************** 2键处理程序***************/
jianpan2()//秒表计时开始键;调解闪烁位置
{
if(gnjc==1)
mbzt=~mbzt;
if(gnjc==2)
{if(flashbit==0)flashbit=3;else flashbit--;}
}
/**************** 3键处理程序***************/
jianpan3()//加数位
{
if(gnjc==2)
switch(flashbit)
{ case 0:{if(i2>3&&i1==1)i1=0;else if(i1==2)i1=0;else i1++;} break;
case 1: {if((i1==2&&i2==3)||i2==9)i2=0;else i2++;} break;
case 2: {if(i3==5)i3=0;else i3++;}break;
case 3:{if(i4==9)i4=0;else i4++;}break;
default: ;
}
}
/**************** 4键处理程序***************/
jianpan4()//减数位
{
if(gnjc==2)
switch(flashbit)
{ case 0:{if(i2>3&&i1==0)i1=1;else if(i1==0)i1=2;else i1--;} break;
case 1: {if(i1==2&&i2==0)i2=3;else if(i2==0) i2=9;else i2--;} break;
case 2: {if(i3==0)i3=5;else i3--;}break;
case 3:{if(i4==0)i4=9;else i4--;}break;
default: ;
}
}
/*************** 延时子程序(毫秒) ******************/
void dl_mss(uint d)
{
uchar j;
while(d--)
{
for ( j=0 ; j<255 ; j++ )
{;}
DIR();
DIR();
}
}
/*********************主程序********************/
main()
{
dl_mss( 500 ) ;
p10=0;
TMOD=1;
TH0=0x4C;
TL0=0x00;
EA=1;
ET0=1;
TR0=1;
time=20;
time1=10;
c_8155=0x03; //单片机工作方式控制字
while(1)
{ if(gnjc==0) //工作在0是时钟状态
{
hcq[0]=TABLE[i1];
hcq[1]=TABLE[i2];
hcq[2]=TABLE[i3];
hcq[3]=TABLE[i4];
}
else if (gnjc==1) //秒钟状态
{
hcq[0]=TABLE[s1];
hcq[1]=TABLE[s2];
hcq[2]=TABLE[s3];
hcq[3]=TABLE[s4];
}
else if (gnjc==2&&bm==0)//此处一定是工作在2调表状态,对bm控制是控制位的闪烁,半秒闪一次
{
hcq[0]=TABLE[i1];
hcq[1]=TABLE[i2];
hcq[2]=TABLE[i3];
hcq[3]=TABLE[i4];
}
else
{
hcq[flashbit]=TABLE[16];
}
xian();
del();
jianpan=KEY_VALUE()
if(jianpan==0X0E) //看是哪个键按下,就进入哪一个键的相应程序
jianpan1();
if(jianpan==0X0D)
jianpan2();
if(jianpan==0X0B)
jianpan3();
if(jianpan==0X07)
jianpan4();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -