汇编语言 秒表程序设计

汇编语言 秒表程序设计,第1张

程序

push ds ;保存数据

mov ax,0000

mov ds,ax ;数据段清零

mov ax,offset irq7 ;取中断程序入口地址

add ax,2000 ;加装时IP=2000地址

mov si,003c ;填8259中断7中断矢量

mov w[si],ax ;填偏移量矢量

mov ax,0000 ;段地址CS=0000H

mov si,003e

mov w[si],ax ;填段地址矢量

pop ds ;d栈

in al,21 ;读8259中断屏蔽字

and al,7f ;开8259中断7

out 21,al

mov al,b4 ;8253的计数器2为方式2,采用二进制计数,先低后高写入计数值 10110100

out 43,al ;写入方式控制字

mov ax,2e9c 0010 1110 1001 1100B 11932D

out 42,al ;写入低字节计数值 1001 1100

mov al,ah

out 42,al ;写入高字节计数值 0010 1110

mov al,81 ;8255的A口为方式0输出,B口为方式0输出,C口下部输入 1000 0001

out 63,al ;写方式控制字

call first ;调用first子程序,赋计数初值

begi:hlt 延时等待

sti ;开中断

mov ah,01

int 16 ;检测是否按了键盘

jz begi

mov ah,00 ;读键值

int 16

cmp al,0d ;是否按了回车

jnz A1

mov si,4000

not [si+04] ;偏移地址为4004的内存单元内容取反

jmp begi

A1:cmp al,1b ;是否按了ESC键

jnz A2

call first ;重新赋初值,相当于清零

A2:jmp begi

中断程序:

irq7:call disp ;调用disp子程序,用来在数码管显示数据

mov si,4000

cmp [si+04],00 ;判断是否按了第2次回车键

je A4

call addn ;调用addn子程序,用来计数

A4:mov al,20

out 20,al

cli ;关中断

iret ;返回

addn程序:

addn:mov si,4000

add [si+03],01 ;百分之一秒加1

cmp [si+03],0a ;判断是否大于10

jz A5

jmp A9

A5:mov [si+03],00

Add [si+02],01 ;十分之一秒加1

cmp [si+02],0a ;判断是否大于10

jz A6

jmp A9

A6:mov [si+02],00

add [si+01],01 ;秒位加1

cmp [si+01],0a ;判断是否大于10

jz A7

jmp A9

A7:mov [si+01],00

add [si],01 ;十秒位加1

cmp [si],06 ;判断是否大于6

jz A8

jmp A9

A8:mov [si],00 ;大于60:00重新开始

A9: ret

赋初值程序:

first:mov si,4000

mov al,00

mov [si],al

mov [si+01],al

mov [si+02],al

mov [si+03],al

mov [si+04],al

ret

显示程序:

disp:push ax ;保存AX

mov si,4000 ;指向数据缓冲区

mov dl,f7 ;1111 0111 指向数码管

mov al,dl ;al=1111 0111

again:out 60,al ;写端口A

mov al,[si]

mov bx,4100 ;指向数码缓冲区 bx=0100 0001 0000 0000

and ax,00ff ; ax=0000 0000 al

add bx,ax ;得到显示代码 bx=0100 0001 al

mov al,[bx]

out 61,al ;写端口B

call dally :调用延时程序dally

inc si

mov al,dl

test al,01

jz out

ror al,1 ;指向下一个数码管

mov dl,al

jmp again

out: pop ax ;d出AX

ret

dally:push cx ;延时程序

push ax

mov cx,0010

t1 :mov ax,0010

t2 dec ax

jnz t2

loop t1

pop ax

pop cx

ret

数码缓冲区:

0000:4000 3f,06,5b4f,66,6d,7d,07,7f,6f

二、 设计思想

电子秒表要实现的功能:用键盘中断来控制整个程序,按一下回车键启动电子秒表,再按一下暂停,按一下ESC键清零,用七段数码管显示时间。整个程序涉及到8255、8253与8259三个芯片。8253的OUT2,CLK2分别连接8259的IRQ7与PCLK,8253的GATE2连接正5伏电压,采用计数器2每隔001秒产生一次中断并且计数,写入以偏移地址4000H开始的4个内存单元,然后利用8255将内存单元的数据输出到七段数码管。由于键盘中断优先于8259的7号中断,所以程序只有在按一下回车键才启动电子秒表,再按一下暂停,按一下ESC键清零,如果超出了60秒,整个程序自动重新开始。

三、 所用芯片工作原理

8255:接口电路在CPU和I/O设备之间起着信号的变换和传输的作用。 任何接口电路与CPU之间的信息传输方式都是并行的,即CPU与接口电路之间以数据字节/字为单位传送信息。接口电路与I/O设备之间的信息传送方式,有并行和串行两种,相应的接口电路称为并行接口和串行接口。

