89c51单片机的数字钟程序?

4个数码管的

/*********************************************
ILONG编做
【注意P3口输出模拟和在{实验板}上不一样。实验板不用取反】
【目的】:用20次T0定时产生1s.进而形成 HH-mm-ss时间
【参数说明】:
40H~47H :显示管,每位暂存器,存放要显示的数码的地址。可根据地址加1,实现该位数加1;
并且低4位可以代表管子要显示的值(42H、45H除外)。
48H :要显示的位值(0~7,由译码器翻译出)
49H :每位每次刷出时要显示的时间0~256us
4A :20次定时,的次数计数器
4BH,4CH :小时十位进位刷0,时,小时两位数的暂存
4DH :调试时,要调整类型,每次INT0中断自增一次
50H~5FH :0~F 16个数的码值
60H :"-"的码值
61H :"空" 的码值
62H,63H :要闪的两位地址暂存 (好像没用着)
R0 :存放 每位暂存器 的地址,用于 刷新位时 移位
00H(位) :是否有INT0(调整)中断
01H(位) :是闪亮,还是闪空,即:闪烁时的亮暗状态
【存在问题】:
1,调整时间时,分钟位开始乱码。
2,调整时间时,必须亮的时候才能调
3,时间差:慢于实际时间
2011.10.21 ilong(crazy night)
*********************************************/
SJMP 0x0030
ORG 0x0030
MAIN:
//启动外部中断
SETB IT0
SETB IE0
SETB EX0
SETB PX0
SETB IT1
SETB IE1
SETB EX1
SETB PX1
SETB EA
CLR 00H //没有调整中断
CLR 01H //闪空
MOV 4DH,#04H //0xFC
MOV P3,#0FH
MOV 62H,46H //从分开始闪
MOV 63H,47H
//十位数********************
MOV 50H,#3FH
MOV 51H,#06H
MOV 52H,#5BH
MOV 53H,#4FH
MOV 54H,#66H
MOV 55H,#6DH
MOV 56H,#7DH
MOV 57H,#07H
MOV 58H,#7FH
MOV 59H,#6FH
MOV 5AH,#77H
MOV 5BH,#7CH
MOV 5CH,#39H
MOV 5DH,#5EH
MOV 5EH,#79H
MOV 5FH,#71H
MOV 60H,#40H
MOV 61H,#00H
//八位管的暂存 从左到右40-47
MOV 40H,#50H
MOV 41H,#50H
MOV 42H,#60H
MOV 43H,#50H
MOV 44H,#50H
MOV 45H,#60H
MOV 46H,#50H
MOV 47H,#50H
MOV 48H,#00H //扫描位暂存
MOV R0,#40H //扫描值地址
MOV 4AH,00H //20次定时 计数
LCALL TIMER_GO20 //开启并初始定时器
//主函数进程,就是扫描码管值并显示,其他为中断操作***************************************************
SCAN: //显示器扫描输出*************************************
MOV P2,48H //选择显示位(从左到右0-7)
MOV A,@R0 //获取该位的数码值 地址
MOV R1,A
MOV A,@R1 //获取该位码值
//CPL A //根据数码管是共阴、共阳 是否取反
MOV P0,A //从P0输出每位的码值,注意:该端口时下面的“清屏”一起改
LCALL DELAY //进入每位延时
MOV P0,#0FFH //清屏
INC 48H //暂存器后移
INC R0 //位后移
MOV A,48H //通过 (48H)的值+08H 判断是否到了 位尾
ADD A,#08H
JB 0D6H,RER //D6H(位)为AC(辅助进位:半进位)。为1时说明(48H)的值+08H=F,即(48H)=8,此时跳向RER
SJMP SCAN
RER: //扫描重置
CLR 0D6H //重置 AC(辅助进位:半进位)
MOV 48H,#00H
MOV R0,#40H
SJMP SCAN
//End 主函数*********************************************************************************************
DELAY: //延时,用于扫描7段管时,在每一位停留的时间.时间太短,回使不该亮的段也有些亮
MOV 49H,#25H //49H的值不可以等于FF,因为FF取反后49H为0,不会延迟了
MOV A,0FEH //用取反设置循环次数,
CPL A
MOV 49H,A
ADD_1:
INC 49H
MOV R1,49H //因为DJNZ判断完后要把判断的地址减去1,所以为了DJNZ不对49H的内容造成影响,把49H的值装到R1中去判断
DJNZ R1,ADD_1
RET
//20次定时*********************************************************************************************************
TIMER_GO20:
//用4AH 设置循环次数*********************************
MOV 4AH,#15H //20(=0x15)次定时
MOV A,4AH //用取反设置定时次数,
CPL A
MOV 4AH,A
SJMP TIMER_S
TIMER_GO5: //与TIMER_GO20类似,只是这里只让定时5次一循环。用于调整闪烁
MOV 4AH,#05H //5(=0x05)次定时
MOV A,4AH //用取反设置定时次数,
CPL A
MOV 4AH,A
TIMER_S://未重置(4AH)的调用,
//设置启动T0
MOV TMOD,#01H //设置模式:T0模式1
MOV TH0,#3CH //T0初值高8位
MOV TL0,#0AH //T0初值低8位
//CLR TF0 //未知问题
SETB ET0 //T0允许中断
SETB EA //CPU允许中断
SETB TR0 //启动T0
RET
T0_INT: //T0中断程序段
CPL P1.7 //测试端口:T0重新定时一次发生一次跳转
LCALL TIMER_S //T0重新定时,继续跑。但:不会初始化20次计数
INC 4AH //T0定时次数加1
MOV A,4AH
JNZ CY_20 //50H加到FF再加就到0了。不为0回去接着执行主程序;为0 则20次定时 溢出即:00H(位)为1
CPL P1.6 //测试端口每秒发生一次跳转
JB 00H,GO_BLINK //如果00H(位)被置1,则不再执行时间系统加1。用于调整时显示闪烁
LCALL CLOCK_GO //时间系统加1秒
LCALL TIMER_GO20 //20次重新开始
SJMP CY_20
GO_BLINK:
LCALL TIMER_GO5 //5次重新开始,
LCALL BLINK
CY_20: RET
//时间系统进位设置*******************************************************************************************
CLOCK_GO:
INC 47H //秒加1
//个位秒 进位 十位
MOV A,#5AH //主要是看"#5A"中的“A”,
SUBB A,47H
JNZ SS_OUT //如果(47H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位
MOV 47H,#50H
INC 46H
SS_OUT:
//秒 进位 分
MOV A,#56H //
SUBB A,46H
JNZ SM_OUT //如果(46H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位
MOV 46H,#50H
CLOCK_GO_M:INC 44H
//分调整用
SM_OUT:
//分个位 进位 分
MOV A,#5AH //
SUBB A,44H
JNZ MM_OUT //如果(44H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位
MOV 44H,#50H
INC 43H
MM_OUT:
//分 进位 时
MOV A,#56H //
SUBB A,43H
JNZ MH_OUT //如果(43H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位
MOV 43H,#50H
CLOCK_GO_H:INC 41H
//时调整用
MH_OUT:
//时个位 进位 时
MOV A,#5AH //
CLR CY //排除借位影响
SUBB A,41H
JNZ HH_OUT //如果(41H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位
MOV 41H,#50H
INC 40H
HH_OUT:
//时十位置0
MOV 4BH,40H //为了不影响暂存器数据,把40H、41H转到4BH、4CH中进行 操作
MOV 4CH,41H
MOV A,4BH
SWAP A //获得小时十位数,并放到A的高4位上
ANL A,#0F0H //清0低4位
ANL 4CH,#0FH //小时个位 高4位清0
ADD A,4CH //小时的十位与个位相加(高4位来自小时的十位暂存器40H,低四位来自小时个位的寄存器41H)
SUBB A,#24H
JNZ HD_OUT //如果(46H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位
MOV 41H,#50H //个位 清零
MOV 40H,#50H //十位清零
HD_OUT:
CG_OUT: RET
//END 时间系统进位设置*******************************************************************************************
//INTO中断程序段*********************************************************************************
INT0_INT:
SETB 00H
CPL P1.5
CPL P1.5
CLR 01H //使得在换位闪烁时不会把上位的数带给下一位,
HMS_BACK: //在每次换位时都要把,被放到暂存上的值那回去,使其显示出来
MOV A,4DH
CJNE A,#02H,BSH_S //back second OR hour _select
LCALL LIGHT_M
SJMP B_END
BSH_S: //恢复秒小时选择
JB CY,B_H
SJMP B_S
B_S: LCALL LIGHT_S //把调好的数据装回暂存器
SJMP B_END
B_H: LCALL LIGHT_H
B_END:
// CLR TR0 //定时器0,停止计时
DEC 4DH //调整类型(时、分、秒)改变
MOV A,4DH
JNZ INT0_OUT //是否恢复时钟
CLR 00H //置0,调整中断(ilong 定义)
CLR 01H
MOV 4DH,#04H //初始化调整类型

