求一个用汇编语言编写一个8051单片机的时钟程序(急急急啊)

一、基本要求:
1、具有时(32H)、分(31H)、秒(30H)功能。
2、时分秒均以压缩BCD码格式存储。
二、扩展要求:
1、具有年(35H)、月(34H)、日(33H)功能。
2、年月日均以压缩BCD码格式存储。
3、具有闹钟功能。
4、其他实用功能。

给你当参考...不足功能自己改...有问题再发问..

;P1.4小时调整 P1.5分种调整

CODE_SEG SEGMENT CODE
DATA_SEG SEGMENT DATA
STACK_SEG SEGMENT IDATA

K1 BIT P1.4
K2 BIT P1.5

RSEG DATA_SEG
KEY_S: DS 1
KEY_V: DS 1
DIS_DIGIT: DS 1
SEC: DS 1
DIS_INDEX: DS 1
HOUR: DS 1
MIN: DS 1
SEC100: DS 1
DIS_BUF: DS 8

BUF_HOUR_H EQU DIS_BUF ; 小时十位
BUF_HOUR_L EQU DIS_BUF+1 ; 小时个位
BUF_MIN_H EQU DIS_BUF+3 ; 分十位
BUF_MIN_L EQU DIS_BUF+4 ; 分个位
BUF_SEC_H EQU DIS_BUF+6 ; 秒十位
BUF_SEC_L EQU DIS_BUF+7 ; 秒个位

RSEG STACK_SEG
STACK: DS 20

;===============================================================================

CSEG AT 0000H
JMP MAIN

CSEG AT 0000BH
LJMP TIMER0

CSEG AT 0001BH
LJMP TIMER1

;===============================================================================

RSEG CODE_SEG
MAIN:
USING 0

MOV SP, #(STACK-1) ;

MOV P0,#0FFH
MOV P2,#0FFH
MOV TMOD,#011H ; 定时器0, 1工作模式1, 16位定时方式
MOV TH0,#0FCH
MOV TL0,#017H
MOV TH1,#0DCH
CLR A
MOV TL1,A

MOV HOUR,#12 ;
CLR A ;
MOV MIN,A
MOV SEC,A
MOV SEC100,A

MOV A,HOUR
MOV B,#10
DIV AB
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR
MOV BUF_HOUR_H,A ; 时十位
MOV A,HOUR
MOV B,#10
DIV AB
MOV A,B
MOVC A,@A+DPTR
MOV BUF_HOUR_L,A ; 时个位
MOV A,MIN
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV BUF_MIN_H,A ; 分十位
MOV A,MIN
MOV B,#10
DIV AB
MOV A,B
MOVC A,@A+DPTR
MOV BUF_MIN_L,A ; 分个位
MOV A,SEC
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV BUF_SEC_H,A ; 秒十位
MOV A,SEC
MOV B,#10
DIV AB
MOV A,B
MOVC A,@A+DPTR
MOV BUF_SEC_L,A ; 秒个位

MOV BUF_HOUR_H+02H,#0BFH
MOV BUF_HOUR_H+05H,#0BFH

MOV DIS_DIGIT,#0FEH
CLR A
MOV DIS_INDEX,A

MOV IE,#08AH ; 使能timer0,1 中断

SETB TR0
SETB TR1

MOV KEY_V,#03H

MAIN_LP:
LCALL SCAN_KEY ; 键扫描
JZ MAIN_LP ; 无键返回

MOV R7,#10 ; 延时10ms
LCALL DELAYMS ; 延时去抖动
LCALL SCAN_KEY ; 再次扫描
JZ MAIN_LP ; 无键返回

MOV KEY_V,KEY_S ; 保存键值
LCALL PROC_KEY ; 键处理
SJMP MAIN_LP ; 调回主循环

;===============================================================================
SCAN_KEY:
; 扫键扫描子程序
; 保存按键状态到key_s
; 返回: A --- 按键是否按下(BOOL)

CLR A

MOV C,K1 ; 读按键K1
MOV ACC.0,C
MOV C,K2 ; 读按键K2
MOV ACC.1,C

MOV KEY_S,A ; 保存按键状态到key_s
XRL A,KEY_V
RET

;===============================================================================
PROC_KEY:
; 键处理子程序
; 传入参数: KEY_V --- 按键值
; 返回值: 无

CLR EA

MOV A,KEY_V
JNB ACC.0,PROC_K1
JNB ACC.1,PROC_K2
SJMP END_PROC_KEY

PROC_K1: ; 按键k1处理
LCALL INC_HOUR ; 小时加1
SJMP END_PROC_KEY

PROC_K2: ; 按键K2处理
INC MIN ; 分钟加1

MOV A,MIN ;
SETB C
SUBB A,#59
JC K2_UPDATE_MIN ; 如果分钟等于60,则分清0,小时加1

CLR A ;
MOV MIN,A