并行接口是在多根数据线上,以数据字节/字与I/O设备交换信息。在输入过程中,输入设备把数据送给接口,并且使状态线“输入准备好”有效。接口把数据存放在“输入缓冲寄存器”中,同时使“输入回答”线有效,作为对外设的响应。外设在收到这个回答信号后,就撤消数据和“输入准备好”信号。数据到达接口中后,接口会在“状态寄存器”中设置输入准备好标志,或者向CPU发一个中断请求。CPU可用查询方式或中断方式从接口中读取数据。接口中的数据被读取后,接口会自动清除状态寄存器中的标志,且撤消对CPU的中断请求。

在输出过程中,每当输出寄存器可以接收数据,接口就会将状态寄存器中“输出准备好”状态置1或向CPU发一个中断请求,CPU可用查询或中断方式向接口输出数据。当CPU输出的数据到达接口后,接口会清除“输出准备好”状态,把数据送往外设,并向外设发一个“数据输出准备好”信号。外设受到驱动后,便接收数据,并向接口电路发一个“输出回答”信号,接口收到该回答信号后,又将状态寄存器中“输出准备好”置位,以便CPU输出下一个数据。

8253:对CLK信号进行“减1计数”。首先CPU把“控制字”,写入“控制寄存器”,把“计数初始值”写入“初值寄存器”,然后, 定时/计数器按控制字要求计数。计数从“计数初始值 开始,每当CLK信号出现一次,计数值减1,当计数值减为0时,从OUT端输出规定的信号(具体形式与工作模式有关)。当CLK信号出现时,计数值是否减1(即是否计数),受到“门控信号”GATE的影响,一般,仅当GATE有效时,才减1门控信号GATE如何影响计数 *** 作,以及输出端OUT在各种情况下输出的信号形式与定时/计数器的工作模式有关。

8259:1 IR线上提出了中断请求的中断源,即出现请求,IRR中断请求寄存器(共有8位D7~D0)对应于连接在IR0~IR7线上的外设的中断请求,哪一根输入线有请求,哪一根输入线就置1。

2 若OCW1(IMR中断屏蔽寄存器)未使该中断请求屏蔽(对应位为0时不屏蔽),该请求被送入PR(优先权分析器)比较。否则,不送入PR比较。

3 PR把新进入的请求与ISR(服务中寄存器)中正在被处理的中断进行比较。如果新进入的请求优先级较低,则8259不向CPU提出请求。如果新进入的请求优先级较高,则8259使INT引脚输出高电平,向CPU提出请求。

4 如果CPU内部的标志寄存器中的IF(中断允许标志)为0,CPU不响应该请求。若IF=1,CPU在执行完当前指令后,从CPU的INTA引脚上向8259发出两个负脉冲。

5第一个 INTA负脉冲到达8259时,8259完成以下三项工作:

a使IRR(中断请求寄存器)的锁存功能失效。这样一来,在IR7~IR0上的请求信号就不会被8259接收。直到第二个INTA负脉冲到达8259时,才又使IRR的锁存功能有效。

b使ISR(服务中寄存器)中的相应位置1。

c使IRR中的相应位清0。

6第二个INTA负脉冲到达8259时,8259完成以下工作:

a将中断类型码(ICW2中的值)送到数据总线上,CPU将其保存在“内部暂存器”中。

b如果ICW4(它设定级中断联方式之特定完全嵌套方式,将在8259的工作方式中详述ICW4)中设置了中断自动结束方式,则将ISR的相应位清0。

AJMP STRAT

ORG 0003H ;中断0入口地址

ACALL DEL

AJMP INTA ;跳转到中断0服务程序

ORG 0013H ;中断1入口地址

ACALL DEL

AJMP INTB ;跳转到中断1服务程序

STRAT:SETB EA

SETB EX0

SETB EX1

SETB IT0

SETB IT1

;

A8:MOV R6,#0 ;24进制计数器

MOV R5,#0

MOV 25H,#3FH ;时十位

A7:MOV R4,#0

MOV 24H,#3FH ;时个位

A6:MOV R3,#0

MOV 23H,#3FH ;分十位

A5:MOV R2,#0

MOV 22H,#3FH ;分个位

A4:MOV R1 ,#0

;MOV 21H,#3FH; ;秒十位

SETB 21H0

SETB 21H1

SETB 21H2

SETB 21H3

SETB 21H4

SETB 21H5

CLR 21H6

CLR 21H7

A3:MOV R0,#0

MOV 20H,#3FH ;秒个位

;

A2:MOV A,R0

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV 20H,A

MOV A,R1

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV 21H,A

MOV A,R2

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV 22H,A