INT0_OUT:
RET
////闪烁*****************************************************************
BLINK:
CPL P1.1
CPL 01H
MOV A,4DH
CJNE A,#02H,SH_S
SJMP MM_SET
SH_S: //闪烁秒小时选择
JB CY,HH_SET
SJMP SS_SET
SS_SET: //秒钟设置****************
JB 01H,DACK_S
LIGHT_S:
MOV 46H,4EH
MOV 47H,4FH
SJMP BLINK_OUT
DACK_S:
MOV 4EH,46H
MOV 4FH,47H
MOV 46H,#61H
MOV 47H,#61H
RET
MM_SET: // 分钟设置**************
JB 01H,DACK_M
LIGHT_M:
MOV 43H,4EH
MOV 44H,4FH
SJMP BLINK_OUT
DACK_M:
MOV 4EH,43H
MOV 4FH,44H
MOV 43H,#61H
MOV 44H,#61H
RET
HH_SET: //小时设置****************
JB 01H,DACK_H
LIGHT_H:
MOV 40H,4EH
MOV 41H,4FH
SJMP BLINK_OUT
DACK_H:
MOV 4EH,40H
MOV 4FH,41H
MOV 40H,#61H
MOV 41H,#61H
BLINK_OUT:RET
//INT1中断程序段***************************************************************
INT1_INT:
//lcall HMS_BACK
//clr tr0
CPL P1.4
MOV A,4DH
CJNE A,#02H,ADDSH_S //ADD Hour OR ADD second OR _select
SJMP ADD_M
ADDSH_S: //调整秒小时选择
JB CY,ADD_H
SJMP ADD_S
ADD_S: LCALL CLOCK_GO
SJMP ADD_END
ADD_M: LCALL CLOCK_GO_M
SJMP ADD_END
ADD_H: LCALL CLOCK_GO_H
ADD_END:
// LCALL CLOCK_GO
RET
/*********************************************************************************
最后放中断保险些
*********************************************************************************/
//T0中断程序***************
ORG 000BH
LCALL T0_INT
RETI
//INT0中断*****************
ORG 0003H
LCALL INT0_INT
RETI
//INT1中断*****************
ORG 0013H
LCALL INT1_INT
RETI
END
温馨提示:内容为网友见解,仅供参考
第1个回答  2011-10-25
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit up_m=P3^0; //秒按键设置
sbit up_f=P3^1; //分按键设置
sbit up_s=P3^2; //时按键设置
uchar const smg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar i,j,k;
void delay(uint cnt)
{
while(--cnt);

}
void delayms(uint a)
{
uchar i;
while(--a)
{
for(i=0;i<125;i++);
}
}
void init()
{
TMOD=0X01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
ET0=1;
EA=1;
TR0=1;
}
void keyboard()
{
P3=0xff;
if(up_m==0)
delayms(40);
if(up_m==0)
{
i++;
if(i>=60)
{
i=0;
}
delayms(40);
}
if(up_f==0)
delayms(40);
if(up_f==0)
{
j++;
if(j>=60)
{
j=0;
}
delayms(40);
}
if(up_s==0)
delayms(40);
if(up_s==0)
{
k++;
if(k==23)
{
k=0;
}
delayms(40);
}
}
void init_smg()
{
P2=2;
P0=0x40;
delay(5);
P2=5;
P0=0x40;
delay(5);
}
main()
{
i=0;
init();
while(1)
{ init_smg();
P2=2;
P0=0x40;
P2=5;
P0=0x40;
P0=0x00;
keyboard();
P2=7;
P0=smg[i%10];
delay(3);
P0=0X00;
P2=6;
P0=smg[i/10];
delay(3);
P0=0x00;

P2=4;
P0=smg[j%10];
delay(3);
P0=0X00;
P2=3;
P0=smg[j/10];
delay(3);
P0=0x00;

P2=1;
P0=smg[k%10];
delay(3);
P0=0X00;
P2=0;
P0=smg[k/10];
delay(3);
P0=0x00;
}
}
void time () interrupt 1
{
unsigned char a;
a++;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
if(a==20)
{
a=0;
i++; //秒控制
if(i==60)
{
i=0;
j++;//分控制
}
if(j==60)
{
j=0;
k++;//时控制
if(k>23)
k=0;
}
}
}