K2_UPDATE_MIN: ; 更新分显示缓冲区
MOV A,MIN
MOV B,#10
DIV AB ; A = MIN / 10
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR
MOV BUF_MIN_H,A ; 更新分十位

MOV A,MIN
MOV B,#10
DIV AB
MOV A,B ; A = MIN % 10
MOVC A,@A+DPTR
MOV BUF_MIN_L,A ; 更新分个位

END_PROC_KEY:
SETB EA
RET

;===============================================================================

USING 0
TIMER0:
; 定时器0中断服程序, 用于数码管的动态扫描
; DIS_INDEX --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
; DIS_DIGIT --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
; 选通P2.0口数码管
; DIS_BUF --- 显于缓冲区基地址

PUSH ACC
PUSH PSW
PUSH AR0

MOV TH0,#0FCH
MOV TL0,#017H

MOV P2,#0FFH ; 先关闭所有数码管

MOV A,#DIS_BUF ; 获得显示缓冲区基地址
ADD A,DIS_INDEX ; 获得偏移量
MOV R0,A ; R0 = 基地址 + 偏移量
MOV A,@R0 ; 获得显示代码
MOV P0,A ; 显示代码传送到P0口

MOV P2,DIS_DIGIT

MOV A,DIS_DIGIT ; 位选通值左移, 下次中断时选通下一位数码管
RL A
MOV DIS_DIGIT,A

INC DIS_INDEX ; DIS_INDEX加1, 下次中断时显示下一位
ANL DIS_INDEX,#0x07 ; 当DIS_INDEX等于8(0000 1000)时, 清0

POP AR0
POP PSW
POP ACC

RETI

;===============================================================================
USING 0
TIMER1:
; 定时器1中断服务程序, 产生时基信号10ms
;
;
PUSH PSW
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL

MOV TH1,#0DCH

INC SEC100

MOV A,SEC100
CLR C
SUBB A,#100 ; 是否中断100次(达到1s)
JC END_TIMER1 ; < 1S

MOV SEC100,#00H ; 达到1s
LCALL INC_SEC ; 秒加1

END_TIMER1:
POP DPL
POP DPH
POP B
POP ACC
POP PSW

RETI ;

;===============================================================================
INC_SEC:
INC SEC

MOV A,SEC
SETB C
SUBB A,#59 ;
JC UPDATE_SEC

CLR A
MOV SEC,A
LCALL INC_MIN

UPDATE_SEC:
MOV A,SEC
MOV B,#10
DIV AB ; A = SEC / 10
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR ;
MOV BUF_SEC_H,A ;

MOV A,SEC
MOV B,#10
DIV AB
MOV A,B ; A = SEC % 10
MOVC A,@A+DPTR
MOV BUF_SEC_L,A
RET

;===============================================================================

INC_MIN:
INC MIN ; 分钟加1

MOV A,MIN ;
SETB C
SUBB A,#59
JC UPDATE_MIN ; 如果分钟等于60,则分清0,小时加1

CLR A ;
MOV MIN,A
LCALL INC_HOUR ; 小时加1

UPDATE_MIN: ; 更新分显示缓冲区
MOV A,MIN
MOV B,#10
DIV AB ; A = MIN / 10
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR
MOV BUF_MIN_H,A ; 更新分十位

MOV A,MIN
MOV B,#10
DIV AB
MOV A,B ; A = MIN % 10
MOVC A,@A+DPTR
MOV BUF_MIN_L,A ; 更新分个位

RET

;===============================================================================

INC_HOUR:
INC HOUR ; 小时加1
MOV A,HOUR
SETB C
SUBB A,#24
JC UPDATE_HOUR ; 如果小时等于24,则小时清0

CLR A
MOV HOUR,A ; 小时清0

UPDATE_HOUR:
MOV A,HOUR
SETB C
SUBB A,#10
JC UPDATE_HOUR1 ; 如果小时小于10,则十位0不显示

MOV A,HOUR
MOV B,#10
DIV AB
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR ;
MOV BUF_HOUR_H,A
SJMP UPDATE_HOUR2

UPDATE_HOUR1:
MOV BUF_HOUR_H,#0FFH

UPDATE_HOUR2:
MOV A,HOUR
MOV B,#10
DIV AB
MOV A,B
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR
MOV BUF_HOUR_L,A
RET

;===============================================================================

DELAYMS:
; 延时子程序
; 传入参数:R7 --- 延时值(MS)
; 返回值:无

MOV A,R7
JZ END_DLYMS
DLY_LP1:
MOV R6,#185
DLY_LP2:
NOP
NOP
NOP
DJNZ R6,DLY_LP2
DJNZ R7,DLY_LP1

END_DLYMS:
RET

; END OF DELAYMS

;===============================================================================

