用C语言编写AT89C51单片机程序,设计一个智能数字钟。

1.C语言程序要求是模块化设计。
2.该闹钟基于AT89C51单片机及相关外围电路进行设计。
3.该闹钟有4个数码管(共阳极),可分别显示时间(时、分、秒)、及定时时间(分、秒)。
4.该闹钟有4个按钮,S1是切换显示按键,该键按下时可分别实现切换正常走时显示、设定走时显示、设置定时时间,启动定时,回到正常状态等功能。S2是设定键,即该键按下,将分别选中需要设定的选项。S3键是加键,即按下去表示相应选项加1。S4键是减键,即按下去表示相应的选项减1。
5.该闹钟可以定时时间到,LED将发出提示闪光,且持续30s。
发挥要求:
1.定时时间可被打断,即打断后恢复时继续计时。
2.设置闹钟报警功能;
3.能切换显示年月日等信息。

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char

sbit QB1=P1^0;
sbit QB2=P1^1; //数码管段选
sbit QB3=P1^2;
sbit QB4=P1^3;
sbit QB5=P1^4;
sbit QB6=P1^5;
sbit fm=P1^6; //蜂鸣器
sbit s1=P2^4; //s5按键,切换显示
sbit s2=P2^3; //s2按键,设置调时
sbit s3=P2^2; //s3按键,加1
sbit s4=P2^1; //s4按键,减1

sbit led1=P0^0;
sbit led2=P0^1;
sbit led3=P0^2;

uchar count;
uchar sec,minu,hour,day,week,mon;
uchar n_sec,n_minu,n_hour;
uint year;
uchar set_2=1,set_1=1;
uchar hs,hg,mis,mig,ss,sg;
uchar nhs,nhg,nms,nmg,nss=0,nsg=0;
uchar ms,mg,ds,dg,w;
uchar code table[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,
0X90,0X88,0X83,0XC6,0XA1,0X8E,0X86,0xbf}; //0~F,-,共阳
//uchar code tableyi[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
//0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};//0-F,-,共阴
uchar code table_d[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef}; //0~9数组,带小数点

uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}; //闰年
uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}; //非闰年

void delay(uint); //延时函数
void timer0(); //走时中断函数
void jishi(); //计时函数
void key_change(); //切换显示按键函数
void key_set(); //设置时间按键函数
void disp(uchar,uchar,uchar,uchar,uchar,uchar); //显示函数
void zd_clock(); //整点报时函数
void nz_clock(); //闹钟函数
uchar incone(uchar); //加1函数
uchar decone(uchar); //减1函数
void set_time(); //设置时间函数
void set_clock(); //设置闹钟函数
void set_mdw(); //设置月日星期函数

void main() //主函数
{
EA=1;
ET0=1;
TR0=1;
TMOD=0x01;
TH0=0x4c; //50ms初值 晶振11.0592
TL0=0x00;
hour=23;minu=59;sec=49; //赋初值:11点59分0秒
n_hour=12;n_minu=56;n_sec=0; //闹钟赋初值12点1分0秒
year=2008;mon=5;day=14;week=3;//年月日星期赋初值2008年5月11日星期天;祝天下所有母亲节日快乐
while(1)
{
hs=hour/10; //时分秒HH.MM.SS
hg=hour%10;
mis=minu/10;
mig=minu%10;
ss=sec/10;
sg=sec%10;

ms=mon/10; //月日-星期MM.DD.-W
mg=mon%10;
ds=day/10;
dg=day%10;
w=week;

nhs=n_hour/10; //闹钟定时HH.MM.SS
nhg=n_hour%10;
nms=n_minu/10;
nmg=n_minu%10;
nss=n_sec/10;
nsg=n_sec%10;

key_change(); //s4按键扫描
key_set(); //s2按键扫描
set_time(); //设置时间
set_mdw(); //设置月日星期
set_clock(); //设置闹钟
if(set_1==1) //正常走时显示
{
disp(hs,hg,mis,mig,ss,sg);
}
if(set_1==2) //设置时间,LED1闪亮
{
disp(hs,hg,mis,mig,ss,sg);
if(sec%2==0)
{led2=1;led3=1;led1=~led1;}
// else
// {led1=1;}
}
if(set_1==3) //正常显示月日-星期
{
disp(ms,mg,ds,dg,16,w);
}
if(set_1==4) //设置月日-星期,LED2闪亮
{
disp(ms,mg,ds,dg,16,w);
if(sec%2==0)
{led1=1;led3=1;led2=~led2;}

// else
// {led2=1;}
}

if(set_1==5) //正常显示定时
{
disp(nhs,nhg,nms,nmg,nss,nsg);
}
if(set_1==6) //设置闹钟定时,LED3闪亮
{
disp(nhs,nhg,nms,nmg,nss,nsg);
if(sec%2==0)
{led1=1;led2=1;led3=~led3;}

// else
// {led3=1;}
}

zd_clock(); //整点报时
nz_clock(); //闹钟
}

}