这是我以前写的一个,是八位数码管的,你自己改一下就好了,思想是一样的
第2个回答  2011-10-24
可以找我代做,成品都没问题,QQ67348467

89c51单片机的数字钟程序?
\/\/END 时间系统进位设置*** \/\/INTO中断程序段***INT0_INT: SETB 00H CPL P1.5 CPL P1.5 CLR 01H \/\/使得在换位闪烁时不会把上位的数带给下一位,HMS_BACK: \/\/在每次换位时都要把,被放到暂存上的值那回去

急求基于单片机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...

89c51单面机c语言时钟控制器编程
2011-10-28 已知AT89C51的时钟频率为6MHz,用定时器编写程序,使... 10 2014-10-29 求用C语言编写一个单片机89C51电子时钟程序,有时,分,秒... 1 2017-05-07 求采用AT89c51单片机控制的数字钟c语言程序。 3 2008-11-08 如何用c语言让at89s51单片机产生一个时钟脉冲 12 2015-06-30 用AT89C51单片机设计...

电工数字钟课程设计 电路图 详细一点啊
本设计采用 89C51 进行 24 小时计时并显示。要求其显示时 间范围是 00:00:00~23:59:59,具备有时分秒校准功能。数字钟上面要带有 闹钟,闹钟与时钟之间能随时切换,闹钟具备时分秒设置功能。设计的详细资料在图片上的网站搜“带整点报时与闹钟功能的数字钟设计,附设计框图,电路图,C语言源程序....

