电子日历时钟系统程序设计,汇编程序设计

电子日历时钟系统程序设计,汇编程序设计,第1张

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

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

电子时钟?说的不明白,我自己编写的数码管现实的电子钟给你了

SDA BIT P36

SCL BIT P15

org 0000H

AJMP STAR

ORG 000BH

LJMP INT

STAR:

MOV PSW,#00H

MOV TH0,#3cH

MOV TL0,#0b0H

MOV TMOD,#01H

MOV R3,#14H

SETB ET0

SETB EA

setb p36

setb p15

MOV R0,#79H

MOV R1,#00H

READ:

LCALL READ_BYTE

MOV @R0,A

INC R0

INC R1

CJNE R0,#08H,READ

SETB TR0

;MOV 79H,#00H

;MOV 7AH,#00H

;MOV 7BH,#0AH

;MOV 7CH,#00H

;MOV 7DH,#0AH

;MOV 7EH,#00H

MAIN:

MOV DPTR,#TAB

MOV R0,#07H

MOV R1,#79H

JNB P32,JS

GO:

MOV A,@R1

MOVC A,@A+DPTR

MOV P0,A

MOV P2,R0

LCALL DELY

CJNE R0,#02H,GO1

AJMP MAIN

GO1:

DEC R0

INC R1

AJMP GO

INT:

PUSH ACC

DJNZ R3,NEXT

MOV R3,#14H

;MOV R3,#02H

INC 79H

MOV R4,79H

CJNE R4,#0AH,NEXT

MOV 79H,#00H

INC 7AH

MOV R4,7AH

CJNE R4,#06H,NEXT

MOV 7AH,#00H

INC 7BH

MOV R4,7BH

CJNE R4,#14H,NEXT

MOV 7BH,#0AH

INC 7CH

MOV R4,7CH

CJNE R4,#06H,NEXT

MOV 7CH,#00H

INC 7DH

MOV R4,7EH

CJNE R4,#02H,TWO

MOV R4,7DH

CJNE R4,#0eH,NEXT

mov 7dh,#0ah

AJMP ONE

TWO:

MOV R4,7DH

CJNE R4,#14H,NEXT

mov 7dh,#0ah

ONE:

INC 7EH

MOV R4,7EH

CJNE R4,#03H,NEXT

MOV 7EH,#00H

NEXT:

MOV TH0,#3CH

MOV TL0,#0B0H

;MOV TH0,#0feH ;检测

;MOV TL0,#0fbH

POP ACC

RETI

js:;按键检测

lcall del

jb P32,main

JNB P32,$

clr ea

CSH:

MOV R0,#7EH

MOV R1,#02H

STA:

MOV DPTR,#TAB

MOV A,@R0

MOVC A,@A+DPTR

MOV P0,A

MOV P2,R1

JNB P32,CLK1

JNB P33,CLK2

JNB P34,CLK3

AJMP STA

CLK3:

LCALL DEL

JB P34,STA

JNB P34,$

SETB EA

mov R0,#79h

MOV R1,#00H

WRITE:

lcall del

LCALL WRITE_BYTE

INC R0

INC R1

CJNE R1,#06H,WRITE

AJMP MAIN

CLK1:

LCALL DEL

JB P32,STA

JNB P32,$

DEC R0

INC R1

CJNE R1,#06H,STA

AJMP CSH

CLK2:

LCALL DEL

JB P33,STA

JNB P33,$

CJNE R1,#02H,THR

mov r3,7dh

cjne r3,#0eh,TMD2

tmd2:

jnc tmd

CJNE @R0,#02H,BUS1

MOV 7EH,#00H

AJMP STA

tmd:

cjne @r0,#01h,bus1

mov 7eh,#00h

ajmp sta

BUS1:

INC 7EH

AJMP STA

THR:

CJNE R1,#03H,FOR

MOV R3,7eH

CJNE R3,#02H,BUS2

CJNE @R0,#0dH,BUS3

MOV 7DH,#0AH

AJMP STA

BUS3:

INC 7DH

AJMP STA

BUS2:

CJNE @R0,#13H,BUS3

MOV 7DH,#0AH

AJMP STA

FOR:

CJNE R1,#04H,FIV

CJNE @R0,#05H,BUS6

MOV 7CH,#00H

AJMP STA

BUS6:

INC 7CH

AJMP STA

FIV:

CJNE @R0,#13H,BUS7

MOV 7BH,#0AH

AJMP STA