MOV A,R3

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV 23H,A

MOV A,R4

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV 24H,A

MOV A,R5

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV 25H,A

;

MOV 31H,#21

B1:MOV 30H ,#0F0H

A1:MOV P0,20H ;点亮秒个位数码管

CLR P13

ACALL DEL

SETB P13

MOV P0,21H ;点亮秒十位数码管

CLR P12

ACALL DEL

SETB P12

MOV P0,22H ;点亮分个位数码管

CLR P11

ACALL DEL

SETB P11

MOV P0,23H ;点亮分十位数码管

CLR P10

ACALL DEL

SETB P10

MOV P0,24H ;点亮时个位数码管

CLR P27

ACALL DEL

SETB P27

MOV P0,25H ;点亮时十位数码管

CLR P26

ACALL DEL

SETB P26

DJNZ 30H,A1

DJNZ 31H,B1

;

INC R0

CJNE R0,#10,A2

INC R1

CJNE R1,#6,A3

INC R2

;

SETB P14 ;1分钟后关定时

CJNE R2,#0,A11;分个位定时

CJNE R3,#0,A11;分十位定时

CJNE R6,#19,A11;时位定时

CLR P14 ;开定时

;

A11:CJNE R2,#10,A44

INC R3

A12:CJNE R3,#6,A55

INC R6

CJNE R6,#24,A9

AJMP A8

A9:INC R4

CJNE R4,#10,A66

INC R5

CJNE R5,#3,A77

AJMP A8

A44:AJMP A4

A55:AJMP A5

A66:AJMP A6

A77:AJMP A7

;

DEL:MOV R7,#0AH ;延时子程序

AA:DJNZ R7,AA

RET

TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH

INTA: INC R2 ;中断0服务程序

CJNE R2, #10,B2

MOV R2,#0

INC R3

CJNE R3,#6,B2

MOV R3,#0

B2:RETI

INTB:INC R6 ;中断1服务程序

CJNE R6,#24,B4

MOV R6,#0

MOV R4,#0

MOV R5,#0

AJMP B3

B4:INC R4

CJNE R4, #10,B3

MOV R4,#0

INC R5

CJNE R5,#3,B3

MOV R5,#0

B3:RETI

END

TIMER0:

CLR TR0

PUSH ACC

MOV TH0,#3CH

MOV TL0,#0B0H

SETB TR0

INC 30H

MOV A,30H

CJNE A,#20,JIXU

MOV 30H,#0

INC MIAO

MOV A,MIAO

CJNE A,#60,JIXU

MOV MIAO,#0

INC FEN

MOV A,FEN

CJNE A,#60,JIXU

MOV FEN,#0

INC HOUR

MOV A,HOUR

CJNE A,#24,JIXU

MOV HOUR,#0

JIXU: POP ACC

RETI

时钟设计基本上就是通过电子 定时器定时 到1s给一个中断 让单片机去执行中断 跳转至相应的数码管位 然后修改当前显示值 再设置到10进位加一 之后就出来数字时钟的效果 弄懂定时器 一切就顺下来了

这是一个C得时钟程序 你看明白思想 就好说汇编的语句了

#include <reg52h>

#include <intrinsh>

#define uchar unsigned char

sbit dula=P3^7;

sbit L1=P2^0;

sbit L2=P2^1;

sbit L3=P2^2;

sbit key1=P3^0;

sbit key2=P3^1;

sbit key3=P3^2;

sbit key4=P3^3;

uchar aa;

uchar code table[]={0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71

};

uchar nummiao,numfen,numshi,t0;

void delayms(uchar xms)

{

uchar i,j;

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

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

}

void init()

{

TMOD=0x11;

TH0=(65536-50000)%256;

TL0=(65536-50000)/256;

EA=1;

ET0=1;

}

void display(uchar nummiao,numfen,numshi)

{

uchar shishi,geshi,shifen,gefen,shimiao,gemiao;

shimiao=nummiao/10;

gemiao=nummiao%10;

shifen=numfen/10;

gefen=numfen%10;

shishi=numshi/10;

geshi=numshi%10;

dula=1;

P0=table[shimiao];

dula=0;

L1=0;

L2=1;

L3=1;

delayms(5);

dula=1;

P0=table[gemiao];

dula=0;

L1=1;

L2=1;

L3=1;

delayms(5);

dula=1;

P0=0x40;

dula=0;

L1=1;

L2=0;

L3=1;

delayms(5);

dula=1;

P0=table[gefen];

dula=0;

L1=0;

L2=0;

L3=1;

delayms(5);

dula=1;

P0=table[shifen];

dula=0;

L1=1;

L2=1;

L3=0;

delayms(5);

dula=1;

P0=0x40;

dula=0;

L1=0;

L2=1;

L3=0;

delayms(5);

dula=1;

P0=table[geshi];

dula=0;

L1=1;

L2=0;

L3=0;

delayms(5);

dula=1;

P0=table[shishi];

dula=0;

L1=0;

L2=0;

L3=0;

delayms(5);

}