设计一个电子秒表,通过软件延时方式实现秒计时通过两个数码管动态显示秒...
这原本是数字钟的程序 要6位数码管显示的,给你改了一下。硬件上需要89c51最小系统+74Hc573两片+数码管两位#include<reg51.h> sbit dula = P2^6;sbit wela = P2^7;sbit led1 = P1^3;define uint unsigned int define uchar unsigned char uint a,c,g;uint b = 5;long int num;uchar ...

求一基于单片机89c51的数字钟电路设计
这个要求有点天真,这个不花钱别人不会给你做的

51微控制器中unsigned char到底定义的是字元还是0--255的数字
89c51微控制器的数字钟程式? \/*** ILONG编做 【注意P3口输出模拟和在{实验板}上不一样。实验板不用取反】 【目的】:用20次T0定时产生1s.进而形成 HH-mm-ss时间 【引数说明】: 40H~47H :显示管,每位暂存器,存放要显示的数码的地址。可根据地址加1,实现该位数加1; 并且低4位可以代表管子要显示的值(...

六位数码管时钟
71.基于单片机的数字钟设计 72.小功率不间断电源(UPS)中变换器的原理与设计 73.自动存包柜的设计 74.空调器微电脑控制系统 75.全自动洗衣机控制器 76.电力线载波调制解调器毕业设计论文 77.图书馆照明控制系统设计 78.基于AC3的虚拟环绕声实现 79.电视伴音红外转发器的设计 80.多传感器障碍物检测...

急求电子信息工程专科毕业论文题目
提供一些电子信息工程专科毕业论文的题目,供参考。精密检波器的设计 简易电子血压计的设计 电子听诊器的设计 简易数码相机的设计 直流电机转动的单片机控制 高频功率合成网络的研究 多功能气体探测器 车用无线遥控系统 家用门窗报警器 智能型全自动充电器 医用病房多路呼叫系统 多功能数字钟 数字电压表的设计...

毕业论文资料收集(采纳追加1000分)
·基于8051单片机的数字钟·红外快速检测人体温度装置的设计与研制·三层电梯的单片机控制电路·交通灯89C51控制电路设计·基于单片机的短信收发系统设计 ――硬件设计·大棚温湿度自动控制系统·串行显示的步进电机单片机控制系统·微机型高压电网继电保护系统的设计·基于单片机mega16L的煤气报警器的设计·智能毫伏表的设计...

相似回答