BUS7:

INC 7BH

LJMP STA

WRITE_BYTE:

CALL START

MOV A,#0A0H

CALL SENDBYTE;选通地址写入

CALL WAITACK

MOV A,r1;入24c02的地址

CALL SENDBYTE;将24c02的地址写入

CALL WAITACK

MOV A,@R0;可以传数据了

CALL SENDBYTE

CALL WAITACK

CALL STOP

RET

READ_BYTE:

CALL START;{

MOV A,#0A0H; 先写写入选通地址,再写读入地址,再写读入选通地址,再读?这样 *** 作的么?

CALL SENDBYTE;

CALL WAITACK; 我认为应该先写读入选通地址,再写读入地址,直接读?不行么?

MOV A,R1;

CALL SENDBYTE; 没资料了···再找找吧!

CALL WAITACK; }

CALL START; C语言也是这个意思,看样这人写的不错

MOV A,#0A1H;

CALL SENDBYTE

CALL WAITACK

CALL RCVBYTE

CALL STOP

RET

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

;从IIC总线上接收一个字节数据

;出口参数:A---接收数据存放在A中

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

RCVBYTE:

MOV R7,#08;一个字节共接收8位数据

CLR A

SETB SDA;释放SDA数据线

R_BYTE:

CLR SCL

NOP

NOP

NOP

NOP

SETB SCL ;启动一个时钟周期,读总线

NOP

NOP

NOP

NOP

MOV C,SDA;将SDA状态读入C

RLC A;结果移入A

SETB SDA;释放SDA数据线

DJNZ R7,R_BYTE;判断8位数据是否接收完全?

RET

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

;向IIC总线发送一个字节数据

;入口参数:A---待发送数据存放在A中

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

SENDBYTE:

MOV R7,#08

S_BYTE:

RLC A

MOV SDA,C

SETB SCL

NOP

NOP

NOP

NOP

CLR SCL

DJNZ R7,S_BYTE ;8位发送完毕

RET

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

;等待应答信号

;等待从机返回一个响应信号

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

WAITACK:

CLR SCL

nop

nop

nop

SETB SDA ;释放SDA信号线

NOP

NOP

nop

SETB SCL

NOP

NOP

NOP

MOV C,SDA

JC WAITACK ;SDA为低电平,返回了响应信号

CLR SDA

CLR SCL

RET

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

;启动信号子程序

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

START:

SETB SDA

SETB SCL

NOP

nop

nop

CLR SDA

NOP

NOP

NOP

NOP

CLR SCL

RET

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

;停止信号子程序

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

STOP:

CLR SDA

NOP

nop

nop

SETB SCL

NOP

NOP

NOP

NOP

SETB SDA

NOP

NOP

CLR SCL;

CLR SDA;

RET

DEL:

MOV R6,#0ffH

DL1:MOV R7,#022H

DL2:DJNZ R7,DL2

DJNZ R6,DL1

RET

DELY:

MOV R6,#4

D1:MOV R7,#248

DJNZ R7,$

DJNZ R6,D1

RET

TAB:

DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,0BfH,86H,0DBH,0CFH,0E6H,0EDH,0fdh,87H,0FFH,0EFH

END

其中包含IIC的部分可以不看,我是用来测试24C02的

接法:P0口段码,P1口接了三八译码器,p3的几个口是调时间用的

#include <reg51h>

#define uchar unsigned char //定义unsigned int为uint

#define uint unsigned int //定义unsigned uchar为uchar

sbit LCD_RS = P2^0 ;

sbit LCD_RW = P2^1 ;

sbit LCD_EN = P2^2 ;

sbit D_SDA = P2^6; //定义74HC164数据线为P26端口

sbit D_SCL = P2^7; //定义74HC164数据线为P27端口

sbit CLK = P1^3; /实时时钟时钟线引脚 /

sbit IO = P1^4; /实时时钟数据线引脚 /

sbit RST = P1^5; /实时时钟复位线引脚 /

sbit ACC0 = ACC^0;

sbit ACC7 = ACC^7;

uchar time[8] = {0x50,0x30,0x19,0x30,0x12,0x06,0x06};

//========= 延时函数 ============

//延时时间以1ms为单位

//s决定延时时间长短

void delay_ms(uint s)

{

uint x;

for(s;s>0;s--)

{

x = 200;

while(x--);

}

}

//========= 送出一个字节给74HC164(实现串并转换) ==========

