电子表显示系统时间设计(汇编语言)

电子表显示系统时间设计(汇编语言),第1张

A方案

--------------------------

外加一颗时钟芯片DS1302(非常准确)。

按键为单片机中断。

--------------------------

1、上电时自动显示时、分、秒;

实现方式:上电时单片机去启动DS1202,然后读取里面的时间值,自动显示时、分、秒;

2、设置一个控制按键,按下按键,则时钟以秒为单位开始计时;

实现方式:将DS1302此时的值暂时保存,最为计时开始的时间。

然后不停地读取DS1302里的新的时间值,

并将新的时间值 - 计时开始的时间 = 已计时数值

3、运行状态下可通过控制按键使时钟暂停,同时显示已计时数值;

实现方式:显示步骤2里的已计时数值。

4、停止状态下(已上电),按下复位按钮,时钟复位(清零),并进入下一次计时状态。

实现方式:计时开始的时间换成当前时间。

B方案

--------------------------

采用单片机内部定时器计时(不准)。

按键为单片机中断。

--------------------------

步骤类似,不用去读DS1302的时间,读自己内部的时间。

-------------------------------------------------------------------------------------------------------------------------------------------------------分割线。--------------------------------------------------------------------------

楼上的方案是当前比较常见的方案了。

没有给出程序

先给出A 方案程序如下。。。。//C语言编写。

头文件/

#include <reg52h>

#include <intrinsh>

#define uint unsigned int

#define uchar unsigned char

#define nop() _nop_()

sbit T_CLK = P1^4; /实时时钟时钟线引脚 /

sbit T_IO = P1^5; /实时时钟数据线引脚 /

sbit T_RST = P2^2; /实时时钟复位线引脚 /

sbit ACC0 = ACC^0;

sbit ACC7 = ACC^7;

sbit time_en_port = P3^7; /时间控制通道寄存器LE控制脚/

sbit sled_en_port = P3^6; /数码管控制通道寄存器LE控制脚/

#define sled_dm_port P0 /定义数码管段码的控制脚/

#define sled_wm_port P2 /定义数码管位码的控制脚/

/定义数码管显示字符跟数字的对应数组关系/