void keyscan()

{

if(key1==0)

{

delayms(10);

if(key1==0)

{

numshi++;

if(numshi==24)

numshi=0;

while(!key1);

}

}

if(key2==0)

{

delayms(10);

if(key2==0)

{

if(numfen==60)

numfen=0;

numfen++;

while(!key2);

}

}

if(key3==0)

{

delayms(10);

if(key3==0)

{

nummiao=0;

while(!key3);

}

}

if(key4==0)

{

delayms(10);

if(key4==0)

{

while(!key4);

TR0=~TR0;

}

}

}

void main()

{

init();

aa=0xfe;

while(1)

{

P1=aa;

if(nummiao==60)

{

numfen++;

nummiao=0;}

if(numfen==60)

{ numshi++;

numfen=0;}

if(numshi==24)

numshi=0;

keyscan();

display(nummiao,numfen,numshi);

}

}

void t0time()interrupt 1

{

TH0=(65535-50000)/256;

TL0=(65535-50000)%256;

t0++;

if(t0==20)

{

t0=0;

nummiao++;}

aa=_crol_(aa,1);

}

muteM EQU 10h ;静音键 闹铃开/关

timerT EQU 0Ch ;菜单键 进入/退出设置状态

leftL EQU 46h ;左移键

rightR EQU 47h ;右移键

upU EQU 19h ;增加键

downD EQU 1dh ;减少键

d_off EQU 16H ;显示键 LED数码管显示/关闭

recall EQU 44H ;日历键 DS1302初始化 *** 作

K_on BIT P30 ;闹铃输出

LED1 BIT P33

LED2 BIT P34

LED3CLK BIT P35 ;DS1302

LED4IO BIT P37

RST BIT P31

SECOND EQU 60H

;60H 秒

;61h 分

;62h 时

;63h 日

;64h 月 ;65h DAY

;66h 年

;6Ah 闹分 from 00(1302)

;6BH 闹时 from 01(1302)

;

ORG 0000H

AJMP START

ORG 0003H

LJMP S_INT ;IRF

ORG 000BH ;200Us

LJMP P_INT ;

ORG 001BH ;display LED

LJMP DISPLAY

; ;main program

ORG 0030H

START: CLR RST

MOV SP,#2AH

SETB 05H

CLR 06H

SETB 07H;CLR 07H

CLR 08H

CLR 09H

CLR 0AH

CLR 0BH

CLR 0CH

SETB 0DH

CLR 0EH

CLR 0FH

CLR 10H

CLR 11H

MOV R2,#00H ;

MOV R3,#00H ;

MOV TMOD,#12H

MOV TL1,#0e5H ;wait

MOV TH1,#0BeH

MOV TH0,#3FH ;200uS 3f

MOV TL0,#3FH

SETB ET0

SETB ET1

setb pt0

SETB TR0

SETB TR1

SETB IT0 ;

SETB EX0 ;

CLR PX0 ;LCALL SET1302 ;初始化

MOV R1,#0C1H ;取定时参数从1302中

acall T_6061

MOV 6AH,A ;M

MOV R1,#0C3H

ACALL T_6061

MOV 6BH,A ;H

MOV 61H,#0

MOV 62H,#0

SETB EA

sjmp $

;

DISPLAY: PUSH ACC

PUSH PSW

MOV TL1,#0e0H ;wait how long to display (20ms)

MOV TH1,#0b0H

MOV dptr,#tab1

JB 0EH,DIS2

JB 0FH,DIS3

JB 10H,DIS4

JB 11H,DIS5

JNB 0DH,D_OUT

JNB 08H,D_GO ;定时到时,显示闪烁

JNB 07H,D_OUT

D_G MOV DPTR,#TAB1

MOV A,62H

ANL A,#0FH

MOV B,A

MOV A,62H

SWAP A

ANL A,#07H

MOVC A,@A+DPTR

MOV P1,A

CLR LED1

LCALL DL2M

SETB LED1

MOV A,B

MOVC A,@A+DPTR

MOV C,07H

MOV acc7,C ;秒灯闪烁

MOV P1,A

CLR LED2

LCALL DL2M

SETB LED2

MOV dptr,#tab2 ;倒装LED字段表

MOV A,61H

ANL A,#0FH

MOV B,A

MOV A,61H

SWAP A

ANL A,#0FH

MOVC A,@A+DPTR

MOV C,07H

MOV acc6,C ;秒灯闪烁

MOV P1,A

CLR LED3CLK

LCALL DL2M