void send_out(unsigned char out)//传送一个字节8位

{

uchar i;

D_SCL = 0;

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

{

D_SDA = out&0x80; //送数据到数据口

D_SCL = 1; //时钟线置1

D_SCL = 0; //送一时钟

out<<=1; //左移

}

}

//========= 写命令函数 ==========

void lcd_wcmd(uchar cmd)

{

LCD_RS = 0;

LCD_RW = 0;

LCD_EN = 0;

send_out(cmd);

LCD_EN = 1;

LCD_EN = 0 ;

}

//========= 写数据函数 ==========

void lcd_wdat(uchar dat)

{

LCD_RS = 1;

LCD_RW = 0;

LCD_EN = 0;

send_out(dat);

LCD_EN = 1;

LCD_EN = 0;

}

//========= LCD初始化函数 ==========

void lcd_init()

{

lcd_wcmd(0x38);

delay_ms(1);

lcd_wcmd(0x0c); //显示开,关光标

delay_ms(1);

lcd_wcmd(0x06); //向右移动光标

delay_ms(1);

lcd_wcmd(0x01); //清除LCD显示屏

delay_ms(1);

}

//========== 往DS1302写入1Byte数据 (内部函数) =============

void w_byte(uchar dat)

{

uchar i;

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

{

IO = dat & 0x01;

CLK = 1;

CLK = 0;

dat = dat >> 1;

}

}

//======== 从DS1302读取1Byte数据 (内部函数) ===================

uchar r_byte(void)

{

uchar i;

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

{

ACC = ACC >> 1;

ACC7 = IO;

CLK = 1;

CLK = 0;

}

return(ACC);

}

//========== 指定地址往DS1302写入1Byte数据 (内部函数) =============

void write_byte(uchar addr, uchar dat)

{

RST = 0;

CLK = 0;

RST = 1;

w_byte(addr);

w_byte(dat);

CLK = 1;

RST = 0;

}

//========== 指定地址往DS1302读1Byte数据 (内部函数) =============

uchar read_byte(uchar addr)

{

uchar ucData;

RST = 0;

CLK = 0;

RST = 1;

w_byte(addr);

ucData = r_byte();

CLK = 1;

RST = 0;

return(ucData);

}

//============ 设置ds1302日期和时间 =============

void write_ds1302(uchar p)

{

uchar i;

uchar addr = 0x80;

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

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

{

write_byte(addr,p); // 秒 分 时 日 月 星期 年

p++;

addr +=2;

}

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

}

//============ 读ds1302当前日期和时间 =============

void read_ds1302(uchar p)

{

uchar i;

uchar addr = 0x81;

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

{

p = read_byte(addr); //格式为: 秒 分 时 日 月 星期 年

addr += 2;

p++;

}

}

//============ 显示函数 ===================

void lcd_disp()

{

uchar addr = 4;

lcd_wcmd(0x80 + addr);

lcd_wdat(((time[2]>>4)&0x0f)+0x30); //显示小时

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat((time[2]&0x0f)+0x30);

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat(':'); //显示":"

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat(((time[1]>>4)&0x0f)+0x30); //显示分

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat((time[1]&0x0f)+0x30);

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat(':'); //显示":"

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat(((time[0]>>4)&0x0f)+0x30); //显示秒

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat((time[0]&0x0f)+0x30);

addr = 2;

lcd_wcmd(0xc0 + addr); //在第二行显示年月日和星期

lcd_wdat('2'); //显示2

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat('0'); //显示0

addr++;

lcd_wdat(((time[6]>>4)&0x0f)+0x30); //年

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat((time[6]&0x0f)+0x30);

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat(' ');

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat(((time[4]>>4)&0x0f)+0x30); //显示月

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat((time[4]&0x0f)+0x30);

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat(' ');

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat(((time[3]>>4)&0x0f)+0x30); //显示日

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat((time[3]&0x0f)+0x30);

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat(' ');

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat((time[5]&0x0f)+0x30); //显示星期

}

//=========== 主函数 ===============

void main()

{

lcd_init(); // 初始化LCD

write_ds1302(time);

while(1)

{

read_ds1302(time); //读DS1302数据

lcd_disp(); //LCD显示

delay_ms(500); //延时05秒

}

}

这是一个电子时钟,在LCD1602上显示,时钟芯片是DS1302

/ ch07-5-3c - 计时器实验3 -60秒计数器,每1分钟LED反相1次 /

//==声明区================================

