1. 51单片机做数字电子钟
这么复杂的东西给这么少分 晕死了 你也太小气了吧,分多的话还可能帮你动动脑
2. 用汇编语言编写一个数字电子钟程序代码
data segment
;*****定义please等提示信息*****
str db 20
db 50h,7,0,0
db 6ch,7,0,1
db 65h,7,0,1
db 61h,7,0,1
db 73h,7,0,1
db 65h, 7,0,1
db 70h,7,1,-10
db 72h,7,0,1
db 65h,7,0,1
db 73h,7,0,1
db 73h,7,0,1
db 53h,7,0,2
db 6bh,7,0,2
db 65h,7,0,1
db 79h,7,0,1
db 65h,7,0,2
db 78h,7,0,1
db 69h,7,0,1
db 74h,7,0,1
db 21h,7,0,1
;*****定义0-9十个图形数字*****
s0 db 6
db 5fh,7,0,0
db 7ch,7,1,-1
db 7ch,7,1,0
db 5fh,7,0,1
db 7ch,7,0,1
db 7ch,7,-1,0
sy db 2
db 7ch,7,1,0
db 7ch,7,1,0
s2 db 5
db 5fh,7,0,0
db 7ch,7,1,1
db 5fh,7,0,-1
db 7ch,7,1,-1
db 5fh,7,0,1
s3 db 5
db 5fh,7,0,0
db 7ch,7,1,1
db 5fh,7,0,-1
db 7ch,7,1,1
db 5fh,7,0,-1
s4 db 4
db 7ch,7,1,0
db 5fh,7,0,1
db 7ch,7,1,1
db 7ch,7,-1,0
s5 db 5
db 5fh,7,0,0
db 7ch,7,1,-1
db 5fh,7,0,1
db 7ch,7,1,1
db 5fh,7,0,-1
s6 db 6
db 5fh,7,0,0
db 7ch,7,1,-1
db 5fh,7,0,1
db 7ch,7,1,1
db 5fh,7,0,-1
db 7ch,7,0,-1
s7 db 3
db 5fh,7,0,0
db 7ch,7,1,1
db 7ch,7,1,0
s8 db 7
db 7ch,7,1,0
db 5fh,7,-1,1
db 7ch,7,1,1
db 5fh,7,0,-1
db 7ch,7,1,1
db 5fh,7,0,-1
db 7ch,7,0,-1
s9 db 6
db 7ch,7,1,0
db 5fh,7,-1,1
db 7ch,7,1,1
db 5fh,7,0,-1
db 7ch,7,1,1
db 5fh,7,0,-1
s11 db 2
db 03h,7,1,0
db 03h,7,1,0
data ends
stack segment
db 200 p (0)
stack ends
code segment
assume cs:code,ss:stack,ds:data
start:
mov ax,data
mov ds,ax
mov ah,0 ;设置显示方式
mov al,4
int 10h
mov ah,0bh ;置彩色调板
mov bh,0
mov bl,1
int 10h
mov ah,0bh ;置彩色调板
mov bh,1
mov bl,4
int 10h
mov ah,2 ;取系统时间
int 1ah
mov ax,0
mov bx,0
mov ah,ch ;取系统时间
mov al,cl ;保存分钟
mov bh,dh ;保存秒
mov bl,dl ;保存百分之一秒
tt:
push ax
push bx
mov ah,0
mov al,4
int 10h
mov ah,0bh
mov bh,0
mov bl,1
int 10h
mov ah,0bh
mov bh,1
mov bl,4
int 10h
MOV AH,1 ;读键盘缓冲区字符
INT 16h
JZ ww
MOV AH,8 ;从键盘输入字符
INT 21h
CMP AL,'s' ;输入s,结束程序
JE tu
ww: pop bx
pop ax
call xian ;调用显示子程序
push ax
qu: mov ah,2 ;取系统时间
int 1ah
cmp bh,dh
je qu
pop ax
inc bh ;对时间进行加1
cmp bh,100
jl tt
mov bh,0
inc al
call beep
cmp al,100
jl tt
mov al,0
inc ah
cmp ah,24
jl tt
mov ah,0
jmp tt
tu: mov ah,4ch
int 21h
ret
xian proc ;对时间值进行处理并显示的子程序
push si
push di
push dx
push cx
push bx
push ax
pop ax
push ax
mov bx,ax
mov ax,0
mov al,bh
mov cl,4
shr al,cl
mov bl,al
mov dh,10
mov dl,2
call ff
pop ax
push ax
mov bx,ax
mov ax,0
mov al, bh
and al,0fh
mov bl,al
mov dh,10
mov dl,6
call ff
mov dh,10
mov dl,10
mov bl,10
call ff
pop ax
push ax
mov cl,4
shr al,cl
mov bl,al
mov dh,10
mov dl,14
call ff
pop ax
push ax
and al ,0fh
mov bl,al
mov dh,10
mov dl,18
call ff
mov dh,10
mov dl,22
mov bl,10
call ff
pop ax
pop bx
push bx
push ax
mov ax,0
mov al,bh
mov cl,4
shr al,cl
mov bl,al
mov dh,10
mov dl,26
call ff
pop ax
pop bx
push bx
push ax
mov al,bh
and al,0fh
mov bl,al
mov dh,10
mov dl,30
call ff
mov dh,0
mov dl,15
mov bl,22
call ff
pop ax
pop bx
pop cx
pop dx
pop di
pop si
ret
xian endp
ff proc ;显示具体数值
push ax
push bx
push cx
push dx
cmp bl,0
je l0
cmp bl,1
je l1
cmp bl,2
je l2
cmp bl,3
je l3
cmp bl,4
je l4
cmp bl,5
je l5
cmp bl,6
je l6
cmp bl,7
je l7
cmp bl,8
je l8
cmp bl,9
je l9
cmp bl,10
je l10
cmp bl,22
je ld
l0: lea di,s0
jmp ty
l1 : lea di,sy
jmp ty
l2: lea di,s2
jmp ty
l3: lea di,s3
jmp ty
l4: lea di,s4
jmp ty
l5: lea di,s5
jmp ty
l6: lea di,s6
jmp ty
l7: lea di,s7
jmp ty
l8: lea di,s8
jmp ty
l9: lea di,s9
jmp ty
l10: lea di,s11
jmp ty
ld : lea di,str
ty: mov ah,0fh ;示方式
int 10h
sub cx,cx
mov cl,[di]
inc di
plot_next: add dh,[di+2]
add dl,[di+3]
mov ah,2
int 10h
mov al,[di]
mov bl,[di+1]
push cx
mov cx,1
mov ah,09
int 10h
pop cx
add di,4
loop plot_next
pop dx
pop cx
pop bx
pop ax
mov cx,100
gg: dec cx
loop gg
ret
ff endp
clear proc
push ax
push bx
push cx
push dx
mov ah,6
mov al,0
mov bh,1
int 10h
pop dx
pop cx
pop bx
pop ax
ret
clear endp
beep proc
push ax
push bx
push cx
push dx
mov al ,10110110b
out 43h,al
mov ax,533h
out 42h,al
mov al,ah
out 42h,al
in al,61h
mov ah,al
or al,03
out 61h,al
sub cx,cx
mov bl,28h
g7: loop g7
dec bl
jnz g7
mov al,ah
out 61h,al
pop dx
pop cx
pop bx
pop ax
ret
beep endp
code ends
end start
3. 简易数字电子钟的设计
数字电子钟的设计
数字电子钟的设计方法有多种,例如,可用中小规模集成电路组成电子钟;也可以利用专用的电子钟芯片配以显示电路及其所需要的外围电路组成电子钟;还可以利用单片机来实现电子钟等等。这些方法都各有特点,其中,利用单片机实现的电子钟具有编程灵活,便于电子钟功能的扩充,即可用该电子钟发出各种控制信号,精确度高等特点。
所设计的电子钟有以下功能:
1. 24小时制时间显示。
2. 可随时进行时间校对。
3. 整点报时。
4. 闹钟功能。
为了节约制作硬件的开支,我们利用单片机开发机上的硬件资源,开发了电脑数字钟的软件。该数字钟由8031单片机控制,采用24小时制计时,利用开发机上的六个LED显示器来显示时、分和秒,使用P1端口中的P1.0端口线实现整点报时功能;使用P3端口的P3.0实现闹钟功能。其硬件原理图如图一所示。
图中的开关K4用于闹钟控制,当K4=1时(开关处于ON的位置),打开闹钟,使之在预定时间起闹;当K1=0时(开关处于OFF的位置),则关闭闹钟,使之不闹。另外,在闹钟响起时,K4也可作为止闹开关使用,若不止闹,则闹一分钟。闹钟信号用发光二极管来模拟。
整点报时信号也是用发光二极管来模拟的。当整点时,P1.0口所接的发光二极管点亮一分钟。
电脑数字钟的秒信号是利用8031单片机定时器T0产生的。由于开发机的晶振频率为6MHz,使得T0的最大定时时间远远小于1秒,因此,在设计时采用了硬件计数与软件计数相结合的方式,即通过T0产生一定的定时时间,然后再利用软件进行计数,从而产生1秒钟的时间信号。在设计中,定时器T0采用了中断方式。
数字电子钟的设计方法有多种,例如,可用中小规模集成电路组成电子钟;也可以利用专用的电子钟芯片配以显示电路及其所需要的外围电路组成电子钟;还可以利用单片机来实现电子钟等等。这些方法都各有特点,其中,利用单片机实现的电子钟具有编程灵活,便于电子钟功能的扩充,即可用该电子钟发出各种控制信号,精确度高等特点。
所设计的电子钟有以下功能:
1. 24小时制时间显示。
2. 可随时进行时间校对。
3. 整点报时。
4. 闹钟功能。
为了节约制作硬件的开支,我们利用单片机开发机上的硬件资源,开发了电脑数字钟的软件。该数字钟由8031单片机控制,采用24小时制计时,利用开发机上的六个LED显示器来显示时、分和秒,使用P1端口中的P1.0端口线实现整点报时功能;使用P3端口的P3.0实现闹钟功能。其硬件原理图如图一所示。
图中的开关K4用于闹钟控制,当K4=1时(开关处于ON的位置),打开闹钟,使之在预定时间起闹;当K1=0时(开关处于OFF的位置),则关闭闹钟,使之不闹。另外,在闹钟响起时,K4也可作为止闹开关使用,若不止闹,则闹一分钟。闹钟信号用发光二极管来模拟。
整点报时信号也是用发光二极管来模拟的。当整点时,P1.0口所接的发光二极管点亮一分钟。
电脑数字钟的秒信号是利用8031单片机定时器T0产生的。由于开发机的晶振频率为6MHz,使得T0的最大定时时间远远小于1秒,因此,在设计时采用了硬件计数与软件计数相结合的方式,即通过T0产生一定的定时时间,然后再利用软件进行计数,从而产生1秒钟的时间信号。在设计中,定时器T0采用了中断方式。
4. 单片机C语言编程简易数字电子时钟
#include <AT89X52.h>
unsigned char X=10,sec,flag;
unsigned char key[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};// 数码管显示数字表
unsigned char key2[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char key1[]={0,0,0,0};//key1[0]=9 key1[1]=1 key1[2]=2 key1[3]=3
void delay02s(void);
void dislplay(void);
void dislplay1(void);
void tim1(void);
void main()
{
tim1();
while(1)
{
if(flag==0) dislplay();
else dislplay1();
}
}
void time1(void) interrupt 3
{
TR1=0;
X=X-1;
if(X==0)
{
flag=flag+1;
if(flag==2)
{
flag=0;
sec=sec+1;
if(sec==60)
{
sec=0;
key1[3]=key1[3]+1;
if(key1[3]==10);
{
key1[3]=0;
key1[2]=key1[2]+1;
if(key1[2]==6)
{
key1[2]=0;
key1[1]=key1[1]+1;
if(key[0]!=2)
{
if(key1[1]==10)
{
key1[1]=0;
key1[0]=key1[0]+1;
}
}
if(key[0]==2)
{
if(key[1]==4)
{
key1[1]=0;
key1[0]=0;
}
}
}
}
}
}
X=10;
}
TL1=0xb0;
TH1=0x3c;
TF1=0;
TR1=1;
}
void tim1(void)
{
TMOD =0X10;
TL1=0xb0;
TH1=0x3c;
EA=1;
ET1=1;
TR1=1;
}
void dislplay(void)
{
P2=0xfe;
P0=key[key1[0]];
delay02s();
P2=0xfd;
P0=key[key1[1]];
delay02s();
P2=0xfb;
P0=key[key1[2]];
delay02s();
P2=0xf7;
P0=key[key1[3]];
delay02s();
}
void dislplay1(void)
{
P2=0xfe;
P0=key[key1[0]];
delay02s();
P2=0xfd;
P0=key2[key1[1]];
delay02s();
P2=0xfb;
P0=key[key1[2]];
delay02s();
P2=0xf7;
P0=key[key1[3]];
delay02s();
}
void delay02s(void)
{
unsigned char i,j,k;
for(i=2;i>0;i--)
{
for(j=15;j>0;j--) //198
{
for(k=25;k>0;k--)//248
{
;
}
}
}
}
我空间还有其他的 http://user.qzone.qq.com/615543707/infocenter?ptlang=2052&ADUIN=615543707&ADSESSION=1276219802&ADTAG=CLIENT.QQ.2653_Mysrv.0
5. 急需一个电子时钟的程序, 哪位高手请帮帮忙!!!,
一功能模、设计指标:
1. 显示时、分、秒。
2. 可以24小时制或12小时制。
3. 具有校时功能,可以对小时和分单独校时,对分校时的时候,停止分向小时进位。校时时钟源可以手动输入或借用电路中的时钟。
4. 具有正点报时功能,正点前10秒开始,蜂鸣器1秒响1秒停地响5次。
5. 为了保证计时准确、稳定,由晶体振荡器提供标准时间的基准信号。
二、设计要求:
1. 画出总体设计框图,以说明数字钟由哪些相对独立的块组成,标出各个模块之间互相联系,时钟信号传输路径、方向和频率变化。并以文字对原理作辅助说明。
2. 设计各个功能模块的电路图,加上原理说明。
3. 选择合适的元器件,在面包上接线验证、调试各个功能模块的电路,在接线验证时设计、选择合适的输入信号和输出方式,在充分电路正确性同时,输入信号和输出方式要便于电路的测试和故障排除。
4. 在验证各个功能模块基础上,对整个电路的元器件和布线,进行合理布局,进行整个数字钟电路的接线调试。
三、制作要求:
自行装配、接线和调试,并能检查和发现问题,根据原理、现象和测量的数据分析问题所在,加以解决。学生要解决的问题包括元器件和面包板故障引起的问题。
四、设计报告内容要求:
1. 目的。
2. 设计指标。
3. 画出设计的原理框图,并要求说明该框图的工作过程及每个模块的功能。
4. 元器件清单。
5. 设计制作的进程,考虑时钟及控制信号的关系、测试、验证的顺序,写出自己的工作进程。
6. 画出各功能模块的电路图,加上原理说明(如2、5进制到10进制转换,10进制到6进制转换的原理,个位到十位的进位信号选择和变换等)。
7. 画出总布局接线图(集成块按实际布局位置画,关键的连接单独应画出,计数器到译码器的数据线、译码器到数码管的数据线可以简化画法,但集成块的引脚须按实际位置画,并注明名称。)
8. 描述设计制作的数字钟的运行结果和操作。
9. 总结。
设计过程中遇到的问题及解决办法
课程设计过程体会
对课程设计内容、方式、要求等各方面的建议。
五、实验仪器、工具:
1. 5V电源(或实验箱)4个人合用1个。
2. 四连面包板1块。
3. 示波器2个(每班)
4. 万用表5个(每班)。
5. 镊子1把。
6. 剪刀1把。
六、实验器件
1. 网络线2米/人。
2. 共阴八段数码管6个。
3. CD4511集成块6块。
4. CD4060集成块1块。
5. 74HC390集成块3块。
6. 74HC51集成块1块。
7. 74HC00集成块4块。
8. 74HC30集成块1块。
9. 10MΩ电阻5个。
10. 500Ω电阻14个。
11. 30p电容2个。
12. 32.768k时钟晶体1个。
13. 蜂鸣器10个(每班)
七、设计过程的日程安排
6月28日
1. 分发仪器、工具、器件
2. 讲解总体设计的过程,明确数字钟实现的功能,由哪些相对独立的功能模块组成,各个模块之间互相联系,时钟信号传输路径、方向和频率变化。
3. 讲解面包板的结构和使用方法,连接导线的要点,包括导线剥线头、插线方法、要求,检查面包板,如面包板中的导电铜片变形或移位,更换导电铜片。
4. 七段数码引脚排列测试,验证每段显示为一个发光二极管,同时完成对每个数码管的检查。
6月29日~7月2日
分功能讲解各个模块功能实现原理、实现,搭建实际电路一个个验证。在接线时注意合理布线和接线的可靠性。
6月29日
a) 数码管的译码驱动电路接线、测试、译码器控制功能测试(手工输入测试电平)。
除了进一步熟悉原理外,主要练习接线合理布局,走线整齐、美观,用手指触动导线时也能正常工作。可以静态显示学号的后几位。然选一个可正常工作的译码、显示电路,分别测试译码器的3个控制引脚的作用。
6月30日
b) 晶体震荡电路接线、测试(用示波器测量4060输入时钟,每一路分频输出的频率)。
c) 5进制计数器接线,输入用4060的2Hz,输出用数码管显示。
7月1日
d) 10进制计数器接线、测试。
e) 6进制计数器接线、测试(在10进制基础上改)。
7月2日
f) 60进制计数器接线、测试。
g) 24进制计数器、测试(在60进制基础上改)。
h) 校时电路接线(用RS触发器实现锁定、防抖动功能),用示波器观察电路的信号选择功能。
7月5~7日
5. 在熟悉各个功能模块基础上,结合对总体框图的理解,设计总接线图。
6. 根据总接线图中各种元器件数量、连线,确定所有元器件布局。
7. 按以下顺序接线:晶体震荡、秒电路、分电路、时电路。
8. 如时间允许加接校时电路和报时电路(整点报时)。
7月8~9日
9. 写课程设计报告。
a) 设计的目的、要求。
b) 总体框图设计。
c) 功能模块设计(对所用元器件使用作一些说明)。
d) 总电路图设计。
e) 总结:遇到的问题和解决办法、体会、意见、建议等。
八、Multisim2001软件部分集成块引脚图
集成块引脚图
九、部分原理仿真模块电路
4511构成译码驱动电路
4060构成脉冲发生及分频电路
74390 构成十进制计数器
74390构成六进制计数器
74390构成六十进制计数器
校时电路(分校时时,不会进位到小时)
十、数字钟的设计与制作原理
具体参照:
数字电子技术课程设计讲义-数字钟的设计与制作
(电子信息学院,2004年6月)
十一、Multisim2001软件及其参考仿真电路
自己在对应位置下载。
十二、设计经验总结:
1. 要求学生根据原理和芯片引脚图,分功能设计原理图,并根据接线顺序分步骤验证。
2. 容易出现故障为接触不良。
a) 集成块引脚方向预先弯好对准面包板的金属孔,再小心插入。
b) 导线的剥线长度与面包板的厚度相适应(比板的厚度稍短)。
c) 导线的裸线部分不要露在板的上面,以防短路。
d) d) 导线要插入金属孔中央。
3. 按照原理图接线时首先确保可靠的电源和接地。
4. 注意芯片的控制引脚必须正确接好。
5. 检查故障时除测试输入、输出信号外,要注意电源、接地和控制引脚。
6. 要注意芯片引脚上的信号与面包板上插座上信号是否一致(集成块引脚与面包板常接触不良)。
7. 为了便于测试,可将2Hz信号直接输入到各级计数器。
8. 接校时电路时可接模拟信号输入(如1Hz和2Hz)测试输出信号的切换正确后,再将秒进位和分进位信号接到校时电路,再接校时电路输出到分计数器和时计数器。
从较时电路接入信号时,必须将原进位信号拔掉。
6. 单片机电子时钟编程
设计两个按键,一个选定时钟数字一个改变时钟数字,选择一个中断定时扫描按键,通过读入键值给DS1307初始化校时,再选择一个中断定时扫描DS1307可以读出时,分,秒的BCD码,将BCD码译码后点亮数码管,数码管的显示可以通过对比当前时间与上一次扫描读出时间确定时,分,秒哪位发生了改变,分别选通对应的数码管,刷新显示。
7. 用51单片机编程:电子时钟(设计电子时钟,用51单片机编程)
如果有问题欢迎到我空间相关文章下留言 乐于回答~~
程序如下:
; 定义管脚
S_SET BIT P1.0 ;数字钟秒控制位
M_SET BIT P1.1 ;分钟控制位
H_SET BIT P1.2 ;小时控制位
SECOND EQU 30H
MINUTE EQU 31H
HOUR EQU 32H
ORG 00H
SJMP MAIN
ORG 0BH
LJMP INT_T0
MAIN: MOV DPTR,#TABLE
MOV HOUR,#0 ;初始化
MOV MINUTE,#0
MOV SECOND,#0
MOV R0,#0
MOV TMOD,#01H
MOV TH0,#3CH ; 设置初值(定时50毫秒)
MOV TL0,#0B0H
SETB TR0 ;启动定时
SETB ET0
SETB EA
;*******************************************************************************
;判断是否有控制键按下
A1: LCALL DISPLAY
JNB S_SET,S1
JNB M_SET,S2
JNB H_SET,S3
LJMP A1
S1: LCALL DELAY ;去抖动
JB S_SET,A1
INC SECOND ;秒值加1
MOV A,SECOND
CJNE A,#60,J0 ;判断是否加到60秒
MOV SECOND,#0
LJMP K1
S2: LCALL DELAY
JB M_SET,A1
K1: INC MINUTE ;分钟值加1
MOV A,MINUTE
CJNE A,#60,J1 ;判断是否加到60分
MOV MINUTE,#0
LJMP K2
S3: LCALL DELAY
JB H_SET,A1
K2: INC HOUR ;小时值加1
MOV A,HOUR
CJNE A,#24,J2 ;判断是否加到24小时
MOV HOUR,#0
MOV MINUTE,#0
MOV SECOND,#0
LJMP A1
;****************************************************
;等待按键抬起
J0: JB S_SET,A1
LCALL DISPLAY
SJMP J0
J1: JB M_SET,A1
LCALL DISPLAY
SJMP J1
J2: JB H_SET,A1
LCALL DISPLAY
SJMP J2
;***********************************************
;定时器中断服务程序,对秒,分钟和小时的计数
INT_T0: MOV TH0,#3CH
MOV TL0,#0B0H
INC R0
MOV A,TCNT
CJNE A,#20,RETUNE ;计时1秒
INC SECOND
MOV R0,#0
MOV A,SECOND
CJNE A,#60,RETUNE
INC MINUTE
MOV SECOND,#0
MOV A,MINUTE
CJNE A,#60,RETUNE
INC HOUR
MOV MINUTE,#0
MOV A,HOUR
CJNE A,#24,RETUNE
MOV HOUR,#0
MOV MINUTE,#0
MOV SECOND,#0
MOV R0,#0
RETUNE: RETI
;******************************************
;显示控制子程序
DISPLAY: MOV A,SECOND ;显示秒
MOV B,#10
DIV AB
CLR P3.6
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.6
MOV A,B
CLR P3.7
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.7
CLR P3.5
MOV P0,#40H ;显示分隔符
LCALL DELAY
SETB P3.5
MOV A,MINUTE ;显示分钟
MOV B,#10
DIV AB
CLR P3.3
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.3
MOV A,B
CLR P3.4
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.4
CLR P3.2
MOV P0,#40H ;显示分隔符
LCALL DELAY
SETB P3.2
MOV A,HOUR ;显示小时
MOV B,#10
DIV AB
CLR P3.0
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.0
MOV A,B
CLR P3.1
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.1
RET
TABLE: DB 3FH,06H,5BH,4FH,66H
DB 6DH,7DH,07H,7FH,6FH
DELAY: MOV R6,#5
D1: MOV R7,#250
DJNZ R7,$
DJNZ R6,D1
RET
END
这里的程序没用38译码器,若要用则显示子程序要改
如 要显示秒,程序如下
DISPLAY: MOV A,SECOND ;显示秒
MOV B,#10
DIV AB
MOV R7,#60H
ORG A,R7
MOV P0,A
LCALL DELAY
MOV A,B
MOV R7,#70H
ORL A,R7
MOV P0,A
LCALL DELAY
其他的一样这样改
8. 用C语言编一个数字电子时钟的程序
1.这是用windows api写的程序。所以要求是纯c的话就没有办法了
2.其中定时用了两种方法。一种是用取消息。另一种是延时队列。这里只使用了取消息的方法。延时队列由于我机器上是vc6.0,CreateTimerQueue在本人机器上无法使用,需要新的sdk,所以没有加以验证,但取消息的方式是可行的。
3.稍稍验证了下,基本满足要求。
-------------------------------------------
程序如下:
// DigitalClock.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <winbase.h>
typedef struct _st_time{
int hour;
int min;
int sec;
}ST_TIME;
ST_TIME g_Time; // The struct contain the hour,min and sec.
HANDLE g_hStdout; //
WORD g_cxCenter, g_cyCenter; // Center of the screen.
HANDLE g_DoneEvent; // The program could be over.
BOOL g_ThreadTerminated; // The Thread should be terminated.
#define SECOND_CIRCLE 60
#define MINUTE_CIRCLE 60
#define HOUR_CIRCLE 24
void TimeIncreaseSecond(ST_TIME & st)
{
st.sec ++;
if (st.sec >= SECOND_CIRCLE)
{
st.sec -= SECOND_CIRCLE;
st.min++;
if (st.min >= MINUTE_CIRCLE)
{
st.min -= MINUTE_CIRCLE;
st.hour++;
if (st.hour >= HOUR_CIRCLE)
{
st.hour -= HOUR_CIRCLE;
}
}
}
}
void PrintTimeToScreen(HANDLE hStdout, short cxCenter, short cyCenter, ST_TIME st)
{
char buf[64] = {0};
COORD crdPos;
// make it format to output.
sprintf (buf, "%02d:%02d:%02d", st.hour, st.min, st.sec);
crdPos.X = cxCenter - 4;
crdPos.Y = cyCenter;
SetConsoleCursorPosition(hStdout, crdPos);
printf(buf);
}
#ifdef USE_TIMERQUEUE
// if we use the timer queue function.
// Its procre is in this.
void CALLBACK TimerRoutine (LPVOID lpParam, BOOL TimerOrWaitFired)
{
if (lpParam == NULL)
{
printf ("NULL parameters.\n");
}
else
{
ST_TIME *st = (ST_TIME *)lpParam;
TimeIncreaseSecond(st);
PrintTimeToScreen(g_hStdout, g_cxCenter, g_cyCenter, *st);
}
}
#else
DWORD WINAPI TimerThreadProc(LPVOID lpParam)
{
#define ID_TIMER_SECOND 1
MSG msg;
BOOL ret;
ST_TIME *st = (ST_TIME *)lpParam;
SetTimer(NULL, ID_TIMER_SECOND, 1000, NULL);
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
while (!g_ThreadTerminated && (ret = GetMessage (&msg, NULL, 0, 0)) != 0)
{
if (ret == -1)
{
//process fatal event.
}
else if (msg.message == WM_TIMER)
{
TimeIncreaseSecond(*st);
PrintTimeToScreen(g_hStdout, g_cxCenter, g_cyCenter, *st);
}
else
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
return 1;
}
#endif
// If the ctrl+break combined key pressed. call this function.
// It set the g_DoneEvent. this terminate the program.
BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
{
switch (fdwCtrlType)
{
case CTRL_BREAK_EVENT:
// Terminate the program.
printf ("Terminate.\n");
SetEvent(g_DoneEvent);
return TRUE;
default:
return FALSE;
}
}
BOOL InitApplication()
{
// Get the stdin and stdout handle.
HANDLE hStdIn;
hStdIn = GetStdHandle(STD_INPUT_HANDLE);
if (hStdIn == INVALID_HANDLE_VALUE)
return FALSE;
g_hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
// Set the mode, make the input echo.
DWORD fOldMode;
GetConsoleMode(hStdIn, &fOldMode);
fOldMode |= ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
SetConsoleMode(hStdIn, fOldMode);
// Set the window buffer.
// make a line 40 columns.
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
GetConsoleScreenBufferInfo(g_hStdout, &csbiInfo);
csbiInfo.srWindow.Right = 40;
// get the center point.
g_cxCenter = csbiInfo.srWindow.Right / 2;
g_cyCenter = csbiInfo.srWindow.Bottom / 2;
// Set the window.
SetConsoleWindowInfo(g_hStdout, TRUE, &csbiInfo.srWindow);
return TRUE;
}
BOOL (HANDLE hStdout, WORD cxCenter, WORD cyCenter, ST_TIME & time)
{
#define GAPS_LEFT_COLON (-2)
#define GAPS_RIGHT_COLON (1)
#define GAPS_LEFT_UNDERLINE_START (-4)
#define GAPS_MIDDLE_UNDERLINE_START (-1)
#define GAPS_RIGHT_UNDERLINE_START (2)
// __:__:__
// So the left ":" center -2
// so the right ":" center + 1
// so the left "_" center - 4;
// so the lfet "_" center - 1;
// so the right "_" center + 2;
COORD crdPos;
crdPos.X = cxCenter + GAPS_LEFT_COLON;
crdPos.Y = cyCenter;
SetConsoleCursorPosition(hStdout, crdPos);
printf (":");
crdPos.X = cxCenter + GAPS_RIGHT_COLON;
SetConsoleCursorPosition(hStdout, crdPos);
printf (":");
crdPos.X = cxCenter + GAPS_LEFT_UNDERLINE_START;
SetConsoleCursorPosition(hStdout, crdPos);
scanf ("%d", &time.hour);
crdPos.X = cxCenter + GAPS_MIDDLE_UNDERLINE_START;
SetConsoleCursorPosition(hStdout, crdPos);
scanf ("%d", &time.min);
crdPos.X = cxCenter + GAPS_RIGHT_UNDERLINE_START;
SetConsoleCursorPosition(hStdout, crdPos);
scanf ("%d", &time.sec);
if (time.hour < 0 || time.hour > HOUR_CIRCLE ||
time.min < 0 || time.min > MINUTE_CIRCLE ||
time.sec < 0 || time.sec > SECOND_CIRCLE)
return FALSE;
return TRUE;
}
int main(int argc, char* argv[])
{
InitApplication();
(g_hStdout, g_cxCenter, g_cyCenter, g_Time);
// create a event to tell the program to terminate.
g_DoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
#ifdef USE_TIMERQUEUE
HANDLE hTimerQueue, hTimer;
hTimerQueue = CreateTimerQueue();
if (!CreateTimerQueueTimer(&hTimer,
hTimerQueue, TimerRoutine, &g_Time, 1000, 0, 0))
{
printf("CreateTimerQueueTimer failed (%d)\\n", GetLastError());
return 3;
}
#else
// create the thread.
HANDLE hThreadTimer;
DWORD dwThreadId;
g_ThreadTerminated = FALSE;
hThreadTimer = CreateThread(NULL, 0,
TimerThreadProc, &g_Time, 0, &dwThreadId);
if (hThreadTimer == NULL)
{
}
#endif
SetConsoleCtrlHandler(CtrlHandler, TRUE);
if (WaitForSingleObject(g_DoneEvent, INFINITE) != WAIT_OBJECT_0)
printf("WaitForSingleObject failed (%d)\\n", GetLastError());
#ifdef USE_TIMERQUEUE
if (!DeleteTimerQueue(hTimerQueue))
printf("DeleteTimerQueue failed(%d) \\n", GetLastError());
#else
g_ThreadTerminated = TRUE;
if (WaitForSingleObject(hThreadTimer, INFINITE) != WAIT_OBJECT_0)
printf("WaitForSingleObject failed (%d)\\n", GetLastError());
#endif
return 0;
}
--------------------------------------------
下面是纯c的。
有几个问题:
1.textmode函数在turboc中没有办法使用,不知道是什么问题,而borland c就可以。
2.无论怎么设置,自己的ctrlbreak函数在上述两个环境中都不能被调用,非常遗憾。所以不能够优雅的退出。只能按两次ctrlbreak。
下面是程序。
------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#define ABORT 0
int jump_out_loop = -1;
int jump_out(void)
{
jump_out_loop = 1;
printf("Abort ..\n");
return ABORT;
}
int main(void)
{
struct text_info ti;
int center_x, center_y;
int hour, min, sec;
char str_out[64] = {0};
clrscr();
/*textmode(BW40);*/
/*textmode在turbo c下设置会出问题*/
gettextinfo(&ti);
center_x = ti.winright / 2;
center_y = ti.winbottom / 2;
gotoxy(center_x - 4, center_y);
cprintf(" : : ");
gotoxy(center_x - 4, center_y);
cscanf("%d", &hour);
gotoxy(center_x - 1, center_y);
cscanf("%d", &min);
gotoxy(center_x + 2, center_y);
cscanf("%d", &sec);
/* check input valid or not */
{}
setcbrk(1);
ctrlbrk(jump_out);
/*jump_out没有起到作用,实在不好意思.*/
/*
if (getcbrk())
printf("crtl break is on\n");
else
printf("is off\n");
*/
while (1)
{
delay(1000);
sec++;
if (sec >= 60)
{
sec -= 60;
min++;
if (min >= 60)
{
min -= 60;
hour++;
if (hour >= 24)
{
hour -= 24;
}
}
}
sprintf(str_out, "%02d:%02d:%02d", hour, min, sec);
gotoxy(center_x - 4, center_y);
cprintf(str_out);
}
/* getch();*/
return 0;
}
9. 数字电子钟设计用汇编
有一个8086的给你借鉴一下,希望对你有用。
.486
DATA SEGMENTAT0USE16
ZDXL EQU20H ;中断向量(20H)
OPORTEQU3A0H ;8259偶地址
JPORTEQU3A8H ;8259奇地址
PORT1EQU340H ;段地址
PORT2EQU360H ;位地址
DS0 EQU300H ;8253通道0
DSC EQU30CH ;8253控制口
COUNT EQU50
ORG 4000H
DATA1 DB6DUP(?)
ORG 4040H
DATA2 DB3DUP(?)
DATA ENDS
CODE SEGMENTUSE16
ASSUMECS:CODE,DS:DATA,ES:DATA
ORG2000H
BEG:CLI
JMPSTART
TABDB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,
DB7FH,67H,77H,7CH,39H,5EH,79H,71H;段码表
TIMERDB0 ;延时、计数初值
START:
MOVAX,DATA ;初始化
MOVDS,AX
MOVES,AX
MOVAX,0
MOVSS,AX
MOVSP,1000H
INIT8253:
MOVDX,DSC
MOVAL,00010110B ;方式3,方波发生器
OUTDX,AL
MOVDX,DS0
MOVAL,0BH
OUTDX,AL
MOVAL,0E9H
OUTDX,AL
SETVECT:
MOVDI,0
MOVDX,OFFSETSERVER ;中断服务子程序偏移地址
MOVZDXL[DI],DX;送中断向量低位
MOVDX,CS ;中断服务子程序段地址
MOVZDXL[DI+2],DX;送中断向量高位
INIT8259:
MOVAL,00010011B ;ICW1
MOVDX,OPORT
OUTDX,AL
MOVAL,00001000B ;ICW2
MOVDX,JPORT
OUTDX,AL
MOVAL,00001101B ;ICW4
MOVDX,JPORT
OUTDX,AL
MOVAL,11111110B ;OCW1
MOVDX,JPORT
OUTDX,AL
MOVAL,20H ;EOI(20H)
MOVDX,OPORT
OUTDX,AL
AGAIN:
STI ;开中断
CALLCZ ;调拆字
CALLDISP ;调显示
JMPAGAIN
CZPROC
PUSHCX
LEASI,DATA1 ;SI=拆字,取数
LEADI,DATA2 ;DI=显示缓冲区首址
CZ0:
MOVBL,[SI]
ANDBL,0F0H;BL=
MOVCL,4
ROLBL,CL
MOV[DI],BL;(DI)=
INCDI
MOVBL,[SI]
ANDBL,0FH;BL=
MOV[DI],BL
INCSI
INCDI
CMPSI,08H;....
JBECZ0
POPCX
RET
CZ ENDP
DISP PROC ;显示子程序
PUSHCX
PUSHDX
LEABX,TAB
LEASI,DATA2
MOVAH,0C1H
DISP1:
MOVDX,PORT2
MOVAL,AH
OUTDX,AL ;AL=,AL=位输出
MOVDX,PORT1
MOVAL,[SI]
XLAT
OUTDX,AL ;AL=,AL=段输出
MOVCX,0200H
LOOP$
INCSI
SALAH,1
ORAH,0C0H
CMPAH,0C0H
JNZDISP1
POPDX
POPCX
RET
DISPENDP
SERVERPROC ;8253中断入口
CLI
PUSHAX
PUSHCX
PUSHDX
PUSHSI
PUSHDI
LEASI,TIMER
MOVAL,[SI]
INCAL
CMPAL,… ;与延时、计数值终值比较
JBWORK ;大于、等于(到1秒)转移
MOV[SI],AL ;[SI]=,[SI]=,[SI]=
JMPEXIT
WORK:
MOVAL,0
MOV[SI],AL
LEASI,DATA2+2
MOVAL,[SI]
INCAL
AAA ;..十进制调整
CMPAL,60 ;...与60秒比较
JBMINUTE ;...大于、等于(60秒)转移
MOV[SI],AL
JMPEXIT
MINUTE:
MOVAL,0
MOV[SI],AL
LEASI,DATA2+1
MOVAL,[SI]
INCAL
AAA ;...十进制调整
CMPAL,60 ;...与60分比较
JBHOURE ;...大于、等于(60分)转移
MOV[SI],AL
JMPEXIT
HOURE:
MOVAL,0
MOV[SI],AL
LEASI,DATA2
MOVAL,[SI]
INCAL
AAA ;...十进制调整
CMPAL,24 ;...与24小时比较
JBNEXT ;...大于、等于(24小时)转移
MOV[SI],AL
JMPEXIT
NEXT:
MOVAL,0
MOV[SI],AL
EXIT:
MOVAL,20H
MOVDX,OPORT
OUTDX,AL
POPDI
POPSI
POPDX
POPCX
POPAX
RET
SERVERENDP
CODE ENDS
ENDBEG