SETB LED3CLK

MOV dptr,#tab1

MOV A,B

MOVC A,@A+DPTR

MOV C,06H

cpl c

MOV acc7,C ;闹铃指示灯

MOV P1,A

CLR LED4IO

LCALL DL2M

SETB LED4IO

D_OUT: SETB TR1

POP PSW

POP ACC

RETI

;

DIS2: AJMP DIS_2

DIS3: AJMP DIS_3

DIS4: AJMP DIS_4

DIS5: AJMP DIS_5

;

DIS_2: MOV dptr,#tab1 ;显示设置小时

MOV 6FH,62H

ACALL BCD_HEX

MOV B,#10

DIV AB

MOVC A,@A+DPTR

MOV P1,A

CLR LED1

LCALL DL2M

SETB LED1

MOV A,B

MOVC A,@A+DPTR

MOV P1,A

CLR LED2

LCALL DL2M

SETB LED2

SETB TR1

POP PSW

POP ACC

RETI

;

DIS_3: MOV DPTR,#TAB2 ;显示设置分

MOV 6FH,61H

ACALL BCD_HEX

MOV B,#10

DIV AB

MOVC A,@A+DPTR

MOV P1,A

CLR LED3CLK

LCALL DL2M

SETB LED3CLK

MOV A,B

MOV DPTR,#TAB1

MOVC A,@A+DPTR

MOV P1,A

CLR LED4IO

LCALL DL2M

SETB LED4IO

SETB TR1

POP PSW

POP ACC

RETI

;

DIS_4: MOV dptr,#tab1 ;显示设置闹时

JNB 07H,D4_OUT ;显示时闪烁

MOV A,6BH

MOV B,#0AH

DIV AB

MOVC A,@A+DPTR

MOV P1,A

CLR LED1

LCALL DL2M

SETB LED1

MOV A,B

MOVC A,@A+DPTR

MOV P1,A

CLR LED2

LCALL DL2M

SETB LED2

D4_OUT: SETB TR1

POP PSW

POP ACC

RETI

;

DIS_5: MOV DPTR,#TAB2

JNB 07H,D5_OUT ;显示时闪烁

MOV A,6AH ;显示设置闹分

MOV B,#0AH

DIV AB

MOVC A,@A+DPTR

MOV P1,A

CLR LED3CLK

LCALL DL2M

SETB LED3CLK

MOV DPTR,#TAB1

MOV A,B

MOVC A,@A+DPTR

MOV P1,A

CLR LED4IO

LCALL DL2M

SETB LED4IO

D5_OUT: SETB TR1

POP PSW

POP ACC

RETI

;

DL2M: MOV 43H,#14H ; every LED(2ms)

DL2: MOV 44H,#14H

DL1: NOP

NOP

DJNZ 44H,DL1

DJNZ 43H,DL2

RET

;定时读取1302时间及判断闹铃时间是否到

P_INT: PUSH ACC

PUSH PSW

INC R2

CJNE R2,#250D,P_OUT

MOV R2,#00H

INC R3

CJNE R3,#10D,P_OUT

MOV R3,#00H

CPL 07H

MOV P1,#0FFH

ACALL R_1302

OUT: JNB 06H,P_OUT

MOV A,6BH

MOV B,#10

DIV AB

SWAP A

ADD A,B

CJNE A,62H,PP_OUT

MOV A,6AH

MOV B,#10

DIV AB

SWAP A

ADD A,B

CJNE A,61H,PP_OUT

SETB 08H ;定时到标志

MOV C,07H

cpl c

MOV K_ON,C

P_OUT: POP PSW

POP ACC

RETI

PP_OUT: SETB K_ON

CLR 08H

POP PSW

POP ACC

RETI

;有接收到遥控器信号

S_INT:CLR EA

PUSH ACC

PUSH PSW

PUSH DPH

PUSH DPL

PUSH 02H

PUSH 03H

MOV R6,#10D ;

SB: ACALL YS1

JB P32,EXIT

DJNZ R6, SB

JNB P32, $ ;

ACALL YS2 ;

JB P32,EXIT

MOV R1,#1AH ;

MOV R2,#4D

PP: MOV R3,#8D

JJJJ: JNB P32,$

ACALL YS1

MOV C,P32

JNC UUU

JB P32,$

UUU: MOV A,@R1

RRC A

MOV @R1,A

DJNZ R3,JJJJ

INC R1

DJNZ R2,PP

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

MOV A,1AH ;

XRL A,#40h ;判断1AH的值是否等于遥控器低8位地址(40h)

JNZ EXIT ;

MOV A,1bH

XRL A,#0bfh ;再判断高8位地址是否正确(0bfh)

JNZ EXIT

MOV A,1CH

CPL A