void timer0() interrupt 1 //50ms中断函数

{
TMOD=0x01;
TH0=0x4c; //50ms初值 晶振11.0592
TL0=0x00;
count++;
if(count==20)
{
count=0;
sec++;
jishi(); //调计时函数
}
}

void jishi() //计时函数
{
if(sec==60)
{
sec=0;
minu++;
if(minu==60)
{
minu=0;
hour++;
if(hour==24)
{ hour=0;
day++;
week++;
if(week==8)
{week=0;}
if(year%4==0&&year%100!=0||year%400==0) //闰年
{
if(day==table1[mon]+1)
{
day=0;
mon++;
if(mon==13)
{mon=0;year++;}
}
}
else //非闰年
{
if(day==table2[mon]+1)
{
day=0;
mon++;
if(mon==13)
{mon=0;year++;}
}
}

}
}
}
}

void key_change() //s1按键扫描
{
if(s1==0)
{
delay(200);
if(s1==0)
{
set_1++;
while(!s1);
if(set_1==7)
{set_1=1;}
}
}
}

void key_set() //s2按键扫描
{
if(s2==0)
{
delay(10);
if(s2==0)
{
set_2++;
while(!s2);
if(set_2==4)
{set_2=1;}
}
}
}
void disp(uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6) //显示函数
{
QB1=1;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=0;
P3=table[a1]; //段码送P0口
delay(10); //延时一小会
QB1=0;
QB2=1;
QB3=0;
QB4=0;
QB5=0;
QB6=0;
P3=table[a2]; //第2个数码管显示,带小数点
delay(10);
QB1=0;
QB2=0;
QB3=1;
QB4=0;
QB5=0;
QB6=0;

P3=table[a3]; //第3个数码管显示
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=1;
QB5=0;
QB6=0;

P3=table[a4]; //第4个数码管显示,带小数点
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=1;
QB6=0;

//第5个数码管显示
P3=table[a5];
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=1;

P3=table[a6]; //第6个数码管显示
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=0;

}

void zd_clock() //整点报时函数
{
if(minu==59&&(sec==53||sec==55||sec==57))
{
fm=0;
delay(5);
fm=1;
delay(5);
}
fm=0;
if(minu==59&&sec==59)
{
fm=0;
delay(5);
fm=1;
delay(5);
fm=0;
}
}

void nz_clock() //闹钟函数
{
if(hour==n_hour&&minu==n_minu&&sec==n_sec)
//if((sec%2==0)&&sec<30)
{
fm=0;
delay(1);
fm=1;
delay(1);
}
}

void set_time() //设置时间函数
{
if(set_1==2)
{
if(set_2==1)
{
hour=incone(hour);
if(hour==24)
{hour=0;}
// if(hour<0)
// {hour=23;}
hour=decone(hour);

}
if(set_2==2)
{
minu=incone(minu);
if(minu==60)
{minu=0;}
// if(minu<0)
// {minu=59;}
minu=decone(minu);

}
}
}

void set_mdw() //设置月日星期函数
{
if(set_1==4)
{
if(set_2==1)
{
mon=incone(mon);
if(mon==13)
{mon=1;}
mon=decone(mon);
// if(mon==0)
// {mon=12;}
}
if(set_2==2)
{
day=incone(day);
if(day==32)
{day=0;}
day=decone(day);
// if(day==0)
// {day=0;}
}
if(set_2==3)
{
week=incone(week);
if(week==8)
{week=0;}
week=decone(week);
// if(week==0)
// {week=7;}
}
}
}

