
assume cs:codesg,ds:data
data segment
db "00/00/00 00:00:00",'$'
data ends
codesg segment
start:
mov ax,data
mov ds,ax
mov cx,6
mov bx,0
mov ah,0
mov al,9
s:
push cx
push ax
out 70h,al
in al,71h
mov ah,al
mov cl,4
shr ah,cl
and al,00001111b
add ah,30h
add al,30h
mov byte ptr ds:[bx],ah
mov byte ptr ds:[bx+1],al
pop ax
cmp al,4
jna s1
jmp short s2
s1:
dec al
s2:
cmp al,7
jne ok
sub al,2
ok:
dec al
add bx,3
pop cx
loop s
mov dx,0
mov ah,9
int 21h
mov ax,4c00h
int 21h
codesg ends
end start
CD BIT P12;用于液晶
W BIT P36
R BIT P37
CE BIT P17
DATA1 EQU 43H;第一参数
DATA2 EQU 44H;第二参数
COM EQU 45H;命令寄存器
;
ORG 0000H
jmp MAIN
ORG 0100H
;
MAIN:
;;;;;;;;;;;;;;;;;;;液晶初始化;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV COM,#80H ;SET or 模式命令
LCALL WRITEDATA3
NOP
MOV DATA1,#00H ;SET TEXT HOME AREA ADDRESS 1000H
MOV DATA2,#10H
MOV COM,#40H
LCALL WRITEDATA
NOP
MOV DATA1,#1EH ;SET TEXT AREA ADDRESS 001EH
MOV DATA2,#00H
MOV COM,#41H
LCALL WRITEDATA
NOP
MOV DATA1,#00H ;SET GRAPHIC HOME AREA ADDRESS 2000H
MOV DATA2,#20H
MOV COM,#42H
LCALL WRITEDATA
NOP
MOV DATA1,#1EH ;SET GRAPHIC AREA ADDRESS 001EH
MOV DATA2,00H
MOV COM,#43H
LCALL WRITEDATA
NOP
MOV DATA1,#0FH ;SET OFFSET REGISTER 000FH
MOV DATA2,#00H
MOV COM,#22H
LCALL WRITEDATA
NOP
MOV DATA1,#00H ;SET ADDRESS POINTER 7C00H
MOV DATA2,#7CH
MOV COM,#24H
LCALL WRITEDATA
NOP
MOV COM,#9CH ;SET TEXT ON,GRAPHIC ON
LCALL WRITEDATA3
NOP
;
这个电子钟程序已经基本符合你的要求。希望能对你有用。
程序说明:
显示的时间格式为:12-00-00,既,时-分-秒
按键说明:P32为时调节。P33为分调节。P34为秒调节。这三个按键均是每按一次加一。
晶振说明:12MHZ
数码管说明:共阳数码管。共8个数码管。共用了两个4连共阳数码管。
其中,P0口为数码管的段选,P2口为数码管的位选。
本程序已通过实践验证!!!
汇编源程序如下:
SECOND EQU 30H
MINITE EQU 31H
HOUR EQU 32H
HOURK BIT P32
MINITEK BIT P33
SECONDK BIT P34
DISPBUF EQU 40H
DISPBIT EQU 48H
T2SCNTA EQU 49H
T2SCNTB EQU 4AH
TEMP EQU 4BH
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0
START:MOV SECOND,#00H
MOV MINITE,#00H
MOV HOUR,#12
MOV DISPBIT,#00H
MOV T2SCNTA,#00H
MOV T2SCNTB,#00H
MOV TEMP,#0FEH
LCALL DISP
MOV TMOD,#01H
MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
SETB TR0
SETB ET0
SETB EA
WT:JB SECONDK,NK1
LCALL DELY10MS
JB SECONDK,NK1
INC SECOND
MOV A,SECOND
CJNE A,#60,NS60
MOV SECOND,#00H
NS60:LCALL DISP
JNB SECONDK,$
NK1:JB MINITEK,NK2
LCALL DELY10MS
JB MINITEK,NK2
INC MINITE
MOV A,MINITE
CJNE A,#60,NM60
MOV MINITE,#00H
NM60:LCALL DISP
JNB MINITEK,$
NK2:JB HOURK,NK3
LCALL DELY10MS
JB HOURK,NK3
INC HOUR
MOV A,HOUR
CJNE A,#24,NH24
MOV HOUR,#00H
NH24:LCALL DISP
JNB HOURK,$
NK3:LJMP WT
DELY10MS:MOV R6,#10
D1:MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
DISP:MOV A,#DISPBUF
ADD A,#8
DEC A
MOV R1,A
MOV A,HOUR
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV @R1,A
DEC R1
MOV A,MINITE
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV@R1,A
DEC R1
MOV A,SECOND
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
RET
INT_T0:MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
MOV A,#DISPBUF
ADD A,DISPBIT
MOV R0,A
MOV A,@R0
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,DISPBIT
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P2,A
INC DISPBIT
MOV A,DISPBIT
CJNE A,#08H,KNA
MOV DISPBIT,#00H
KNA:INC T2SCNTA
MOV A,T2SCNTA
CJNE A,#100,DONE
MOV T2SCNTA,#00H
INC T2SCNTB
MOV A,T2SCNTB
CJNE A,#05H,DONE
MOV T2SCNTB,#00H
INC SECOND
MOV A,SECOND
CJNE A,#60,NEXT
MOV SECOND,#00H
INC MINITE
MOV A,MINITE
CJNE A,#60,NEXT
MOV MINITE,#00H
INC HOUR
MOV A,HOUR
CJNE A,#24,NEXT
MOV HOUR,#00H
NEXT:LCALL DISP
DONE:RETI
TABLE:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0BFH
TAB:DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FH
END
/电子时钟源代码/
#include<graphicsh>
#include<stdioh>
#include<mathh>
#include<dosh>
#define PI 31415926 /定义常量/
#define UP 0x4800 /上移↑键:修改时间/
#define DOWN 0x5000 /下移↓键:修改时间/
#define ESC 0x11b /ESC键 : 退出系统/
#define TAB 0xf09 /TAB键 : 移动光标/
/函数声明/
int keyhandle(int,int); /键盘按键判断,并调用相关函数处理/
int timeupchange(int); /处理上移按键/
int timedownchange(int); /处理下移按键/
int digithour(double); /将double型的小时数转换成int型/
int digitmin(double); /将double型的分钟数转换成int型/
int digitsec(double); /将double型的秒钟数转换成int型/
void digitclock(int,int,int ); /在指定位置显示时钟或分钟或秒钟数/
void drawcursor(int); /绘制一个光标/
void clearcursor(int);/消除前一个光标/
void clockhandle(); /时钟处理/
double h,m,s; /全局变量:小时,分,秒/
double x,x1,x2,y,y1,y2; /全局变量:坐标值/
struct time t[1];/定义一个time结构类型的数组/
main()
{
int driver, mode=0,i,j;
driver=DETECT; /自动检测显示设备/
initgraph(&driver, &mode, "");/初始化图形系统/
setlinestyle(0,0,3); /设置当前画线宽度和类型:设置三点宽实线/
setbkcolor(0);/用调色板设置当前背景颜色/
setcolor(9); /设置当前画线颜色/
line(82,430,558,430);
line(70,62,70,418);
line(82,50,558,50);
line(570,62,570,418);
line(70,62,570,62);
line(76,56,297,56);
line(340,56,564,56); /画主体框架的边直线/
/arc(int x, int y, int stangle, int endangle, int radius)/
arc(82,62,90,180,12);
arc(558,62,0,90,12);
setlinestyle(0,0,3);
arc(82,418,180,279,12);
setlinestyle(0,0,3);
arc(558,418,270,360,12); /画主体框架的边角弧线/
setcolor(15);
outtextxy(300,53,"CLOCK"); /显示标题/
setcolor(7);
rectangle(342,72,560,360); /画一个矩形,作为时钟的框架/
setwritemode(0); /规定画线的方式。mode=0, 则表示画线时将所画位置的原来信息覆盖/
setcolor(15);
outtextxy(433,75,"CLOCK");/时钟的标题/
setcolor(7);
line(392,310,510,310);
line(392,330,510,330);
arc(392,320,90,270,10);
arc(510,320,270,90,10); /绘制电子动画时钟下的数字时钟的边框架/
/绘制数字时钟的时分秒的分隔符/
setcolor(5);
for(i=431;i<=470;i+=39)
for(j=317;j<=324;j+=7){
setlinestyle(0,0,3);
circle(i,j,1); /以(i, y)为圆心,1为半径画圆/
}
setcolor(15);
line(424,315,424,325); /在运行电子时钟前先画一个光标/
/绘制表示小时的圆点/
for(i=0,m=0,h=0;i<=11;i++,h++){
x=100sin((h60+m)/360PI)+451;
y=200-100cos((h60+m)/360PI);
setlinestyle(0,0,3);
circle(x,y,1);
}
/绘制表示分钟或秒钟的圆点/
for(i=0,m=0;i<=59;m++,i++){
x=100sin(m/30PI)+451;
y=200-100cos(m/30PI);
setlinestyle(0,0,1);
circle(x,y,1);
}
/在电子表的左边打印帮助提示信息/
setcolor(4);
outtextxy(184,125,"HELP");
setcolor(15);
outtextxy(182,125,"HELP");
setcolor(5);
outtextxy(140,185,"TAB : Cursor move");
outtextxy(140,225,"UP : Time ++");
outtextxy(140,265,"DOWN: Time --");
outtextxy(140,305,"ESC : Quit system!");
outtextxy(140,345,"Version : 20");
setcolor(12);
outtextxy(150,400,"Nothing is more important than time!");
clockhandle();/开始调用时钟处理程序/
closegraph(); /关闭图形系统/
return 0; /表示程序正常结束,向 *** 作系统返回一个0值/
}
void clockhandle()
{
int k=0,count;
setcolor(15);
gettime(t);/取得系统时间,保存在time结构类型的数组变量中/
h=t[0]ti_hour;
m=t[0]ti_min;
x=50sin((h60+m)/360PI)+451; /时针的x坐标值/
y=200-50cos((h60+m)/360PI); /时针的y坐标值/
line(451,200,x,y);/在电子表中绘制时针/
x1=80sin(m/30PI)+451; /分针的x坐标值/
y1=200-80cos(m/30PI); /分针的y坐标值/
line(451,200,x1,y1); /在电子表中绘制分针/
digitclock(408,318,digithour(h)); /在数字时钟中,显示当前的小时值/
digitclock(446,318,digitmin(m)); /在数字时钟中,显示当前的分钟值/
setwritemode(1);
/规定画线的方式,如果mode=1,则表示画线时用现在特性的线
与所画之处原有的线进行异或(XOR) *** 作,实际上画出的线是原有线与现在规定
的线进行异或后的结果。因此, 当线的特性不变, 进行两次画线 *** 作相当于没有
画线,即在当前位置处清除了原来的画线/
for(count=2;k!=ESC;){ /开始循环,直至用户按下ESC键结束循环/
setcolor(12);/淡红色/
sound(500);/以指定频率打开PC扬声器,这里频率为500Hz/
delay(700);/发一个频率为500Hz的音调,维持700毫秒/
sound(200);/以指定频率打开PC扬声器,这里频率为200Hz/
delay(300);
/以上两种不同频率的音调,可仿真钟表转动时的嘀哒声/
nosound(); /关闭PC扬声器/
s=t[0]ti_sec;
m=t[0]ti_min;
h=t[0]ti_hour;
x2=98sin(s/30PI)+451; /秒针的x坐标值/
y2=200-98cos(s/30PI); /秒针的y坐标值/
line(451,200,x2,y2);
/绘制秒针/
/利用此循环,延时一秒/
while(t[0]ti_sec==s&&t[0]ti_min==m&&t[0]ti_hour==h)
{ gettime(t);/取得系统时间/
if(bioskey(1)!=0){
k=bioskey(0);
count=keyhandle(k,count);
if(count==5) count=1;
}
}
setcolor(15);
digitclock(485,318,digitsec(s)+1);/数字时钟增加1秒/
setcolor(12); /淡红色/
x2=98sin(s/30PI)+451;
y2=200-98cos(s/30PI);
line(451,200,x2,y2);
/用原来的颜色在原来位置处再绘制秒针,以达到清除当前秒针的目的/
/分钟处理/
if(t[0]ti_min!=m){ /若分钟有变化/
/消除当前分针/
setcolor(15); /白色/
x1=80sin(m/30PI)+451;
y1=200-80cos(m/30PI);
line(451,200,x1,y1);
/绘制新的分针/
m=t[0]ti_min;
digitclock(446,318,digitmin(m)); /在数字时钟中显示新的分钟值/
x1=80sin(m/30PI)+451;
y1=200-80cos(m/30PI);
line(451,200,x1,y1);
}
/小时处理/
if((t[0]ti_hour60+t[0]ti_min)!=(h60+m)){ /若小时数有变化/
/消除当前时针/
setcolor(15); /白色/
x=50sin((h60+m)/360PI)+451;/50:时钟的长度(单位:像素),451:圆心的x坐标值/
y=200-50cos((h60+m)/360PI);
line(451,200,x,y);
/绘制新的时针/
h=t[0]ti_hour;
digitclock(408,318,digithour(h));
x=50sin((h60+m)/360PI)+451;
y=200-50cos((h60+m)/360PI);
line(451,200,x,y);
}
}
}
int keyhandle(int key,int count) /键盘控制 /
{ switch(key)
{case UP: timeupchange(count-1); /因为count的初始值为2,所以此处减1/
break;
case DOWN:timedownchange(count-1); /因为count的初始值为2,所以此处减1/
break;
case TAB:setcolor(15);
clearcursor(count); /清除原来的光标/
drawcursor(count); /显示一个新的光标/
count++;
break;
}
return count;
}
int timeupchange(int count) /处理光标上移的按键/
{
if(count==1){
t[0]ti_hour++;
if(t[0]ti_hour==24) t[0]ti_hour=0;
settime(t); /设置新的系统时间/
}
if(count==2){
t[0]ti_min++;
if(t[0]ti_min==60) t[0]ti_min=0;
settime(t); /设置新的系统时间/
}
if(count==3){
t[0]ti_sec++;
if(t[0]ti_sec==60) t[0]ti_sec=0;
settime(t); /设置新的系统时间/
}
}
int timedownchange(int count) /处理光标下移的按键/
{
if(count==1) {
t[0]ti_hour--;
if(t[0]ti_hour==0) t[0]ti_hour=23;
settime(t);/设置新的系统时间/
}
if(count==2) {
t[0]ti_min--;
if(t[0]ti_min==0) t[0]ti_min=59;
settime(t);/设置新的系统时间/
}
if(count==3) {
t[0]ti_sec--;
if(t[0]ti_sec==0) t[0]ti_sec=59;
settime(t);/设置新的系统时间/
}
}
int digithour(double h)/将double型的小时数转换成int型/
{int i;
for(i=0;i<=23;i++)
{if(h==i) return i;}
}
int digitmin(double m)/将double型的分钟数转换成int型/
{int i;
for(i=0;i<=59;i++)
{if(m==i) return i;}
}
int digitsec(double s) /将double型的秒钟数转换成int型/
{int i;
for(i=0;i<=59;i++)
{if(s==i) return i;}
}
void digitclock(int x,int y,int clock)/在指定位置显示数字时钟:时\分\秒/
{char buffer1[10];
setfillstyle(0,2);
bar(x,y,x+15,328);
if(clock==60) clock=0;
sprintf(buffer1,"%d",clock);
outtextxy(x,y,buffer1);
}
void drawcursor(int count) /根据count的值,画一个光标/
{switch(count)
{
case 1:line(424,315,424,325);break;
case 2:line(465,315,465,325);break;
case 3:line(505,315,505,325);break;
}
}
void clearcursor(int count) /根据count的值,清除前一个光标/
{switch(count)
{
case 2:line(424,315,424,325);break;
case 3:line(465,315,465,325);break;
case 1:line(505,315,505,325);break;
}
}
以上就是关于如何用微机汇编语言编写时钟程序全部的内容,包括:如何用微机汇编语言编写时钟程序、电子日历时钟程序设计(汇编语言)、电子时钟程序(单片机汇编语言编写,不要C语言)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)