XRL A,1DH ;将1CH的值取反后和1DH比较 不同则无效丢弃(核对数据是否准确)

JNZ EXIT

ACALL DO ;相应按键的处理

EXIT: SETB EA

POP 03H

POP 02H

POP DPL

POP DPH

POP PSW

POP ACC

RETI

;--------------------delay-----------------------

YS1: MOV 70H,#16D ;延时1

D1: MOV 71H,#21D

DJNZ 71H,$

DJNZ 70H,D1

RET

YS2: MOV 70H,#09D ;延时2

D2: MOV 71H,#220D

DJNZ 71H,$

DJNZ 70H,D2

RET

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

TAB: DB 00H,01H,02H,03H,04H,05H,06H,07H,08H,09H ;TAB1 LED数码管显示表 TAB遥控器键值表(未用)

;TAB1: DB 3FH,11H,5EH,5BH,71H,6BH,6FH,19H,7FH,7bH,77H,7CH,39H,5EH,79H,71H

tab1: DB 0C0H,0F9H,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h,88h,83h,0a7h,0a1h,86h,8EH

TAB2: DB 0c0H,0f9H,64H,70H,59H,52H,42H ;倒装LED段码表

;0CH 为设置标志,0DH为全显示标志,0EH为显示设置小时标志,0FH为显示设置分标志

;10H 为显示设置闹时标志,11H为显示设置闹分标志

;增加闹时静音功能

;mute-10h,timer-0eh,left-46h,right-47h,up-19h,down-1dh

D MOV A,1CH

CJNE A,#TIMERT,REDO ;代码不是设置/退出键

JNB 0CH,SET1 ;是,则进入

CLR 0CH ;是,已经进入,则退出

SETB 0DH ;恢复正常显示

CLR 0EH

CLR 0FH

CLR 10H

CLR 11H

RET

SET1: SETB 0CH

SETB 0EH

CLR 0DH

CLR 0FH

CLR 10H

CLR 11H

RET

RED CJNE A,#MUTEM,REDO1 ;不是设置键的处理REDO1,2,3,4

LJMP MUTE ;MUTE

REDO1: CJNE A,#D_OFF,DO_SET2

LJMP DIS_OFF ;关闭显示

DO_SET2:JB 0CH,SET2 ;时间设置的处理

RET

SET2: CJNE A,#UPU,SET2A

LJMP INC1 ;+加(^)

SET2A: CJNE A,#DOWND,SET2B

LJMP DEC2 ;- 减

SET2B: CJNE A,#RIGHTR,SET2C

LJMP RIGHT ;RIGHT右移(>)

SET2C: CJNE A,#LEFTL,SET2D LJMP LEFT ;LEFT左移(<)

SET2D: CJNE A,#RECALL,SET2EXT ;DS1302初始化

LJMP SET1302

SET2EXT:RET

;--------------------------------INC------------------------

INC1: JB 0EH,INCH

JB 0FH,INCM

JB 10H,INC_H

JB 11H,INC_M

RET

INC_H: INC 6BH ;闹钟小时增加

MOV A,6BH

CJNE A,#24D,INCH3

MOV 6BH,#0

INCH3: MOV R1,#0C2H

MOV R0,6BH

ACALL SETONE ;写入DS1302

RET

INC_M: INC 6AH ;闹钟分增加

MOV A,6AH

CJNE A,#60D,INCH4

MOV 6AH,#0

INCH4: MOV R1,#0C0H

MOV R0,6AH

ACALL SETONE ;

RET

INCH: ;INC 62H ;

MOV 6FH,62H

ACALL BCD_HEX

INC A

CJNE A,#24D,INCH1

MOV A,#0

INCH1: MOV 6FH,A

ACALL HEX_BCD

MOV 62H,A

MOV R1,#84H

MOV R0,62H

ACALL SETONE ;

RET

INCM: ;INC 61H ;

MOV 6FH,61H

ACALL BCD_HEX

INC A

CJNE A,#60D,INCH2

MOV A,#0

INCH2: MOV 6FH,A

ACALL HEX_BCD

MOV 61H,A

MOV R1,#82H

MOV R0,61H

ACALL SETONE ;

RET

;----------------------------------DEC----------------------

DEC2: JB 0EH,DECH

JB 0FH,DECM

JB 10H,DEC_H

JB 11H,DEC_M

RET

DECH: MOV 6FH,62H

ACALL BCD_HEX

DEC A

CJNE A,#0FFH,DECH1

MOV A,#23

DECH1: MOV 6FH,A

ACALL HEX_BCD

MOV 62H,A

MOV R1,#84H

MOV R0,62H

ACALL SETONE

RET

DECM: MOV 6FH,61H

ACALL BCD_HEX

DEC A

CJNE A,#0FFH,DECM1