DIS_CODE:
DB 0C0H
DB 0F9H
DB 0A4H
DB 0B0H
DB 099H
DB 092H
DB 082H
DB 0F8H
DB 080H
DB 090H
DB 0FFH

END
温馨提示:内容为网友见解,仅供参考
第1个回答  2010-06-21
只有c的没汇编的,没闹钟功能,要的话留下邮箱
第2个回答  2010-06-25
干脆去买一个电子钟吧,这设计的问题的自己搞啊,遇到技术问题了再问
第3个回答  2010-06-16
这么多要求,才这么点分,估计没人回答

求一个用汇编语言编写一个8051单片机的时钟程序(急急急啊)
KEY_V: DS 1 DIS_DIGIT: DS 1 SEC: DS 1 DIS_INDEX: DS 1 HOUR: DS 1 MIN: DS 1 SEC100: DS 1 DIS_BUF: DS 8 BUF_HOUR_H EQU DIS_BUF ; 小时十位 BUF_HOUR_L EQU DIS_BUF+1 ; 小时个位 BUF_MIN_H EQU DIS_BUF+3 ;...

51单片机编程题,用汇编语言怎么做?
在8051单片机的时钟频率为6MHz,那么定时器的计数脉冲周期就是 2uS;sbit CP=P1^0;void Timer0_init(){ TMOD |=0x01; \/\/T0定时器,方式1,采用16位定时器 TH0 = (65536-500)\/256; \/\/定时器装初值500, 即 1000uS 中断一次 TL0 = (65536-500)%256;EA=1; ET0=1; TR0=1;} ...

用汇编语言做单片机时钟显示
uchar dat,count,f=1;\/\/f测试哪个单元为当前闪烁状态 uchar data clock[3]={24,00,00};uchar code clockname[10]={"北京时间:"};uchar data num[6];\/***主程序***\/ void main(){ lcd_ini();count=10;\/\/机器周期为1us,每次定时50ms,此变量用来控制循环次数,在下面赋值为20,共定时1...

8051单片机汇编程序请教
SJMP ; 实际个数 保存单元 统计个数 ;零个数 14 R2 21 ;正数个数 19 R3 19 ;负数个数: 7 R4 0 ;其实是零和负数没有分开统计,请高手指教一下,谢谢!ORG 400H TABLE:DB 01H, 15H, 22H,0FFH, 00H, 02H, 09H,0F9H, 00H, 00H DB 01H, 15H, ...

8051单片机的汇编程序编程问题!!!
6Mhz,也就是指令周期是2us,0.5ms需要250个计数,250<256,为了速度和效率,我们让定时器1工作在自动重载模式下,也就是模式2;C语言整个程序编程如下;include <reg52.h> bit P1_2_Turn_Cnt = 0; \/\/---用于P1.2的计数翻转,因为只有两次,大可不必用unsigned char类型的 unsigned char P1_3_Turn...

8051单片机时钟电路
8051单片机时钟电路如下所示:电容C2、C3对频率有微调的作用,电容容量的选择范围在30pF±10pF。震荡频率的选择范围为1.2-12MHz。时钟周期=石英振荡器频率的倒数。单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I\/O口和...

用汇编语言编写80c51单片机程序,求内部RAM中50H~59H十个单元内容的平均...
;A=溢出部分的平均值,肯定小于0FF MOV 5AH,A ;第一部分的平均值p1给5AH MOV A,#6H MOV B,5BH MUL AB ;值给5BH,最大值是3CH,所以不用考虑溢出。ADD A,5CH ;MOV B,#10 DIV AB ;6B+s1的平均值p2 ADD A,5AH MOV 5AH,A ;p1+p2 MOV 5BH,B SJMP END ...

51单片机时钟程序,C语言,汇编都行
Set_RTC(); \/\/写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽 while(1){ if(ReadRTC_Flag){ ReadRTC_Flag=0;Read_RTC();l_tmpdisplay[0]=l_tmpdate[2]\/16; \/\/数据的转换,因我们采用数码管0~9的显示,将数据分开 l_tmpdisplay[1]=l_tmpdate[2]&0x...

求用C语言编写一个单片机89C51电子时钟程序,有时,分,秒,还有电路图_百 ...
后读命令\/数据(寄存器多字节方式)调 用:W1302()入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年 7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B返 回 值:无***\/void Set1302(uchar *pClock) { uchar h; uchar ucAddr = 0x80; W1302(0x8e,0x...

C语言编8051FX系列的控制LED灯的程序
是 C8051FXXX系列的单片机么?我用的编译器是Keil C 程序如下:\/\/我用的是310的片子 include<c8051f310.h> include<stdio.h> \/\/初始化系统时钟 void SYSCLK_Init(){ OSCICN = 0x83;} void Port_Init(){ \/\/输出为推挽方式 P1MDOUT = 0xFF;\/\/允许弱上拉,并开启交叉开关 XBR1 = 0x40;}...

相似回答