uchar code mun_to_char[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

/ 0 1 2 3 4 5 6 7 8 9 a b c d e f /

/定义需要点亮的数码管/

uchar code sled_bit_table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

uchar data sled_data[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; /0-7号SLED缓冲值/

uchar data led_lighten_bit=0 ; /LED灯点亮标志位0-7/

uchar data time_data[8]={0x00,0x57,0x16,0x00,0x00,0x00,0x00,0x00};/格式为: 秒 分 时 日 月 星期 年 /

/-----------------------------------------------

显示部分程序,采用定时器0产生中断,1MS更新一次

------------------------------------------------/

void SLED_Disp() interrupt 1 using 3

{

TH0 = (65536-1000)/256;

TL0 = (65536-1000)/256;

time_en_port = 0; /关闭时钟控制通道/

sled_wm_port = sled_bit_table[led_lighten_bit]; /输出位码数据到数码管/

sled_dm_port = sled_data[led_lighten_bit]; /输出段码数据到数码管/

sled_en_port = 1; /打开数码管控制通道/

sled_en_port = 0; /关闭数码管控制通道/

sled_wm_port = 0xdf; / 释放P2端口,同时关闭发光二极管显示/

time_en_port = 1; /打开时钟控制通道/

led_lighten_bit++;

if(led_lighten_bit>=8) led_lighten_bit=0; /8位数码管全动态输出/

}

void T0_valueSet() /定义中断方式,中断时间/

{

TMOD = 0x01; /定时0,工作在方式1/

TH0 = (65536-1000)/256;

TL0 = (65536-1000)/256;

TR0 = 1; /启动计数/

EA = 1; /开总中断/

ET0 = 1; /开定时器0中断/

return;

}

/

函 数 名:RTInputByte()

功 能:实时时钟写入一字节

说 明:往DS1302写入1Byte数据 (内部函数)

入口参数:d 写入的数据

返 回 值:无

设 计:zhaojunjie 日 期:2002-03-19

修 改: 日 期:

/

void RTInputByte(uchar d)

{

uchar i;

ACC = d;

for(i=8; i>0; i--)

{

T_IO = ACC0; /相当于汇编中的 RRC /

T_CLK = 1;

T_CLK = 0;

ACC = ACC >> 1;

}

}

/

函 数 名:RTOutputByte()

功 能:实时时钟读取一字节

说 明:从DS1302读取1Byte数据 (内部函数)

入口参数:无

返 回 值:ACC

设 计:zhaojunjie 日 期:2002-03-19

修 改: 日 期:

/

uchar RTOutputByte(void)

{

uchar i;

for(i=8; i>0; i--)

{

ACC = ACC >>1; /相当于汇编中的 RRC /

ACC7 = T_IO;

T_CLK = 1;

T_CLK = 0;

}

return(ACC);

}

/

函 数 名:W1302()

功 能:往DS1302写入数据

说 明:先写地址,后写命令/数据 (内部函数)

调 用:RTInputByte() , RTOutputByte()

入口参数:ucAddr: DS1302地址, ucData: 要写的数据

返 回 值:无

设 计:zhaojunjie 日 期:2002-03-19

修 改: 日 期:

/

void W1302(uchar ucAddr, uchar ucDa)

{

T_RST = 0;

T_CLK = 0;

T_RST = 1;

RTInputByte(ucAddr); / 地址,命令 /

RTInputByte(ucDa); / 写1Byte数据/

T_CLK = 1;

T_RST = 0;

}

/

函 数 名:R1302()

功 能:读取DS1302某地址的数据

说 明:先写地址,后读命令/数据 (内部函数)

调 用:RTInputByte() , RTOutputByte()

入口参数:ucAddr: DS1302地址

返 回 值:ucData :读取的数据

设 计:zhaojunjie 日 期:2002-03-19

修 改: 日 期:

/

uchar R1302(uchar ucAddr)

{

uchar ucData;

T_RST = 0;

T_CLK = 0;

T_RST = 1;

RTInputByte(ucAddr); / 地址,命令 /

ucData = RTOutputByte(); / 读1Byte数据 /

T_CLK = 1;

T_RST = 0;

return(ucData);

}

/

函 数 名:BurstW1302T()

功 能:往DS1302写入时钟数据(多字节方式)

说 明:先写地址,后写命令/数据

调 用:RTInputByte()

入口参数:pWClock: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制

8Byte (BCD码)1B 1B 1B 1B 1B 1B 1B 1B

返 回 值:无

设 计:zhaojunjie 日 期:2002-03-19

修 改: 日 期:

/

void BurstW1302T(uchar pWClock)

{

uchar i;

W1302(0x8e,0x00); / 控制命令,WP=0,写 *** 作/

T_RST = 0;

T_CLK = 0;

T_RST = 1;

RTInputByte(0xbe); / 0xbe:时钟多字节写命令 /

for (i = 8; i>0; i--) /8Byte = 7Byte 时钟数据 + 1Byte 控制/

{

RTInputByte(pWClock); / 写1Byte数据/

pWClock++;

}

T_CLK = 1;

T_RST = 0;

}

/

函 数 名:BurstR1302T()

功 能:读取DS1302时钟数据

说 明:先写地址/命令,后读数据(时钟多字节方式)

调 用:RTInputByte() , RTOutputByte()

入口参数:pRClock: 读取时钟数据地址 格式为: 秒 分 时 日 月 星期 年

7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B

返 回 值:无

设 计:zhaojunjie 日 期:2002-03-19

修 改: 日 期:

/

void BurstR1302T(uchar pRClock)

{

uchar i;

T_RST = 0;

T_CLK = 0;

T_RST = 1;

RTInputByte(0xbf); / 0xbf:时钟多字节读命令 /

for (i=8; i>0; i--)

{

pRClock = RTOutputByte(); / 读1Byte数据 /

pRClock++;

}

T_CLK = 1;

T_RST = 0;

}

/

函 数 名:Set1302()

功 能:设置初始时间

说 明:先写地址,后读命令/数据(寄存器多字节方式)

调 用:W1302()

入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年

7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B

返 回 值:无

设 计:zhaojunjie 日 期:2002-03-19

修 改: 日 期:

/

void Set1302(uchar pClock)

{

uchar i;

uchar ucAddr = 0x80;

EA = 0;

W1302(0x8e,0x00); / 控制命令,WP=0,写 *** 作/

for(i =7; i>0; i--)

{

W1302(ucAddr,pClock); / 秒 分 时 日 月 星期 年 /

pClock++;

ucAddr +=2;

}

W1302(0x8e,0x80); / 控制命令,WP=1,写保护/

EA = 1;

}

/

函 数 名:Get1302()

功 能:读取DS1302当前时间

说 明:

调 用:R1302()

入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年

7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B

返 回 值:无

设 计:zhaojunjie 日 期:2002-03-19

修 改: 日 期:

/

void Get1302(uchar ucCurtime[])

{

uchar i;

uchar ucAddr = 0x81;

EA = 0;

for (i=0; i<7; i++)

{

ucCurtime[i] = R1302(ucAddr);/格式为: 秒 分 时 日 月 星期 年 /

ucAddr += 2;

}

EA = 1;

}

void delay_1ms(uchar x)

/ 1MS为单位的延时程序 /

{

uchar j;

while(x--){

for(j=0;j<125;j++)

{;}

}

}

void main()

{

T0_valueSet();

Set1302(time_data);

while(1){

Get1302(time_data);

sled_data[0]=mun_to_char[time_data[2]/0x10];

sled_data[1]=mun_to_char[time_data[2]%0x10];

sled_data[3]=mun_to_char[time_data[1]/0x10];

sled_data[4]=mun_to_char[time_data[1]%0x10];

sled_data[6]=mun_to_char[time_data[0]/0x10];

sled_data[7]=mun_to_char[time_data[0]%0x10];

delay_1ms(200);

}

}

方案B

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

sbit dula=P2^6;

sbit wela=P2^7;

sbit rs=P3^5;

sbit lcden=P3^4;

sbit s1=P3^0;

sbit s2=P3^1;

sbit s3=P3^2;

sbit rd=P3^7;

uchar count,s1num;

char miao,shi,fen;

uchar code table[]=" 2007-7-30 MON";

uchar code table1[]=" 00:00:00";

void delay(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void write_com(uchar com)

{

rs=0;

lcden=0;

P0=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_date(uchar date)

{

rs=1;

lcden=0;

P0=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void init()

{

uchar num;

dula=0;

wela=0;

lcden=0;

// fen=59;

// miao=53;

// shi=23;

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01);

write_com(0x80);

for(num=0;num<15;num++)

{

write_date(table[num]);

delay(5);

}

write_com(0x80+0x40);

for(num=0;num<12;num++)

{

write_date(table1[num]);

delay(5);

}

TMOD=0x01;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

EA=1;

ET0=1;

TR0=1;

}

void write_sfm(uchar add,uchar date)

{

uchar shi,ge;

shi=date/10;

ge=date%10;

write_com(0x80+0x40+add);

write_date(0x30+shi);

write_date(0x30+ge);

}

void keyscan()

{

rd=0;

if(s1==0)

{

delay(5);

if(s1==0)

{ s1num++;

while(!s1);

if(s1num==1)

{

TR0=0;

write_com(0x80+0x40+10);

write_com(0x0f);

}

}

if(s1num==2)

{

write_com(0x80+0x40+7);

}

if(s1num==3)

{

write_com(0x80+0x40+4);

}

if(s1num==4)

{

s1num=0;

write_com(0x0c);

TR0=1;

}

}

if(s1num!=0)

{

if(s2==0)

{

delay(5);

if(s2==0)

{

while(!s2);

if(s1num==1)

{

miao++;

if(miao==60)

miao=0;

write_sfm(10,miao);

write_com(0x80+0x40+10);

}

if(s1num==2)

{

fen++;

if(fen==60)

fen=0;

write_sfm(7,fen);

write_com(0x80+0x40+7);

}

if(s1num==3)

{

shi++;

if(shi==24)

shi=0;

write_sfm(4,shi);

write_com(0x80+0x40+4);

}

}

}

if(s3==0)

{

delay(5);

if(s3==0)

{

while(!s3);

if(s1num==1)

{

/ if(miao==0)

{

miao=59;

write_sfm(10,miao);

write_com(0x80+0x40+10);

}/

miao--;

if(miao==-1)

miao=59;

write_sfm(10,miao);

write_com(0x80+0x40+10);

}

if(s1num==2)

{

fen--;

if(fen==-1)

fen=59;

write_sfm(7,fen);

write_com(0x80+0x40+7);

}

if(s1num==3)

{

shi--;

if(shi==-1)

shi=23;

write_sfm(4,shi);

write_com(0x80+0x40+4);

}

}

}

}

}

void main()

{

init();

while(1)

{

keyscan();

}

// while(1);

}

void timer0() interrupt 1

{

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

count++;

if(count==18)

{

count=0;

miao++;

if(miao==60)

{

miao=0;

fen++;

if(fen==60)

{

fen=0;

shi++;

if(shi==24)

{

shi=0;

}

write_sfm(4,shi);

}

write_sfm(7,fen);

}

write_sfm(10,miao);

}

}

以上的程序都是用C编写 如果是初学还是直接用C编写吧 虽然汇编也很好用 但是C已经是时代的趋势了。。

如果以上能帮到你 请给分哦。。 有什么不懂得也可以问我。

STACK SEGMENT STACK

DW 200 DUP ()

STACK ENDS

DATA SEGMENT

WHOUR DB 0 ;秒表的时、分、秒、毫秒

WMIN DB 0

WSEC DB 0

WMSEC DB 0

OLD1CH DD 0

SIGNAL DB 0

COUNT DW 0

;---------------------------------------------------------------------------------------------------------------

CHOUR DB 0 ;闹钟的时、分、秒

CMIN DB 0

CSEC DB 0

;-----------------------------------------------------------------------------------------------------------------

SPACE DB 2000 DUP (' ')

PATTERN DB 6 DUP (' '),0C9H,26 DUP (0CDH),0BBH,6 DUP (' ')

DB 6 DUP (' '),0BAH,26 DUP (20H),0BAH,6 DUP (' ')

DB 6 DUP (' '),0C8H,26 DUP (0CDH),0BCH,6 DUP (' ')

;----------------------------------------------------------------------------------------------------------------

DBUFFER DB 8 DUP (':'),12 DUP (' ')

DBUFFER1 DB 20 DUP (' ')

DBUFFER2 DB 11 DUP (':'),15 DUP (' ')

STR DB 0DH,0AH, ' INPUT ''M'' TO NEXT-STATE, INPUT ''Q'' TO EXIT: $',0DH,0AH,'$'

DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK

;-------------------------------------------------------------------

PUSHA MACRO

PUSH DS

PUSH AX

PUSH BX

PUSH CX

PUSH DX

ENDM

POPA MACRO

POP DX

POP CX

POP BX

POP AX

POP DS

ENDM

;图形化界面设计

START:

MOV AX,DATA

MOV DS,AX

MOV ES,AX

MOV AX,0003H ;设置显示方式为4025彩色文本方式

INT 10H

LEA DX,STR ;显示提示信息

MOV AH,9

INT 21H

MOV BP,OFFSET SPACE

MOV DX,0B00H

MOV CX,1000

MOV BX,0000H

MOV AX,1300H

INT 10H ;显示字符串,定义显示方式

;---------------------------------------------------------------

;主程序

LP1:

MOV AH,1 ;从键盘输入单个字符

INT 21H

CMP AL,'M' ;AL='M'?

JNE LP5

CALL DATE ;显示系统日期

LP2: MOV AH,1 ;从键盘输入单个字符

INT 21H

CMP AL,'M' ;AL='M'?

JNE LP5

CALL TIME ;显示系统时间

LP3: MOV AH,1 ;从键盘输入单个字符

INT 21H

CMP AL,'M' ;AL='M'?

JNE LP4

CALL STOPWATCH ;显示秒表

LP4: MOV AH,1 ;从键盘输入单个字符

INT 21H

CMP AL,'M' ;AL='M'?

JNE LP5

CALL RING

LP5: CMP AL,'Q' ;AL='Q'?

JNE LP1

MOV AH,4CH ;返回DOS状态

INT 21H

;---------------------------------------------------------------

;显示日期子程序

DATE PROC NEAR

DISPLAY:

MOV AH,2AH ;取日期CX:DH:DL=年:月:日 AL=星期

INT 21H

MOV SI,0

MOV AX,CX

MOV BX,100

DIV BL

MOV BL,AH

CALL BCDASC1 ;日期数值转换成相应的ASCII码字符

MOV AL,BL

CALL BCDASC1

INC SI

MOV AL,DH

CALL BCDASC1

INC SI

MOV AL,DL

CALL BCDASC1

MOV BP,OFFSET DBUFFER1

MOV DX,0C0DH

MOV CX,20

MOV BX,004EH

MOV AX,1301H

INT 10H

MOV AH,02H ;设置光标位置

MOV DX,0300H

MOV BH,0

INT 10H

MOV BX,0018H

REPEA:MOV CX,0FFFFH ;延时

REPEAT:LOOP REPEAT

DEC BX

JNZ REPEA

MOV AH,01H ;读键盘缓冲区字符到AL寄存器

INT 16H

JE DISPLAY

JMP LP2

MOV AX,4C00H

INT 21H

RET

DATE ENDP

;------------------------------------------------------

;显示时间子程序

TIME PROC NEAR

DISPLAY1:

MOV SI,0

MOV BX,100

DIV BL

MOV AH,2CH ;取时间CH:CL=时:分 DH:DL=秒:1/100秒

INT 21H

MOV AL,CH

CALL BCDASC ;将时间数值转换成ASCII码字符

INC SI

MOV AL,CL

CALL BCDASC

INC SI

MOV AL,DH

CALL BCDASC

MOV BP,OFFSET DBUFFER

MOV DX,0C0DH

MOV CX,20

MOV BX,004EH

MOV AX,1301H

INT 10H

MOV AH,02H

MOV DX,0300H

MOV BH,0

INT 10H

MOV BX,0018H

RE: MOV CX,0FFFFH

REA: LOOP REA

DEC BX

JNZ RE

MOV AH,01H

INT 16H

JE DISPLAY1

JMP LP3

MOV AX,4C00H

INT 21H

RET

TIME ENDP

;------------------------------------------------------

;显示秒表子程序

STOPWATCH PROC NEAR

DISPLAY2:

PUSHA

MOV SI,0

MOV BX,100

DIV BL

;CALL WATCH

DISP3:

MOV AX,DATA

MOV DS,AX

MOV AL,WHOUR

CALL BCDASC2 ;将时间数值转换成ASCII码字符

INC SI

MOV AL,WMIN

CALL BCDASC2

INC SI

MOV AL,WSEC

CALL BCDASC2

MOV AL,WMSEC

INC SI

CALL BCDASC2

MOV BP,OFFSET DBUFFER2

MOV DX,0C0DH

MOV CX,20

MOV BX,004EH

MOV AX,1301H

INT 10H

MOV AH,02H

MOV DX,0300H

MOV BH,0

INT 10H

MOV BX,0018H

RE2: MOV CX,0FFFFH

REA2: LOOP REA2

DEC BX

JNZ RE2

MOV AH,01H

INT 16H

JE DISPLAY2

POPA

JMP LP4

MOV AX,4C00H

INT 21H

RET

STOPWATCH ENDP

;----------------------------------------------------------------

;显示闹钟子程序

RING PROC NEAR

DISPLAY3:

PUSHA

MOV SI,0

MOV BX,100

DIV BL

;MOV AH,CH ;取时间CH:CL=时:分 DH:DL=秒:1/100秒

;INT 21H

MOV AX,DATA

MOV DS,AX

MOV AL,CHOUR

CALL BCDASC ;将时间数值转换成ASCII码字符

INC SI

MOV AL,CMIN

CALL BCDASC

INC SI

MOV AL,CSEC

CALL BCDASC

MOV BP,OFFSET DBUFFER

MOV DX,0C0DH

MOV CX,20

MOV BX,004EH

MOV AX,1301H

INT 10H

MOV AH,02H

MOV DX,0300H

MOV BH,0

INT 10H

MOV BX,0018H

RE3: MOV CX,0FFFFH

REA3: LOOP REA3

DEC BX

JNZ RE3

MOV AH,01H

INT 16H

JE DISPLAY3

POPA

JMP START

MOV AX,4C00H

INT 21H

RET

RING ENDP

;----------------------------------------------------------------

;时间数值转换成ASCII码字符子程序

BCDASC PROC NEAR

PUSH BX

CBW

MOV BL,10

DIV BL

ADD AL,'0'

MOV DBUFFER[SI],AL

INC SI

ADD AH,'0'

MOV DBUFFER[SI],AH

INC SI

POP BX

RET

BCDASC ENDP

;-----------------------------------------------------------------

;日期数值转换成ASCII码字符子程序

BCDASC1 PROC NEAR

PUSH BX

CBW

MOV BL,10

DIV BL

ADD AL,'0'

MOV DBUFFER1[SI],AL

INC SI

ADD AH,'0'

MOV DBUFFER1[SI],AH

INC SI

POP BX

RET

BCDASC1 ENDP

;------------------------------------------------------------------

;秒表时间数值转换成ASCII码字符子程序

BCDASC2 PROC NEAR

PUSH BX

CBW

MOV BL,10

DIV BL

ADD AL,'0'

MOV DBUFFER2[SI],AL

INC SI

ADD AH,'0'

MOV DBUFFER2[SI],AH

INC SI

POP BX

RET

BCDASC2 ENDP

;---------------------------------------------------------------------

CODE ENDS

END START

这是主要的程序,完全可以用其它的子程序比较多,我再发给你好了

以上就是关于电子表显示系统时间设计(汇编语言)全部的内容,包括:电子表显示系统时间设计(汇编语言)、汇编程序:实现一个24小时制的电子钟程序、急求单片机电子时钟程序,用汇编写的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/9574789.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存