MOV A,#59

DECM1: MOV 6FH,A

ACALL HEX_BCD

MOV 61H,A

MOV R1,#82H

MOV R0,61H

ACALL SETONE

RET

DEC_H: DEC 6BH

MOV A,6BH

CJNE A,#0FFH,DECH3

MOV 6BH,#23D

DECH3: MOV R1,#0C2H

MOV R0,6BH

ACALL SETONE

RET

DEC_M: DEC 6AH

MOV A,6AH

CJNE A,#0FFH,DECH4

MOV 6AH,#59D

DECH4: MOV R1,#0C0H

MOV R0,6AH

ACALL SETONE

RET

;--------------------------------RIGHT----------------------

RIGHT: JB 0EH,RIGHT1

JB 0FH,RIGHT2

JB 10H,RIGHT3

JB 11H,RIGHT4

RET ;右移

RIGHT1: CLR 0EH

SETB 0FH

RET

RIGHT2: CLR 0FH

SETB 10H

RET

RIGHT3: CLR 10H

SETB 11H

RET

RIGHT4: CLR 11H

SETB 0EH

RET

;--------------------------------LEFT-----------------------

LEFT: JB 0EH,LEFT1

JB 0FH,LEFT2

JB 10H,LEFT3

JB 11H,LEFT4

RET ;左移

LEFT1: SETB 11H

CLR 0EH

RET

LEFT2: SETB 0EH

CLR 0FH

RET

LEFT3: SETB 0FH

CLR 10H

RET

LEFT4: SETB 10H

CLR 11H

RET

;------------------------------MUTE--------------

MUTE: setb k_ON

CPL 06H ;静音

CLR 08H

RET

;-----------------------------DISPLAY OFF--------

DIS_OFF:CLR ET1

CPL 05H

JNB 05H,REDORE

SETB ET1

REDORE: RET

;------------------------------------初始化1302

SET1302: CLR RST ;2002年1月1日12:00:00

CLR LED3CLK

MOV SECOND,#0

MOV 61H,#0

MOV 62H,#18 ;

MOV 63H,#1

MOV 64H,#1

MOV 65H,#1

MOV 66H,#2

SETB RST

MOV A,#8EH

LCALL R_BIT

MOV A,#00H

LCALL R_BIT

SETB LED3CLK

CLR RST

MOV R0,#SECOND

MOV R7,#7

MOV R1,#80H

SET1302A:CLR RST

CLR LED3CLK

SETB RST

MOV A,R1

LCALL R_BIT

MOV A,@R0

LCALL R_BIT

INC R0

INC R1

INC R1

SETB LED3CLK

CLR RST

DJNZ R7,SET1302A

CLR RST

CLR LED3CLK

sETB LED3CLK

nop

CLR RST

nop

clr led3clk

SETB RST

MOV A,#90H

LCALL R_BIT

MOV A,#10100101B ;充电器设置

LCALL R_BIT

SETB LED3CLK

CLR RST

CLR LED3CLK

SETB RST

MOV A,#8EH

LCALL R_BIT

MOV A,#80H

LCALL R_BIT

SETB LED3CLK

CLR RST

RET

;----------------------读取一RAM ------

T_6061: CLR RST

CLR LED3CLK

SETB RST

MOV A,R1

LCALL R_BIT

LCALL W_BIT

SETB LED3CLK

CLR RST

RET

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

R_1302: MOV R0,#SECOND

MOV R7,#7

MOV R1,#81H

R_1302A: CLR RST

CLR LED3CLK

SETB RST

MOV A,R1

LCALL R_BIT

LCALL W_BIT

MOV @R0,A

INC R0

INC R1

INC R1

SETB LED3CLK

CLR RST

DJNZ R7,R_1302A

RET

;------------------R_BIT------------------

R_BIT: MOV R4,#8

R_BIT1: RRC A

MOV LED4IO,C

SETB LED3CLK

CLR LED3CLK

DJNZ R4,R_BIT1

RET

;-------------------W_BIT-----------------------

W_BIT: MOV R4,#8

W_BIT1: MOV C,LED4IO

RRC A

SETB LED3CLK

CLR LED3CLK

DJNZ R4,W_BIT1

RET

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

BCD_HEX:

MOV A,6FH

ANL A,#0FH

MOV B,A

MOV A,6FH

MOV 6FH,B

SWAP A

ANL A,#0FH

MOV B,#0AH

MUL AB

ADD A,6FH

;MOV 6FH,A

RET

HEX_BCD:

MOV A,6FH

MOV B,#10

DIV AB

SWAP A

ADD A,B

;MOV 6FH,A

RET

;-----写一地址---R1 为地址,R0 为数据----------

SETONE: CLR LED3CLK

CLR RST