void set_clock() //设置闹钟函数
{
if(set_1==6)
{
if(set_2==1)
{
n_hour=incone(n_hour);
if(n_hour==24)
{n_hour=0;}
n_hour=decone(n_hour);
if(n_hour==0)
{n_hour=0;}
}
if(set_2==2)
{
n_minu=incone(n_minu);
if(n_minu==60)
{n_minu=0;}
n_minu=decone(n_minu);
if(n_minu==0)
{n_minu=0;}
}
}

}

uchar incone(uchar n) //加1函数
{
if(s3==0)
{ delay(200);
if(s3==0)
{
n++;
while(!s3);
}
}
return(n);
}

uchar decone(uchar m) //减1函数
{
if(s4==0)
{
delay(200);
if(s4==0)
{
m--;
while(!s4);
if(m<0)
{m=0;}
}
}
return(m);
}

void delay(uint k) //延时函数
{
uint i,j;
for(i=k;i>0;i--)
for(j=80;j>0;j--);
}
温馨提示:内容为网友见解,仅供参考
第1个回答  2011-12-21
这是我的课程设计,6个数码管,显示时分秒,三个按钮P0.0、P0.1、P0.2可以调时,有8个彩灯(可以不要),没闹钟、倒计时之类的。呵呵。

#include
#define uchar unsigned char
int i;
//**********************************************************************时钟的
uchar one[10]={0xbf,0xb0,0xdb,0xcf,0xe6,0xed,0xfd,0x07,0xff,0xef}; //NPN,阿拉伯数码(共阳数码管专用)
//uchar one[10]={0x40,0x4f,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //PNP三极管,低电平使能
uchar three[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //扫描
int num[6]={2,3,5,9,3,6};
uint a,t,d;
void time(); //计时
void turn(); //调时
void delay(int); //延时
//***********************************************************************彩灯的
uchar light[24]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,
0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,
0x7e,0xbd,0xdb,0xe7,0xe7,0xdb,0xbd,0x7e};
int n,m=6,h;
void go();

//====================================主函数========================================
void main()
{
TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1; //允许计数
ET0=1; //允许中断
EA=1;

for(;;) //主循环
{
time();
for(a=0;a<6;a++)
{
P3=three[a]; //扫描
P1=one[num[a]];
delay(1);
}
turn();
go();
}
}
//=====================================中断函数=================================
void work()interrupt 1 using 0
{
t++; //时钟时间
h++;
}

//=====================================计时子函数================================
void time()
{
if(t>=4000) //中断了4000次,一秒
{
t=0;
num[5]++;
if(num[5]>9) //1
{
num[5]=0;
num[4]++;
}
if(num[4]>5) //2
{
num[4]=0;
num[3]++;
}
if(num[3]>9) //3
{
num[3]=0;
num[2]++;
}
if(num[2]>5) //4
{
num[2]=0;
num[1]++;
}
if(num[1]>9) //5
{
num[1]=0;
num[0]++;
}
if(num[0]>1) //6
if(num[1]>3)
{
num[0]=0;
num[1]=0;
}
}
}

//====================================调时子程序===========================================
void turn()
{
if(P0_0==0) //小时
{
delay(5);
if(P0_0==0)
{
num[1]++;
if(num[1]>9)
{
num[1]=0;
num[0]++;
}
if(num[0]>1)
if(num[1]>3)
{
num[0]=0;
num[1]=0;
}

}
while(P0_0==0);
}
if(P0_1==0) //分钟
{
delay(5);
if(P0_1==0)
{
num[3]++;
if(num[3]>9)
{
num[3]=0;
num[2]++;
}
if(num[2]>5)
{
num[2]=0;
}
}
while(P0_1==0);
}
if(P0_2==0)
{
delay(5);
if(P0_2==0)
{
num[5]++;
if(num[5]>9)
{
num[5]=0;
num[4]++;
}
if(num[4]>5)
num[4]=0;
}
while(P0_2==0);
}
}

//========================================彩灯===========================================
void go()
{

if(h>=500*m) //1000=0.125秒
{
h=0;
P2=light[n];
n++;
}
if(n==24)
{
n=0;
m--;
}
if(m==0)
m=6;

}

//=====================================延时子程序==========================================
void delay(int c)
{
for(i=0;i<30*c;i++);
}
第2个回答  2012-01-06
ds12c887这个芯片能完成多有你要求的功能。。。

