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语言)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)