如何用单片机汇编语言设计一个秒表
设计一个秒表,需要考虑以下因素:
1、因为视觉暂留的因素,一般而言到0.1秒的精度就可以了。
2、需要有按键控制启动、停止、清零这些功能。
KEYVAL EQU 30H
DAT EQU 33H
SCANLED EQU 39H
CLK EQU 77H
SEC EQU 78H
SEC1 EQU 79H
SEC2 EQU 7AH
DOT BIT 00H
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP EXTINT0
ORG 000BH
LJMP T0ISR 50ms定时
ORG 001BH
LJMP T1ISR 扫描显示
ORG 0030H
MAIN:
MOV SP,#5FH
MOV TMOD,#11H
MOV TH0,#03CH
MOV TL0,#0B0H
MOV TH1,#0ECH
MOV TL1,#078H
MOV KEYVAL,#2
MOV 33H,#10H
MOV 34H,#10H
MOV 35H,#10H
MOV 36H,#10H
MOV CLK,#0
SETB IT0
SETB EX0
CLR TR0
CLR ET0
MOV R2,#0
SETB TR1
SETB ET1
SETB EA
LOOP:
MOV A,KEYVAL
LOOP1:
JNZ LOOP2 启动
SETB TR0
SETB ET0
SJMP LOOP
LOOP2:
DEC A
JNZ LOOP3 暂停
CLR TR0
CLR ET0
SJMP LOOP
LOOP3:
DEC A
JNZ LOOP 清零
MOV 36H,#0
MOV 35H,#0
MOV 34H,#0
MOV 33H,#0
SJMP LOOP
EXTINT0:
PUSH ACC
INC KEYVAL
MOV A,KEYVAL
CJNE A,#3,EXT00
EXT00:
JC EXT01
MOV KEYVAL,#0
EXT01:
POP ACC
RETI
T0ISR:
PUSH ACC
CLR TR0
MOV TH0,#3CH
MOV TL0,#0B0H
SETB TR0
INC CLK
MOV A,CLK
CJNE A,#2,T0ISRE
MOV CLK,#0
INC 36H
MOV A,36H
CJNE A,#10,T0ISRE
MOV 36H,#0
INC 35H
MOV A,35H
CJNE A,#10,T0ISRE
MOV 35H,#0
INC 34H
MOV A,34H
CJNE A,#6,T0ISRE
MOV 34H,#0
INC 33H
MOV A,33H
CJNE A,#10,T0ISRE
MOV 33H,#0
T0ISRE:
POP ACC
RETI
T1ISR:
PUSH ACC
CLR TR1
MOV TH1,#0ECH
MOV TL1,#78H
SETB TR1
MOV DPTR,#LEDTAB
T100:
MOV R0,#DAT
MOV A,SCANLED
ADD A,R0
MOV R0,A
MOV A,SCANLED
JNZ T101
MOV P2,#01H
SETB DOT
SJMP T1DIS
T101:
DEC A
JNZ T102
MOV P2,#02H
CLR DOT
SJMP T1DIS
T102:
DEC A
JNZ T103
MOV P2,#04H
SETB DOT
SJMP T1DIS
T103:
MOV P2,#08H
CLR DOT
T1DIS:
MOV A,@R0
MOVC A,@A+DPTR
JNB DOT,T1DIS1
ORL A,#01H
T1DIS1:
CPL A
MOV P0,A
INC SCANLED
MOV A,SCANLED
CJNE A,#4,T1END
MOV SCANLED,#0
T1END:
POP ACC
RETI
LEDTAB: DB 0FCH "0" 00H
DB 60H "1" 01H
DB 0DAH "2" 02H
DB 0F2H "3" 03H
DB 66H "4" 04H
DB 0B6H "5" 05H
DB 0BEH "6" 06H
DB 0E0H "7" 07H
DB 0FEH "8" 08H
DB 0F6H "9" 09H
DB 0EEH "A" 0AH
DB 3EH "B" 0BH
DB 9CH "C" 0CH
DB 7AH "D" 0DH
DB 9EH "E" 0EH
DB 8EH "F" 0FH
DB 00H " " 10H
END
数字电子技术基础课程设计(一)——电子钟
数字电子技术基础
课程设计
电子秒表
一.设计目的:
1、了解计时器主体电路的组成及工作原理
2、熟悉集成电路及有关电子元器件的使用
3、学习数字电路中基本RS触发器、时钟发生器及计数、译码显示等单元电路的综合应用。
二.设计任务及说明:
电子秒表电路是一块独立构成的记时集成电路芯片。它集成了计数器、、振荡器、译码器和驱动等电路,能够对秒以下时间单位进行精确记时,具有清零、启动计时、暂停计时及继续计时等控制功能。
设计一个可以满足以下要求的简易秒表
1.秒表由5位七段LED显示器显示,其中一位显示“min”,四位显示“s”,其中显示分辩率为0.01 s,计时范围是0—9分59秒99毫秒;
2.具有清零、启动计时、暂停计时及继续计时等控制功能;
3.控制开关为两个:启动(继续)/暂停记时开关和复位开关
三.总体方案及原理:
电子秒表要求能够对时间进行精确记时并显示出来,因此要有时钟发生器,记数及译码显示,控制等模块,系统框图如下:
时钟发生器 记数器 译码器
显示器
控制器
图1.系统框图
其中:
(1)时钟发生器:利用石英震荡555定时器构成的多谐振荡器做时钟源,产生100HZ的脉冲
(2)记数器:对时钟信号进行记数并进位,毫秒和秒之间10进制,秒和分之间60进制
(3)译码器:对脉冲记数进行译码输出到显示单元中;
(4)显示器:采用5片LED显示器把各位的数值显示出来,是秒表最终的输出,有分、秒、和毫秒位;
(5)控制器:控制电路是对秒表的工作状态(记时开始/暂停/继续/复位等)进行控制的单元,可由触发器和开关组成。
四.单元电路设计,参数计算和器件选择:
1.时钟发生单元
时钟发生器可以采用石英晶体震荡产生100HZ时钟信号,也可以用555定时器构成的多谐振荡器,555定时器是一种性能较好的时钟源,切构造简单,采用555定时器构成的多谐振荡器做为电子秒表的输入脉冲源。
因输出要求为100HZ的,选择占空比为55%,可根据
T=( )Cln2=0.01
可选择的电阻进行连接可在输出端3获得频率为100HZ的矩形波信号,即T=0.01S的时钟源,当基本RS触发器Q=1时,门5开启,此时100HZ脉冲信号通过门5作为计数脉冲加于计数器①的计数输入端CP2。
图2.时钟发生器555定时器构成的多谐振荡器
2.记数单元
记数器74160、74ls192、74ls90等都能实现十进制记数,本设计采用二—五—十进制加法计数器74LS90构成电子秒表的计数单元,如图3所示,555定时器构成的多谐振荡器作为计数器①的时钟输入。计数器①及计数器②接成8421码十进制形式,其输出端与实验装置上译码显示单元的相应输入端连接,可显示0.01~0.09秒;0.1~0.9秒计时,计数器②及计数器③,计数器③和计数器④也接成8421码十进制形式,计数器④和计数器⑤接成60进制的形式,实现秒对分的进位。
集成异步计数器74LS90简介
74LS90是异步二—五—十进制加法计数器,它既可以作二进制加法计数器,又可以作五进制和十进制加法计数器。
图3为74LS90引脚排列,表1为功能表。
通过不同的连接方式,74LS90可以实现四种不同的逻辑功能;而且还可借助R0(1)、R0(2)对计数器清零,借助S9(1)、S9(2)将计数器置9。其具体功能详述如下:
(1)计数脉冲从CP1输入,QA作为输出端,为二进制计数器。
(2)计数脉冲从CP2输入,QDQCQB作为输出端,为异步五进制加法计数器。
(3)若将CP2和QA相连,计数脉冲由CP1输入,QD、QC、QB、QA作为输出端,
则构成异步8421码十进制加法计数器。
(4)若将CP1与QD相连,计数脉冲由CP2输入,QA、QD、QC、QB作为输出端,
则构成异步5421码十进制加法计数器。
(5)清零、置9功能。
a) 异步清零
当R0(1)、R0(2)均为“1”;S9(1)、S9(2)中有“0”时,实现异步清零功能,即QDQCQBQA=0000。
b) 置9功能
当S9(1)、S9(2)均为“1”;R0(1)、R0(2)中有“0”时,实现置9功能,即QDQCQBQA=1001。
图3.74LS90引脚排列(下)
输 入 输 出 功 能
清 0 置 9 时 钟 QD QC QB QA
R0(1)、R0(2) S9(1)、S9(2) CP1 CP2
1 1 0
× ×
0 × × 0 0 0 0 清 0
0
× ×
0 1 1 × × 1 0 0 1 置 9
0 ×
× 0 0 ×
× 0 ↓ 1 QA 输 出 二进制计数
1 ↓ QDQCQB输出 五进制计数
↓ QA QDQCQBQA输出8421BCD码 十进制计数
QD ↓ QAQDQCQB输出5421BCD码 十进制计数
1 1 不 变 保 持
表1 .74LS90功能表
10秒到分位的6进制位可在十进制的基础上将QB、QC连接到一个与门,它的置零信号与系统的置零信号通过一个或门连接接至R0(1),即当记数为6或有置零信号是均置零,如图4所示。
图4 .74ls90组成的6进制记数器
3 .译码显示单元
74LS248(74LS48)是BCD码到七段码的显示译码器,它可以直接驱动共阴极数码管。它的管脚图如图5所示. 显示器用 LC5011-11 共阴极LED显示器.(注:在multisim中仿真可以用译码显示器DCD_HEX代替译码和显示单元)。
图5. 74LS248管脚图
4 .控制单元
(1) 启动(继续)/暂停记时开关
采用集成与非门构成的基本RS触发器。属低电平直接触发的触发器,有直接置位、复位的功能。
它的一路输出作为单稳态触发器的输入,另一路输出Q作为与非门5的输入控制信号。
按动按钮开关B(接地),则门1输出 =1;门2输出Q=0,K2复位后Q、状态保持不变。再按动按钮开关K1 ,则Q由0变为1,门5开启, 为计数器启动作好准备。由1变0,送出负脉冲,启动单稳态触发器工作。
(2) 清零开关
通过开关对每个计数器的R0(2)给以高电平能实现系统的清零。
五:在MULTISIM中进行仿真
将各个芯片在MULTISIM8中连接并进行仿真,仿真如图6所示,结果正确。
六:设计所需元件
555触发器一片,74ls90五片,74ls248五片,LC5011-11 共阴极LED显示器五片,
电容、电阻若干。
七:设计心得
本次课程设计对数字电子技术有了更进一步的熟悉,实际操作和课本上的知识有很大联系,但又高于课本,一个看似很简单的电路,要动手把它设计出来就比较困难了,因为是设计要求我们在以后的学习中注意这一点,要把课本上所学到的知识和实际联系起来,同时通过本次电路的设计,不但巩固了所学知识,也使我们把理论与实践从真正意义上结合起来,增强了学习的兴趣,考验了我们借助互联网络搜集、查阅相关文献资料,和组织材料的综合能力。
参考资料:http://blog.sina.com.cn/gaowentao
用89C51,外接晶振,复位电路,二个数码管,二个按键,做一个电子秒表,具体要求为用按键起停电子表,可用按键设计倒计时时间(如10S,20S,60S),并启动倒计时功能。能用按键选择以上两功能之一。
三、程序代码:
A_BIT EQU 20H 数码管个位数存放内存位置
B_BIT EQU 21H 数码管十位数存放内存位置
TEMP EQU 22H 计数器数值存放内存位置
开机初始化
MOV P3,#0FFH对P3口初始化,设置为高电平,用于按键输入
MOV P0,#0FFH使显示时间数码管熄灭
CLR F0
CLR F1
MOV DPTR,#NUMTAB 指定查表启始地址
等待按键输入
根据按键的输入判断执行什么功能
按键1按下则执行功能1
MOV P3,#0FFH对P3口初始化,设置为高电平,用于按键输入
MOV P0,#0FFH使显示时间数码管熄灭
START:JB P3.6,START1循环判断开始按钮K1是否按下?
ACALL DELAY10延时10毫秒触点消抖
JB P3.6,START如果是干扰就返回
JNB P3.6,$等待按键松开
LJMP GN1
按键2按下则执行功能2
START1: JB P3.7,START循环判断开始按钮K2是否按下?
ACALL DELAY10延时10毫秒触点消抖
JB P3.7,START1如果是干扰就返回
JNB P3.7,$
LJMP GN2
数码管显示秒表时间的程序
GN1:先初始化
S1:MOV A,#0
MOV TEMP,A
GOON1: MOV R2,#2
JS1: MOV R3,#250
TIME1: MOV A,TEMP 将TEMP中的十六进制数转换成10进制
MOV B,#10 10进制/10=10进制
DIV AB
MOV B_BIT,A 十位在A
MOV A_BIT,B 个位在B
LCALL DPLOP1
插入一段判断定时过程中是否有按键输入的程序段
C1: JB P3.6,B1
ACALL DELAY10延时10毫秒消抖
JB P3.6,C1
JNB P3.6,$等待按键松开
CPL F0
ZT1: MOV P3,#0FFH对P3口初始化,设置为高电平,用于按键输入
JB P3.6,$循环判断开始按钮K1是否按下?
ACALL DELAY10延时10毫秒触点消抖
JB P3.6,ZT1如果是干扰就返回
JNB P3.6,$等待按键松开
LCALL DPLOP1
B1: JB P3.7,LOOP1
ACALL DELAY10延时10毫秒消抖
JB P3.7,B1
JNB P3.7,$等待按键松开
AJMP OVER
LOOP1: DJNZ R3,TIME1 2毫秒循环执行250次,时间约0.5秒
DJNZ R2,JS1 循环执行2次,时间为1 秒钟
INC TEMP满一秒钟对时间加1
MOV A,TEMP
CLR C
SUBB A,#60
JNZ GOON1判断TEMP的数值是否为60?不为60循环
ACALL OVER
RET
GN2: MOV A,#14H 设定倒计时的时间20S
MOV TEMP,A
数码管显示倒计时时间的程序
初始化
MOV P3,#0FFH对P3口初始化,设置为高电平,用于按键输入
MOV P0,#14H使显示时间为设定的倒计时时间
GOON2: MOV R2,#2
JS2: MOV R3,#250
TIME2: MOV A,TEMP 将TEMP中的十六进制数转换成10进制
MOV B,#10 10进制/10=10进制
DIV AB
MOV B_BIT,A 十位在A
MOV A_BIT,B 个位在B
MOV DPTR,#NUMTAB 指定查表启始地址
DPLOP2: MOV A,A_BIT 取个位数
MOVC A,@A+DPTR 查个位数的7段代码
MOV P0,A 送出个位的7段代码
CLR P2.5 开个位显示
ACALL DELY1显示1毫秒
SETB P2.5关闭个位显示,防止鬼影
MOV A,B_BIT 取十位数
MOVC A,@A+DPTR 查十位数的7段代码
MOV P0,A 送出十位的7段代码
CLR P2.6 开十位显示
ACALL DELY1显示1毫秒
SETB P2.6关闭十位显示,防止鬼影
插入一段判断定时过程中是否有按键输入的程序段
C2: JB P3.6,B2
ACALL DELAY10延时10毫秒消抖
JB P3.6,C2
JNB P3.6,$等待按键松开
ZT2:MOV P3,#0FFH对P3口初始化,设置为高电平,用于按键输入
JB P3.6,$循环判断开始按钮K1是否按下?
ACALL DELAY10延时10毫秒触点消抖
JB P3.6,ZT2如果是干扰就返回
JNB P3.6,$等待按键松开
B2: JB P3.7,LOOP2
ACALL DELAY10延时10毫秒消抖
JB P3.7,B1
JNB P3.7,$等待按键松开
AJMP OVER
LOOP2: DJNZ R3,TIME2 2毫秒循环执行250次,时间约0.5秒
DJNZ R2,JS2 循环执行2次,时间为1 秒钟
DEC TEMP满一秒钟对时间减1
MOV A,TEMP
JNZ GOON2判断TEMP的数值是否为0?不为0循环
ACALL OVER
RET
结束定时
OVER: AJMP START退到开机初始化状态
1毫秒延时子程序
DELY1: MOV R4,#2
D1:MOV R5,#248
DJNZ R5,$
DJNZ R4,D1
RET
10毫秒延时子程序
DELAY10: MOV R4,#20
D2:MOV R5,#248
DJNZ R5,$
DJNZ R4,D2
RET
实验板上的两位一体的数码管0~9各数字的显示代码
NUMTAB: DB 40H,79H,24H,30H,19H,12H,02H,78H,00H,10H
DPLOP1: MOV A,A_BIT 取个位数
MOVC A,@A+DPTR 查个位数的7段代码
MOV P0,A 送出个位的7段代码
CLR P2.5 开个位显示
ACALL DELY1显示1毫秒
SETB P2.5关闭个位显示,防止鬼影
MOV A,B_BIT 取十位数
MOVC A,@A+DPTR 查十位数的7段代码
MOV P0,A 送出十位的7段代码
CLR P2.6 开十位显示
ACALL DELY1显示1毫秒
SETB P2.6关闭十位显示,防止鬼影
RET
END
#include <reg51.H>
sbit P3_5 =P3^5
unsigned char code dispcode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x00}
unsigned char second
unsigned char keycnt
unsigned int tcnt
void main(void)
{
unsigned char i,j
TMOD=0x02
ET0=1
EA=1
second=0
P1=dispcode[second/10]
P2=dispcode[second%10]
while(1)
{
if(P3_5==0)
{
for(i=20i>0i--)
for(j=248j>0j--)
if(P3_5==0)
{
keycnt++
switch(keycnt)
{
case 1:
TH0=0x06
TL0=0x06
TR0=1
break
case 2:
TR0=0
break
case 3:
keycnt=0
second=0
P1=dispcode[second/10]
P2=dispcode[second%10]
break
}
while(P3_5==0)
}
}
}
}
void t0(void) interrupt 1 using 0
{
tcnt++
if(tcnt==4000)
{
tcnt=0
second++
if(second==100)
{
second=0
}
P1=dispcode[second/10]
P2=dispcode[second%10]
}
}
//12M晶振。6位共阴数码管,P0 段码,P2.0~P2.5 位控
//显示 00.00.00 最小为0.01s ,
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit P20=P2^0
sbit P21=P2^1
sbit P22=P2^2
sbit P23=P2^3
sbit P24=P2^4
sbit P25=P2^5
sbit P07=P0^7
sbit P05=P0^5
sbit KS=P1^0 //开始/暂停
sbit KC=P1^1 //清零
uchar time,xs2,xs,ge,shi,bai,qian
uchar code tab[ ]= {
0x3F,
0x06,
0x5B,
0x4F,
0x66,
0x6D,
0x7D,
0x07,
0x7F,
0x6F,
}
void delay_ms(uint ms) //1ms延时
{
uchar a
while(ms--)
for(a=123a>0a--)
}
void display()
void t0intinit( ) //定时器T0
{
TMOD=0x01
TH0=(65536-10000)/256 //10ms定时
TL0=(65536-10000)%256
EA=1
ET0=1
}
void main()
{
t0intinit( )
while(1)
{
display( )
while(!KS) //开始键
{
display( )
if(KS)
TR0=!TR0
}
while(!KC) //清零键
{
display( )
if(KC)
TR0=0
qian=0
bai=0
shi=0
ge=0
xs=0
xs2=0
}
if(ge==10)
{
ge=0
shi++
}
if(shi==6)
{
shi=0
bai++
}
if(bai==10)
{
bai=0
qian++
}
if(qian==6)
qian=0
}
}
void display( )
{
P25=0
P0=tab[xs2]
delay_ms(1)
P25=1
P24=0
P0=tab[xs]
delay_ms(1)
P24=1
P23=0
P0=tab[ge]
P07=1
delay_ms(1)
P23=1
P22=0
P0=tab[shi]
delay_ms(1)
P22=1
P21=0
P0=tab[bai]
P07=1
delay_ms(1)
P21=1
P20=0
P0=tab[qian]
delay_ms(1)
P20=1
}
void T0int( ) interrupt 1 //定时器T0中断 方式1
{
TH0=(65536-10000)/256 //10ms定时
TL0=(65536-10000)%256
xs2++
if(xs2==10)
{
xs2=0
xs++
}
if(xs==10)
{
xs=0
ge++
}
}
S3 BIT P2.6
S2 BIT P2.5
S1 BIT P2.4
CLK BIT P0.0
DAT BIT P0.1
STR BIT P0.2
BUF BIT P1.0
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP LOOP
ORG 000BH
AJMP L2
ORG 0100H
MAIN:
MOV IE,#83H
MOV TCON,#01H
MOV TMOD,#51H
MOV TH0,#0DCH
MOV TL0,#010H
MOV R0,#0
mov R3,#0
MOV R1,#0
MOV 51H,#0
L4:判断中断计数的标志位,作相应的动作
CJNE R1,#1,T4
SETB BUF
ACALL L8
CLR BUF
SETB TR0
T4:
CJNE R1,#2,T2
SETB BUF
ACALL L8
CLR TR0
T2:
CJNE R1,#3,T3
CLR BUF
ACALL L8
MOV R1,#0
MOV R0,#0
MOV R3,#0
T3:数据输出,四位输出
MOV A,R0
MOV B,#10
DIV AB
MOV R6,A
MOV A,B
SETB S2
SETB S1
SETB S3
CLR S4
ACALL L7
ACALL L8
MOV A,R6
SETB S4
CLR S3
ACALL L7
ACALL L8
MOV A,R3
MOV B,#10
DIV AB
MOV R4,A
MOV A,B
SETB S3
CLR S2
ACALL L7
ACALL L8
MOV A,R4
SETB S2
CLR S1
ACALL L7
ACALL L8
AJMP L4
L7:按位取数据输出
MOV DPTR,#TAB
MOVC A,@A+DPTR
CPL A
L5:MOV R7,#8
CLR STR
L6:8位数据的输出
RRC A
MOV DAT,C
NOP
CLR CLK
NOP
NOP
SETB CLK
DJNZ R7,L6
SETB STR
CLR STR
RET
L8:MOV R7,#50 延迟函数50.50
dip:MOV R5,#50
DJNZ R5,$等待中断
DJNZ R7, DIP
RET
L2:定时中断
INC R0
CJNE R0,#99,L3
MOV R0,#0
INC R3
CJNE R3,#60,L3
MOV R3,#0
L3:付值语句
MOV TH0,#0DCH定时初值
MOV TL0,#010H定时初值
RETI返回函数
LOOP:外部中断程序
INC R1
RETI返回主函数
TAB: DB 0F5H,05H,0E3H,67H,17H,76H,0F6H,25H
DB 0F7H,77H
END
// 51单片机 秒表,显示时间为0000—9999秒,启动、停止,(停止后再次启动复位)
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}
uchar bai,shi
uint a1,a2
sbit D1=P3^0
sbit D2=P3^1
sbit D3=P3^2
sbit D4=P3^3
sbit key=P3^5
sbit key1=P3^7
bit j
uint y
void main()
{
TMOD=0x01
TH0=(65536-10000)/256
TL0=(65536-10000)%256
EA=1
ET0=1
TR0=1
bai=0
shi=0
while(1)
{
if(key==0)
{
j=0
}
if(key1==0)
{
j=1a2=0
}
}
}
void timer0()interrupt 1
{
TH0=(65536-10000)/256
TL0=(65536-10000)%256
a1++
y++
if(a1==100)
{
a1=0
if(j==1) a2++
if(a2>=10000) a2=0
}
D1 = 1D2 = 1D3 = 1D4 = 1
if(y==1)
{
P1=table[a2%10000/1000]
D4=0
}
if(y==2)
{
P1=table[a2%1000/100]
D3=0
}
if(y==3)
{
P1=table[a2%100/10]
D2=0
}
if(y==4)
{
P1=table[a2%10]
D1=0
y=0
}
}
(1)采用定时器...,利用开发板上的按钮,...
--------
楼主应该给出你的 开发板上的 显示电路 和 按键电路。
根据要求, 秒表的设计要有三个输入端:runstop,rst和clk. runstop是开关, 按一下开始计时, 再按一下停止计时, 显示时间. 可以使用一个T触发器来实现. 当我们把T触发器的T端接高电平时, 它将实现翻转功能. 然后用输入端口runstop 来控制, 当runstop 被按一下, 一个时钟到来, T触发器就进行一次翻转. 我们也可以用D触发器来代替T触发器, 需要用一个反馈信号, 将输出的信号反馈到D端口. Rst 是复位, 当按下rst 时, 秒表的显示变为0. Clk是时钟, 实验中的时钟信号是250KHZ,为了实现秒表的正确计时功能, 需要进行2500分频. 所以clk首先就应该接到一个分频器, 然后再为其他模块提供时钟. 接着我们把秒表划分为以下几个模块:分频器, 计数器, T触发器, 扫描器, 八选一选择器, 七段译码器, 另外还有一个模块要在分, 秒和毫秒之间做一个划分(BAR). 计数器的功能是要实现毫秒,秒,分的计数,比较麻烦.我们再将它分成几个模块, 可以是六进制的计数器和十进制的计数器进行级联来实现.也可以是用100进制的计数器和60进制的计数器进行级联. 我两种方法都尝试了一下.发现后一种方法编程要复杂的多, 级联的时候可以稍微简单一些. 因为D触发器,八选一选择器是程序包里有的,所以可以不编. 把这些模块都编好了以后要做的就是把他们连在一起. 有两种方法. 一是用画图的方法, 二是用编程的方法, 用port map语句. 同样, 这两种方法我也都尝试了. 我觉得用画图的方法要简单一些.
1程序如下:分频器: library ieeeuse ieee.std_logic_1164.alluse ieee.std_logic_unsigned.allentity df is port(clkin:in std_logicdout:out std_logic)
endarchitecture behavioral of df is begin process(clkin) variable df: std_logic_vector(7 downto 0):="00000000"begin if (clkin'event and clkin='1')then if df/="11111010" then df:=df+1else df:="00000001"end ifend ifdout<=df(7)end processend behavioral扫描器: library ieeeuse ieee.std_logic_1164.alluse ieee.std_logic_unsigned.all
entity scan is port(clk:in std_logics:out std_logic_vector(2 downto 0))end scan
architecture behavioral of scan is variable scan:std_logic_vector(2 downto 0)begin process(clk) begin if(clk'event and clk='1')then scan:=scan+1end ifs<=scanend processend behavioral七段译码器: library ieeeuse ieee.std_logic_1164.all
entity bcd is port(o:in std_logic_vector(3 downto 0)q:out std_logic_vector(6 downto 0))end bcd
architecture behavioral of bcd is begin process(o) begin case o is when"0000"=>q<="0111111"when"0001"=>q<="0000110"when"0010"=>q<="1011011"when"0011"=>q<="1001111"when"0100"=>q<="1100110"when"0101"=>q<="1101101"when"0110"=>q<="1111101"when"0111"=>q<="0100111"when"1000"=>q<="1111111"when"1001"=>q<="1101111"when others=>q<="0000000"end caseend processend behavioral当然,以上的100进制和60进制计数器的设计过于复杂,可以由六进制和十进制的计数器级联代替,程序如下:六进制: library ieeeuse ieee.std_logic_1164.alluse ieee.std_logic_unsigned.allentity c6 is port(count:out std_logic_vector(3 downto 0)cout:out std_logiccin,rst,clk:in std_logic)end c6architecture behavioral of c6 is signal counter:std_logic_vector(2 downto 0)begin process(clk,rst) begin if rst='1'then counter<="000"cout<='0'elsif clk'event and clk='1' then if cin='1' then if counter="101"then counter<="000"cout<='1'else counter<=counter+"001"cout<='0'end ifend ifend ifend processcount(2 downto 0)<=countercount(3)<='0'end behavioral
十进制: library ieeeuse ieee.std_logic_1164.alluse ieee.std_logic_unsigned.all
entity c10 is port(count:out std_logic_vector(3 downto 0)cout:out std_logiccin,rst,clk:in std_logic)end c10
architecture behavioral of c10 is signal counter:std_logic_vector(3 downto 0)begin process(clk,rst) begin if rst='1'then counter<="0000"cout<='0'elsif clk'event and clk='1' then if cin='1' then if counter="1001"then counter<="0000"cout<='1'else counter<=counter+"0001"cout<='0'end ifend ifend ifend processcount<=counterend behavioral
最后用画图讲这些模块连接起来.