用C语言编写AT89C51单片机程序,设计一个智能数字钟。
sbit s2=P2^3; \/\/s2按键,设置调时 sbit s3=P2^2; \/\/s3按键,加1 sbit s4=P2^1; \/\/s4按键,减1 sbit led1=P0^0;sbit led2=P0^1;sbit led3=P0^2;uchar count;uchar sec,minu,hour,day,week,mon;uchar n_sec,n_minu,n_hour;uint year;uchar set_2=1,set_1=1;uchar hs,hg,...

以AT89C51单片机为核心,制作一个LCD显示的智能电子钟
bit)(io|=(1<<bit))\/\/1#define cbi(io,bit)(io&=~(1<<bit))\/\/0#define gbi(pin,bit)(pin&(1<<bit))\/\/读#define enableInterrupts() {_asm("rim\\n");

at89c51单片机实现电子时钟,不带闹铃。显示时分秒。求图求程序
} return(dat); \/\/将一个字节数据返回 } void tmpwritebyte(uchar dat) \/\/write a byte to ds18b20 { \/\/写一个字节到DS18B20里 uint i;uchar j;bit testb;for(j=1;j<=8;j++){ testb=dat&0x01;dat=dat>>1;if(testb) \/\/write 1 写1部分 ...

急求基于单片机AT89C51的多功能数字电子钟的汇编程序,高手进!~_百度知...
用89C51控制3个HC595,前两个595接8段数码显示管,显示“0”~“9”每秒跳动一次.第3个HC595接8个LED灯,每隔1秒闪烁1次.include<at89x52.h> include<intrins.h> define uchar unsigned char define uint unsigned int uchar table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90...

求程序用AT89C51单片机...用六位数码管实现数字时钟,显示时分秒,用两个...
init();\/\/初始化子程序 miao=0;shi=0;fen=0;while(1){ display(miao,fen,shi);} }void delay(uint z){ uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void display(uchar miao,uchar fen,uchar shi) \/\/ 显示子函数 { P0=0x00;P0=table[miao%10];P2=0x7f;delay(...

用AT89C51单片机编写一个C语言程序实现2个数码管秒计数器,用4个按键...
void t0isr() interrupt 1 { TH0=(65536-50000)\/256;TL0=(65536-50000)%256;num++;if(num>=20){ num=0;sec++;} } main(){ TMOD=0x01;TH0=(65536-50000)\/256;TL0=(65536-50000)%256;TR0=1;ET0=1;EA=1;LED1=0;LED2=0;while(1){ key=P1;if((key&0x0f)!=0x0f){ delay...

单片机at89c51用C语言编写报警器
include<reg51.h>#define uchar unsigned charuchar time;sbit spk=P1^0;void t0isr() interrupt 1{TH0=t_h;TL0=t_l;spk=~spk;}void t1isr() interrupt 3{TH1=(65536-50000)\/256;TL1=(65536-50000)%256;time++;time%=6;if(time==0){t_h=(65536-500)\/256;t_l=(65536-500)%256;...

AT89C51单片机,定时器1,50ms中断,用c语言写出初始化程序和中断函数程序...
include <reg51.h> void InitTimer1(void){ TMOD = 0x10;TH1 = 0x3C;TL1 = 0x0B0;EA = 1;ET1 = 1;TR1 = 1;} void main(void){ InitTimer1();} void Timer1Interrupt(void) interrupt 3 { TH1 = 0x3C;TL1 = 0x0B0;\/\/add your code here!} ...

求用单片机设计一个秒表AT89C51
;汇编程序如下。;使用T0定时方式1,每隔50ms中断一次,用于修改时间及显示 ;使用外部中断0、1,用于控制启动和清零 ;=== ORG 0000H AJMP MAIN ORG 0003H AJMP X0_INT ORG 000BH AJMP T0_INT ORG 0013H AJMP X1_INT MAIN:MOV TMOD,#01H ;T0定时方式1 MOV TH0, #(65536-5000...

单片机 at89c51 6位数码管24小时倒计时程序
void timer0(void)interrupt 1 { TH0=0x00;TL0=0x38;counter--;if(counter==0){ sec--;if(sec==-1){ sec=59;min--;if(min==-1){ min=59;hour--;if(hour==-1){ hour=23;} } } } } \/***主函数***\/ void main(){ uchar i;uchar display[6];counter=5000;sec=min=59...

相似回答