#include // 定义8x51暂存器之标头档,P2-17~19

#define SEG P2 // 定义七节显示器接至Port 2

#define SCANP P1 // 定义扫瞄线接至Port 1

sbit LED=P0^7; // 声明LED接至P07

/声明T0计时相关声明/ // THx TLx 计算参考

#define count_M1 50000 // T0(MODE 1)之计量值,005s

#define TH_M1 (65636-count_M1)/256// T0(MODE 1)计量高8位元

#define TL_M1 (65636-count_M1)%256// T0(MODE 1)计量低8位元

int count_T0=0; // 计算 T0中断次数

/声明T1扫瞄相关声明/

#define count_M2 250 // T1(MODE 2)之计量值,025ms

#define TH_M2 (256-count_M2) // T1(MODE 2)自动载入计量

#define TL_M2 (256-count_M2) // T1(MODE 2)计数量

char count_T1=0; // 计算 T1中断次数

/ 声明七节显示器驱动信号阵列(共阳) /

char code TAB[10]={ 0xc0, 0xf9, 0xa4, 0xb0, 0x99, //数字0-4

0x92, 0x83, 0xf8, 0x80, 0x98 }; //数字5-9

char disp[2]={ 0xc0, 0xc0 }; // 声明显示区阵列初始显示00

/ 声明基本变量 /

char seconds=0; // 秒数

char scan=0; // 扫瞄信号

//==主程序================================

main() // 主程序开始

{ IE=0x8a; // 1000 1010,启用TF0、TF1中断(6-4页)

TMOD=0x21; // 0010 0001,T1采mode 2、T0采mode 1

TH0=TH_M1; TL0=TL_M1;// 设置T0计数量高8位元、低8位元

TR0=1; // 启动T0(7-7页)

TH1=TH_M2; TL1=TL_M2;// 设置T1自动载入值、计数量

TR1=1; // 启动T1

LED=1; // 关闭LED

while(1); // 无穷回圈,程序停滞

} // 主程序结束

//== T0中断子程序- 计算并显示秒数 ==================

void T0_1s(void) interrupt 1 // T0中断子程序开始

{ TH0=TH_M1; TL0=TL_M1; // 设置T0计数量高8位元、低8位元

if (++count_T0==20) // 若中断20次,即005x20=1秒

{ count_T0=0; // 重新计次

seconds++; // 秒数加1

if (seconds==60) // 若超过60秒

{ seconds=0; // 秒数归0,重新开始

LED=~LED; // 切换LED

} // if叙述结束(超过60秒)

} // if叙述结束(中断20次)

disp[1]=TAB[seconds/10]; // 填入十位数显示区

disp[0]=TAB[seconds%10]; // 填入个位数显示区

} // T0中断子程序结束

//===T1中断子程序 - 扫瞄 =========================

void T1_8ms(void) interrupt 3 // T1中断子程序开始

{ if (++count_T1==32) // 若中断32次,即025mx32=8ms

{ count_T1=0; // 重新计次

if (++scan==3) scan=1;// 若超过十位数,显示个位

SEG=0xff; // 关闭7段显示器

SCANP=~scan; // 输出扫瞄信号

SEG=disp[scan-1]; // 输出显示信号

} // 结束if判断(中断32次)

} // T0中断子程序结束

自己写了一个时钟程序,用来模拟时间类型软件的破解,先从基础的运行时间开始,程序运行界面如图:十秒后程序自动退出

十秒后程序自动退出

破解思路:查看程序导入表函数(有N多个程序可以查看,以PETOOLS为例),如图所示:输入表目录

只找到一个和时间有关的函数GetSystemTimeAsFileTime。我们可以通过od自带的api断点,去断下GetSystemTimeAsFileTime这个函数,

Enter进入,在系统领空下段,运行程序,会断在这个函数的系统领空,之后ctrl+F9执行到返回到,call GetSystemTimeAsFileTime的调用,再ctrl+F9执行到返回,来到如下关键代码处:

可见通过上面call函数clock的调用,返回值去和10比较,来判断程序运行的时间,修改跳转或者修改A的值即可实现破解。

以上就是关于电子日历时钟系统程序设计,汇编程序设计全部的内容,包括:电子日历时钟系统程序设计,汇编程序设计、电子时钟程序用汇编语言编写、求c51单片机电子钟程序(c语言)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: https://outofmemory.cn/zz/9705185.html

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

发表评论

登录后才能评论

评论列表(0条)

保存