CLR LED3CLK

NOP

SETB RST

MOV A,#8EH

LCALL R_BIT

MOV A,#00H

LCALL R_BIT

SETB LED3CLK

CLR RST

CLR LED3CLK

NOP

CLR RST

CLR LED3CLK

SETB RST

MOV A,R1

LCALL R_BIT

MOV A,R0

LCALL R_BIT

NOP

SETB LED3CLK

CLR RST

NOP

NOP

CLR RST

CLR LED3CLK

SETB RST

MOV A,#8EH

LCALL R_BIT

MOV A,#80H

LCALL R_BIT

SETB LED3CLK

CLR RST

RET

ms50 DATA 31H ;50ms计数内存地址sec DATA 32H ;秒计数内存地址min DATA 33H ;分计数内存地址hour DATA 34H ;时计数内存地址buffer DATA 35H ;显示十进制内存起始地址EXTRN CODE(Display8) ;外部显示子程序(跟硬件设计有关,原文未列出) ORG 0000H ; LJMP STAR ;转主程序 ORG 000BH ; LJMP INT_Timer0 ;转50ms定时器中断处理程序ORG 0100H ;STAR: MOV SP,#60H ;主程序 MOV ms50,A ;50ms计数器初始化到0 MOV hour,#12 ;小时初始化为12 MOV min,#59 ;分钟初始化为59 MOV sec,#50 ;秒初始化为50 MOV TH0,#60 ;初始化定时器T0为50ms的数据(跟时钟频率和定时器模式有关) MOV TL0,#176 ; MOV TMOD,#1 ;初始化定时器模式 MOV IE,#82H ;设定中断 SETB TR0 ;开定时器0STAR1: LCALL Display ;调用显示转换程序(先将16进制转为BCD码再显示) JNB F0,$ ;等待中断处理完成标志 CLR F0 ;复位中断处理完成标志

SJMP STAR1 ;循环显示;中断服务程序 INT_Timer0:

MOV TL0,#176-5 ;50ms定时器计数器初始值再装入(-5为微调,含响应中断用时) MOV TH0,#60 ; PUSH 01H ;压入堆栈 MOV R1,#ms50 ;装入50ms计数内存地址数31H INC @R1 ;50ms计数内存加1

CJNE @R1,#20,ExitInt ;不够1秒,退出 MOV @R1,#0 ;50ms计数内存复位为0(31H)

INC R1 ;转为秒内存地址(32H)

INC @R1 ;秒计数内存加1 CJNE @R1,#60,ExitInt1 ;不够60秒,退出 MOV @R1,#0 ;够60秒,秒计数复位为0 INC R1 ;转为分计数内存地址(33H)

INC @R1 ;分计数内存加1 CJNE @R1,#60,ExitInt1 ;不够60分,退出 MOV @R1,#0 ;够60分,分复位为0 INC R1 ;转为时内存地址(34H) INC @R1 ;时计数内存加1 CJNE @R1,#24,ExitInt1 ;不够24时,退出 MOV @R1,#0 ;时计数内存复位为0ExitInt1:

SETB F0 ;置位中断处理完成标志ExitInt:

POP 01H ; 恢复现场 RETI ;退出中断

HexToBCD: ;16进制转BCD码

MOV B,#10 ; DIV AB ; MOV @R0,B ;存余数(10进制个位) INC R0 ;转伤地址 MOV @R0,A ;存伤(10进制十位) INC R0 ;转下一次余数地址 RET ;

Display: ;显示转换与调用显示程序

MOV R0,#buffer ;10进制BCD秒显示缓存地址(35H) MOV A,sec ; ACALL HexToBCD ;十进制秒转换后存在(35H)、(36H) MOV @R0,#10H ;(37H)=#10H,秒与分之间的间隔,无实际意义,或与dispaly8有关

INC R0 ;10进制BCD分显示缓存地址(38H)

MOV A,min ; ACALL HexToBCD ;十进制分转换后存在(38H)、(39H)

MOV @R0,#10H ;(3AH)=#10H,分与时之间的间隔,无实际意义,或与dispaly8有关

INC R0 ;10进制BCD时显示缓存地址(3BH)

MOV A,hour ; ACALL HexToBCD ;十进制时转换后存在(3CH)、(3DH)

MOV R0,#buffer ;恢复显示缓存地址(35H),为dispaly8置初始显示地址 LCALL Display8 ;调用实际显示程序 RET ; END

形式的程序,不便于看,以及修改。

程序太长,也可以放在你的百度空间,大家去看。

---------

程序,重新写了,放在:

>

仿真运行截图:

以上就是关于汇编语言 秒表程序设计全部的内容,包括:汇编语言 秒表程序设计、单片机时钟程序、51单片机时钟汇编程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存