汇编和C语言的程序都有,请支持一下,谢谢
/***************************************/
//clock.c
//单片机电子钟C语言程序XSCLK V1.0
//MCU:AT89C2051晶振频率:12MHZ
//编写:舒新生日期:2007-11-23
/***************************************/
//最简单的单片机电子钟程序,学习单片机必经之路
//免费单片机辅导,尽最大努力回答您遇到的问题
//电话:13073399262QQ:625608148(白天在线)
/***************************************/
#include <at89x51.h>    //头文件包含
      
#define uchar unsigned char   //宏定义
#define uintunsigned int
#define ON0    //定义0为打开
#define OFF 1    //定义1为关闭
#define LEDBus P1    //定义p1口为数码管段码口
sbit MIAO =P1^2;     //秒点
sbit HOU_S=P3^0;    //时十位位选
sbit HOU_G=P3^1;    //时个位位选
sbit MIN_S=P3^2;    //分十位位选
sbit MIN_G=P3^3;    //分个位位选
sbit H_KEY=P3^4;    //时调整键
sbit M_KEY=P3^5;    //分调整键
bitSHAN;     //闪烁标志位
uchar second,minute,hour;  //定义秒、分、时寄存器
uchar code LEDTab[]={0x14,0xd7,0x4c,//数码管段码表0--9
0x45,0x87,0x25,0x24,0x57,0x04,0x05};
void delay(uchar t);    //延时函数
void init();    //初始化函数
void display();     //显示函数
void min_tiao();    //分调整函数
void hou_tiao();    //时调整函数
/***************************************
函 数 名:main
功  能:主函数
说  明:
入口参数:无
返 回 值:无 
****************************************/
void main()
{
init();      //调用初始化函数
while(1)     //主程序循环
{
if(!H_KEY) hou_tiao();   //如果时调整键按下(为0),调用时调整函数
if(!M_KEY) min_tiao();   //如果分调整键按下(为0),调用分调整函数
display();     //调用显示函数
}
}
/***************************************
函 数 名:init
功  能:初始化函数
说  明:初始化定时器及中断
入口参数:无
返 回 值:无 
***************************************/
void init()
{
TMOD=1;TH0=0X3C;TL0=0XB0;   //定时器0模式1,50毫秒
ET0=1;TR0=1;EA=1;   //开定时器0中断、启动定时器0、开总中断
}
/***************************************
函 数 名:display
功  能:显示函数
说  明:
入口参数:无
返 回 值:无 
***************************************/
void display()
{
LEDBus=LEDTab[minute%10];   //分个位送数码管显示
MIAO=SHAN;    //秒点闪烁
MIN_G=ON;     //打开分个位位选
delay(1);     //显示1毫秒
MIN_G=OFF;    //关闭分个位位选
LEDBus=LEDTab[minute/10];   //分十位送数码管显示
MIAO=SHAN;    //秒点闪烁
MIN_S=ON;     //打开分十位位选
delay(1);     //显示1毫秒
MIN_S=OFF;    //关闭分十位位选
LEDBus=LEDTab[hour%10];  //时个位送数码管显示
HOU_G=ON;     //打开时个位位选
delay(1);     //显示1毫秒
HOU_G=OFF;    //关闭时个位位选
if(hour/10)    //如果时十位为0,不显示十位数字
{
LEDBus=LEDTab[hour/10];   //时十位送数码管显示
HOU_S=ON;    //打开时十位位选
delay(1);    //显示1毫秒
HOU_S=OFF;     //关闭时十位位选
}
}
/***************************************
函 数 名:min_tiao
功  能:分调整
说  明:
入口参数:无
返 回 值:无
***************************************/
void min_tiao()
{
while(!M_KEY) display();   //等待分调整键松开
second=0;minute++;    //秒清零、分加1
if(minute==60) minute=0;   //如果分等于60,分变0
}
/***************************************
函 数 名:hou_tiao
功  能:时调整
说  明:
入口参数:无
返 回 值:无 
***************************************/
void hou_tiao()
{
while(!H_KEY) display();   //等待时调整键松开
second=0;hour++;   //秒清零,时加1
if(hour==24) hour=0;   //如果时等于24,时变0
}
/***************************************
函 数 名:delay
功  能:延时函数
说  明:
入口参数:t:延时时间长短
返 回 值:无 
***************************************/
void delay(uchar t)
{
uchar i;     //定义变量
for(;t>0;t--)     //如果t大于0,t减1(外层循环)
for(i=124;i>0;i--);   //i等于124,如果i大于0,i减1
}
/***************************************
函 数 名:timer0
功  能:定时器0中断函数
说  明:
入口参数:无
返 回 值:无 
***************************************/
void timer0() interrupt 1  //定时器0(中断1)
{
uchar tim1,tim2;   //定义临时变量
TL0=TL0+0XB0;TH0=0X3C;  //重装定时器初值
tim1++;      //每中断一次tim1加1
if(tim1==10)     //中断10(0.5秒)
{       
SHAN=!SHAN;     //闪烁标志取反
tim1=0;tim2++;   //tim1清零,tim2加1
if(tim2==2)     //到了1秒
{
 tim2=0;second++;   //tim2清零,秒加1
 if(second==60)    //如果秒到60
 {     
  second=0;minute++;   //秒变0,分加1
  if(minute==60)   //如果分到60
  {
 minute=0;hour++;   //分变0,时加1
 if(hour==24) hour=0; //如果时到24,时变0
  }
 }
}
}
}
/***************************************
program end     程序结束
***************************************/
以下是汇编程序
;********************************
;单片机电子钟汇编程序
;MCU:AT89C2051 晶振:12M
;编写:舒新生 日期:2007.11.08
;手机:13073399262QQ:625608148
;********************************
MIAO BIT P1.2 ;秒点位
HOU_S BIT P3.0 ;时十位
HOU_G BIT P3.1 ;时个位
MIN_S BIT P3.2 ;分十位
MIN_G BIT P3.3 ;分个位
H_KEY BIT P3.4 ;时调整键
M_KEY BIT P3.5 ;分调整键
SHAN BIT 0 ;秒点闪烁
LEDBUS EQU P1 ;显示数据总线
SECONDEQU 30H ;秒寄存器
MINUTEEQU31H ;分寄存器
HOUREQU32H ;时寄存器
TIM_1 EQU 33H ;定时器0中断次数
TIM_2 EQU 34H ;定时器0中断次数
;********************************
ORG0000H;程序开始
LJMPINIT
ORG000BH;定时器0中断入口地址
LJMPTIMER0
ORG0030H;程序从30H开始
;********************************
; 单片机初始化
INIT: MOVSECOND, #0 ;秒置0
MOVMINUTE, #0 ;分置0
MOVHOUR,#0 ;开机后显示0点
MOVTIM_1,#10 ;中断10次为0.5秒
MOVTIM_2,#2 ;0.5*2=1秒
MOVSP,#60H ;堆栈指针指向60H
MOVTMOD,#01H ;定时器0为模式1(16位)
MOVTH0,#03CH
MOVTL0,#0B0H ;50毫秒初值(晶振12M)
SETB ET0;定时器0中断允许
SETBTR0;启动定时器0
SETB EA;开总中断
;********************************
; 主程序
MAIN: JNBH_KEY,HT ;时调整键按下转到HT
JNBM_KEY,MT ;分调整键按下转到MT
ACALLDISP;调用显示子程序
AJMPMAIN;转LOOP继续检测按键状态
;********************************
; 时间调整
;-----分调整----------------- 
MT: ACALLDISP;调用显示子程序
JNBM_KEY,MT ;判断按键是否松开
INCMINUTE;分加一
MOVA,MINUTE 
CJNEA,#60,MAIN ;判断分是否加到60
MOVMINUTE, #0 ;分到60变为0
MOV SECOND, #0 ;秒置0
AJMPMAIN
;-----时调整-----------------
HT: ACALLDISP;调用显示子程序
JNBH_KEY,HT ;判断按键是否松开
INCHOUR;时加1
MOVA,HOUR
CJNEA,#24,MAIN
MOVHOUR,#0 ;判断时是否到24,时到24变0
AJMPMAIN
;********************************
; 显示子程序
DISP: MOVDPTR,#LEDTAB ;数码管段码表首地址送DPTR 
MOVA,MINUTE;分放入ACC
MOVB,#10 ;B放入10
DIVAB;A/B,商在A余数在B
MOVC A,@A+DPTR ;查表取分十位段码 
MOVLEDBUS, A ;段码送LEDBUS口显示
MOV C, SHAN
MOV MIAO, C ;秒点闪烁
CLRMIN_S;打开分十位显示
ACALLD1MS;延时1毫秒
SETBMIN_S;关闭分十位显示
MOVA,B
MOVCA,@A+DPTR ;查表取分个位段码
MOVLEDBUS, A
MOV C, SHAN
MOV MIAO, C ;秒点闪烁
CLRMIN_G;打开分个位显示
ACALLD1MS;延时1毫秒
SETBMIN_G;关闭分十位显示
MOVA,HOUR 
MOVB,#10
DIVAB;拆分小时的十位和个位
JZ DISP0;十位为0不显示十位
MOVCA,@A+DPTR
MOVLEDBUS, A
CLRHOU_S;打开时十位显示
DISP0: ACALLD1MS
SETBHOU_S;关闭时十位显示
MOVA,B
MOVCA,@A+DPTR
MOV LEDBUS, A 
CLRHOU_G;打开时个位显示
ACALLD1MS
SETBHOU_G;关闭时个位显示
MOV P1, #0FFH
RET
;********************************
; 定时器0中断服务程序
TIMER0: PUSHACC;入栈保护ACC和PSW
PUSHPSW
MOVA,#0B1H ;定时器0中断服务子程序
ADDA,TL0 ;同步修正(参考本人的<如何是自制的单片机电子钟走时精准>)
MOVTL0,A
MOVTH0,#03CH ;重装定时器0初值
DJNZTIM_1,RETI_1
MOVTIM_1,#10 ;中断10次为0.5秒
CPLSHAN;取反闪烁位
DJNZTIM_2,RETI_1
MOVTIM_2,#2 ;1秒时间到
INCSECOND;秒加1
MOVA,SECOND
CJNEA,#60,RETI_1
MOVSECOND, #0 ;秒到60变0
INCMINUTE;分加1
MOVA,MINUTE
CJNEA,#60,RETI_1 
MOVMINUTE, #0 ;分到60变0
INCHOUR;时加1
MOVA,HOUR
CJNEA,#24,RETI_1
MOVHOUR,#0 ;时到24变0 
RETI_1: POPPSW;出栈
POPACC
RETI
;******************************** 
; 延时子程序 
D1MS: MOVR7,#2 ;延时1毫秒子程序
D_1: MOVR6,#250 ;延时时间估算250*2*2=1000微秒=1毫秒
DJNZR6,$
DJNZR7,D_1
RET
;********************************
; 数码管段码表 
LEDTAB: DB14H,0D7H,4CH,45H,87H
; 0 1  23 4
DB 25H,024H,57H,04H,05H
; 5 6  78 9
END