基于状态机的多功能时钟的设计

合集下载

基于vhdl数字闹钟设计说明书

基于vhdl数字闹钟设计说明书

毕业设计(论文)论文题目:基于VHDL的数字闹钟设计所属系部:指导老师:职称:学生姓名:班级、学号:专业:毕业设计(论文)任务书题目:基于VHDL的数字闹钟设计任务与要求:设计一个带闹钟功能的24小时计时器。

完成功能:1.计时功能:每隔1分钟计时1次,并在显示屏上显示当前时间。

2.闹钟功能:如果当前时间与设置的闹钟时间相同,扬声器发出蜂鸣声。

时间:年月日至年月日共周所属系部:学生姓名:学号:专业:指导单位或教研室:指导教师:职称:毕业设计(论文)进度计划表本表作评定学生平时成绩的依据之一。

基于VHDL的数字闹钟设计【摘要】随着EDA技术的发展和应用领域的扩大与深入,EDA技术在电子信息、通信、自动控制及计算机应用领域的重要性日益突出。

EDA技术就是依赖功能强大的计算机,在EDA工具软件平台上,对以硬件描述语言VHDL为系统逻辑描述手段完成的设计文件,自动地完成逻辑优化和仿真测试,直至实现既定的电子线路系统功能。

本文介绍了基于VHDL硬件描述语言设计的多功能数字闹钟的思路和技巧。

在Quartus 11开发环境中编译和仿真了所设计的程序,并逐一调试验证程序的运行状况。

仿真和验证的结果表明,该设计方法切实可行,该数字闹钟可以实现调时定时闹钟功能具有一定的实际应用性。

关键词:数字闹钟 FPGA VHDL Quartus IIAbstract: With the EDA technology development and expansion of application fields and in-depth, EDA technology in the electronic information, communication, automatic control and computer applications of growing importance. EDA technology is dependent on a powerful computer, the software platform in the EDA tools for the hardware description language VHDL description for the system logic means completed design documents, automatically complete the test logic optimization and simulation, electronic circuit set up to achieve the system functionality. This article describes the VHDL hardware description language based on multi-function digital alarm clock design ideas and techniques. In the Quartus 11 compiler and development environment designed to simulate the process, and one by one to debug verification process operating conditions. Simulation and verification results show that the design method is feasible, digital alarm clock can adjust the time when the alarm clock to play music with some practical application.Key words: Alarm Clock FPGA VHDL Quartus II目录1 选题背景 (6)1.1选题研究内容 (6)1.2课题研究功能课题研究功能 (6)1.3课题相关技术应用 (6)2 FPGA 简介 (8)2.1FPGA概述 (8)2.2FPGA编程原理 (8)2.3FPGA设计流程 (9)3 总体设计思想 (10)3.1基本原理 (10)3.2设计框图 (10)4 设计步骤和调试过程 (11)4.1总体设计电路 (11)4.2模块设计和相应模块程序 (12)4.3仿真及仿真结果分析 (14)4.4实验调试结果 (15)结束语 (16)文献 (17)1 选题背景1.1 选题研究内容设计一个 24 小时的闹钟,该闹钟由显示屏、数字键、TIME 键、ALARM 键、扬声器组成。

毕业设计(论文)-基于单片机多功能电子时钟的设计与仿真(含程序仿真)[管理资料]

毕业设计(论文)-基于单片机多功能电子时钟的设计与仿真(含程序仿真)[管理资料]

程序仿真等全套设计,联系153893706第1章绪论二十一世纪的今天,最具代表性的计时产品就是电子万年历,它是近代世界钟表业界的第三次革命。

第一次是摆和摆轮游丝的发明,相对稳定的机械振荡频率源使钟表的走时差从分级缩小到秒级,代表性的产品就是带有摆或摆轮游丝的机械钟或表。

第二次革命是石英晶体振荡器的应用,发明了走时精度更高的石英电子钟表,使钟表的走时月差从分级缩小到秒级。

第三次革命就是单片机数码计时技术的应用(电子万年历),使计时产品的走时日差从分级缩小到1/600万秒,从原有传统指针计时的方式发展为人们日常更为熟悉的夜光数字显示方式,直观明了,并增加了全自动日期、星期、温度以及其他日常附属信息的显示功能,它更符合消费者的生活需求!因此,电子万年历的出现带来了钟表计时业界跨跃性的进步……我国生产的电子万年历有很多种,总体上来说以研究多功能电子万年历为主,使万年历除了原有的显示时间,日期等基本功能外,还具有闹铃,报警等功能。

商家生产的电子万年历更从质量,价格,实用上考虑,不断的改进电子万年历的设计,使其更加的具有市场。

本设计为软件,硬件相结合的一组设计。

在软件设计过程中,应对硬件部分有相关了解,这样有助于对设计题目的更深了解,有助于软件设计。

基本的要了解一些主要器件的基本功能和作用。

除了采用集成化的时钟芯片外,还有采用MCU的方案,利用AT89系列单片微机制成万年历电路,采用软件和硬件结合的方法,控制LED数码管输出,分别用来显示年、月、日、时、分、秒,其最大特点是:硬件电路简单,安装方便易于实现,软件设计独特,可靠。

AT89C52是由ATMEL公司推出的一种小型单片机。

95年出现在中国市场。

其主要特点为采用Flash存贮器技术,降低了制造成本,其软件、硬件与MCS-51完全兼容,可以很快被中国广大用户接受。

本文介绍了基于AT89C52单片机设计的电子万年历。

选题背景及研究的目的与意义设计的目的电子钟已成为人们日常生活中必不可少的物品,广泛用于个人家庭以及车站码头、剧院、办公室等公共场所,给人们的生活、学习、工作、娱乐带来了极大的方便。

用Verilog语言编写的多功能数字钟

用Verilog语言编写的多功能数字钟
四. 总结体会
这次的闹钟电路设计和多功能数字钟有一些相似的地方,不同在于整体构思和细
节上要求的差异。
构思根据要求采用的是状态机设计方法。从一个状态进入另一个状态最适合这个
设计了。细节上和数字钟也有很大的差异。中间的控制逻辑有时候需要反馈。前
后都是有联系的,并不是独立存在的。
本次设计基本上完成的所以的要求,但是由于时间紧急,一些细节并不是很完美,
分频器的作用是对 50Mhz 的系统时钟信号进行分频,得到频率为 1hz 的信号,
作为时钟的输入信号。
2
2.控制器和计数器 控制器的作用是,调整小时和分钟的值,并能实现清零功能。计数器的
作用是实现分钟和秒钟满 60 进 1,小时则由 23 跳到 00。当到达 59 分 55 秒的时 候,LED 灯会闪烁来进行报时。
end 2:
begin state<=2; s=1;
end 3:
begin s=0; if(k1==0) //时调整
7
begin
if(nz_h_l==3)
begin
nz_h_l=0;
if(nz_h_h==2)nz_h_h=0;
else nz_h_h=nz_h_h+1;
end
else nz_h_l=nz_h_l+1;
end
else if(k3==0) finish=1;
//设置完成
else if(k4==0) spker_en=1; //停止声响
end
8
4: begin s=0; if(k4==0) begin on_off<=!on_off;state=0;end end
endcase end end endmodule 3.显示器 显示器的作用是将时:分的值在数码管上依次显示出来。从分频器输出的 1Khz 的信号作为数码管的扫描信号。SEL 表示 6 个数码管选择位,它的取值表示八个 数码管,从左至右依次是 111~000。seg 表示七段数码管,它的取值决定特定位 数上显示的数字。

多功能数字钟电路设计课程设计论文

多功能数字钟电路设计课程设计论文

电子技术课程设计报告——多功能数字钟电路设计目录一、任务及要求.......................................................... - 1 -(一)设计要求...................................................... - 1 - (二)设计指标...................................................... - 1 -二、数字钟的构成........................................................ - 1 -三、单元电路的设计...................................................... - 2 -(一)秒脉冲产生电路................................................ - 2 - (二)计数器电路.................................................... - 5 - (三)译码显示电路.................................................. - 7 - (四)校时、校分电路............................................... - 10 - (五)整点报时电路................................................. - 11 - (六)闹钟电路..................................................... - 11 -四、元器件清单......................................................... - 12 -五、总电路图........................................................... - 13 -六、电路仿真........................................................... - 14 -(一)开始状态..................................................... - 14 - (二)校时、校分功能............................................... - 14 - (三)满六十秒向分钟进位状态....................................... - 15 - (四)满六十分向小时进位........................................... - 15 - 七、个人小结........................................................... - 16 -一、任务及要求(一)设计要求(1)利用中规模数字集成器件设计、实现所需电路。

推荐-多功能计时电路的设计数字钟的实验设计 精品

推荐-多功能计时电路的设计数字钟的实验设计 精品

实验1多功能计时电路的设计——数字钟1.1 实验目的1.通过实验掌握十进制加法计数、译码、显示电路的工作过程。

2.通过实验深入掌握电路的分频原理和数字信号的测量方法。

3.熟悉集成电路构成的计数、译码、显示器件的外部功能及其使用方法。

1.2 实验要求1.秒信号发生电路:为计时器提供秒信号2.计时电路:完成0分00秒~9分59秒的计时功能。

3.清零电路:具有开机自动清零功能;在任何时候,按动清零开关,可进行计时器手动清零。

4.译码显示电路:显示计时电路产生的数字信息。

5.系统级联调试:将以上电路进行级联完成计时器的所有功能。

1.3 实验原理及框图图1.1 三位计时器示意图计时电路示意图如图1.1所示,计时电路完成计时功能,并且将计时结果传送至显示电路,进而实现显示功能。

原理框图如图1.2所示,主要由计时电路,秒信号发生电路,清零电路和译码显示电路组成。

计时电路在秒信号的作用下,产生0:00~9:59的循环计时,清零电路控制计时电路的清零端,实现时钟的清零,最终将计时电路的输出送至译码显示电路,实现时钟的显示。

图1.2 数字钟的原理框图1.4 单元电路设计1.秒信号发生电路图1.3 秒信号发生电路秒信号发生电路为计时电路提供驱动信号,电路原理如图1.3所示。

为提供较为精确的秒信号,本设计中振荡电路采用215Hz 的石英晶体管为主体的晶振电路,并作为电路的秒信号源。

由于振荡电路产生的源信号为215Hz ,而秒的基准信号频率为1Hz ,则需要对215Hz 信号进行分频,得到1Hz 信号。

分频器采用CD4060和74LS74来实现,CD4060为14位二进制串行计数器,各管脚功能如表1.1所示,功能表如表1.2所示。

虽然CD4060内部有14级由T 触发器构成的二分频器,但实际输出端只有10个:Q 4~Q 10、Q 12~Q 14。

Q 1~Q 3以及Q 11并不引出。

CP 1̅̅̅̅、CP 0̅̅̅̅̅、CP 0为晶振电路的引出端,需接外部石英晶体。

多功能数字闹钟电路设计实验报告

多功能数字闹钟电路设计实验报告

多功能数字闹钟电路设计实验报告
实验目的:设计一个多功能数字闹钟电路,能够显示时间、设定并响起闹铃。

实验原理:本实验采用数字集成电路实现数字显示和闹铃功能。

数字显示部分采用BCD到七段数码管解码器74LS47和共阴
七段数码管进行实现,闹铃部分采用555定时器集成电路作为发生器,通过驱动蜂鸣器发出声音。

实验仪器:多功能数字闹钟电路实验箱、数字集成电路
74LS47、七段数码管、555定时器集成电路、蜂鸣器、电源、
示波器等。

实验步骤:
1. 按照电路图连接电路。

将74LS47连接到七段数码管,将
555定时器连接到蜂鸣器和电路中相应的电源和地线。

2. 上电并调节电路供电电压。

3. 设定时间。

通过拨动开关和按钮进行时间的设定。

4. 切换闹钟状态。

通过开关切换闹钟的开启和关闭状态。

5. 监测闹钟时间。

借助示波器调整闹钟时间的精度。

6. 监测闹钟声音。

确认蜂鸣器发出的声音符合要求。

实验结果:实验中,我们成功设计并调试出了一个多功能数字闹钟电路。

通过拨动开关和按钮可以设定时间,并且可以通过切换开关来设置闹钟的开启和关闭状态。

实验中监测到的闹钟时间和声音都符合预期要求。

结论:通过本次实验,我们成功设计了一个多功能数字闹钟电路,实现了时间显示和闹铃功能。

实验结果显示该电路的性能良好,具有实用价值。

在实验中我们也学到了关于数字集成电路和定时器集成电路的使用和调试方法。

使用状态机做时钟产生电路-独特却又最为精准(CPU设计中常用方法)

使用状态机做时钟产生电路-独特却又最为精准(CPU设计中常用方法)

使用状态机做时钟产生电路-独特却又最为精准(CPU设计中常用方法)使用状态机做时钟产生电路-独特却又最为精准(CPU设计中常用方法)介绍一款时钟发生器--独特却又最为精准(CPU设计中常用方法)时钟发生器clkgen 利用外来时钟信号clk 来生成一系列时钟信号clk1、fetch、alu_clk 送往CPU的其他部件。

其中fetch是外来时钟clk 的八分频信号。

利用fetch的上升沿来触发CPU控制器开始执行一条指令,同时fetch信号还将控制地址多路器输出指令地址和数据地址。

clk1信号用作指令寄存器、累加器、状态控制器的时钟信号。

alu_clk 则用于触发算术逻辑运算单元。

module clk_gen (clk,reset,clk1,clk2,clk4,fetch,alu_clk);input clk,reset;output clk1,clk2,clk4,fetch,alu_clk;wire clk,reset;reg clk2,clk4,fetch,alu_clk;reg[7:0] state;parameter S1 = 8'b00000001,S2 = 8'b00000010,S3 = 8'b00000100,S4 = 8'b00001000,S5 = 8'b00010000,S6 = 8'b00100000,S7 = 8'b01000000,S8 = 8'b10000000,idle = 8'b00000000;assign clk1 = ~clk;always @(negedge clk)if(reset)beginclk2 <= 0;clk4 <= 1;fetch <= 0;alu_clk <= 0;state <= idle;endelsebegincase(state)S1:beginclk2 <= ~clk2;alu_clk <= ~alu_clk;state <= S2;endS2:beginclk2 <= ~clk2;clk4 <= ~clk4;alu_clk <= ~alu_clk;state <= S3;endS3:beginclk2 <= ~clk2;state <= S4;endS4:beginclk2 <= ~clk2;clk4 <= ~clk4;fetch <= ~fetch;state <= S5;endS5:beginclk2 <= ~clk2;state <= S6;endS6:beginclk2 <= ~clk2;clk4 <= ~clk4;state <= S7;endS7:beginclk2 <= ~clk2;state <= S8;endS8:beginclk2 <= ~clk2;clk4 <= ~clk4;fetch <= ~fetch;state <= S1;endidle: state <= S1;default: state <= idle;endcaseendendmodule//--------------------------------------------------------------------------------由于在时钟发生器的设计中采用了同步状态机的设计方法,不但使clk_gen模块的源程序可以被各种综合器综合,也使得由其生成的clk1、clk2、clk4、fetch、alu_clk 在跳变时间同步性能上有明显的提高,为整个系统的性能提高打下了良好的基础。

电子综合设计多功能数字钟报告

电子综合设计多功能数字钟报告

电子综合设计多功能数字钟报告报告内容如下:一、设计目的和原理多功能数字钟是一种能够显示时间,并具有闹钟、计时、倒计时等功能的电子设备。

本设计的目的是通过FPGA实现一个多功能数字钟的功能,以实现时间的显示和闹钟的设置功能。

二、设计方案和实现1.硬件设计方案:本设计使用FPGA作为主控芯片,使用七段数码管作为显示器,通过与FPGA的IO口连接来实现时间的显示功能。

同时,使用按键作为输入进行功能的选择和设置。

2.硬件连接:将FPGA的IO口连接到七段数码管的控制端,通过IO口输出相应的数字信号来控制数码管的亮灭。

将按键连接到FPGA的IO口,通过IO口输入按键的信号。

此外,还需要连接一个晶振电路来提供时钟信号。

3.软件设计方案:本设计使用VHDL语言进行程序设计,通过状态机来实现多功能数字钟的功能。

具体实现包括时间的显示、闹钟的设置和启动、计时和倒计时功能的实现。

通过按键的输入来切换不同的状态,实现不同功能的切换和设置。

4.软件实现具体步骤:(1)定义状态机的状态,包括时间显示、闹钟设置、计时和倒计时等状态。

(2)在时间显示状态下,通过FPGA的IO口输出相应的数字信号来控制七段数码管的亮灭,实现时间的显示。

(3)在闹钟设置状态下,通过按键的输入来设置闹钟时间,并将设置好的时间保存在寄存器中。

(4)在计时和倒计时状态下,通过按键的输入来实现计时和倒计时功能,并通过七段数码管的显示来实时显示计时和倒计时的时间。

以下为本设计的完整程序代码:```vhdl--时钟频率--定义状态signal state : state_type;--定义时钟、按键和数码管信号signal clk : std_logic;signal key : std_logic_vector(1 downto 0);signal seg : std_logic_vector(6 downto 0);--闹钟时间寄存器signal alarm_hour_reg : std_logic_vector(5 downto 0);signal alarm_min_reg : std_logic_vector(5 downto 0);--计时和倒计时寄存器signal count_up_reg : std_logic_vector(23 downto 0); signal count_down_reg : std_logic_vector(23 downto 0); signal count_down_flag : std_logic := '0';beginclock : processbeginwhile true loopclk <= '0';wait for 10 ns;clk <= '1';wait for 10 ns;end loop;end process;key_scan : process(clk)beginif rising_edge(clk) thenkey <= key_scan_func; -- 按键扫描函数end if;end process;fsm : process(clk, key)beginif rising_edge(clk) thencase state isif key = "10" then -- 第一个按键按下state <= set_alarm;elsif key = "01" then -- 第二个按键按下state <= count_up;end if;when set_alarm =>seg <= set_alarm_func; -- 闹钟设置函数if key = "00" then -- 两个按键同时按下elsif key = "01" then -- 第一个按键按下state <= count_up;end if;when count_up =>seg <= count_up_func; -- 计时函数if key = "00" then -- 两个按键同时按下elsif key = "10" then -- 第二个按键按下state <= count_down;count_down_flag <= '1';end if;when count_down =>seg <= count_down_func; -- 倒计时函数if key = "00" then -- 两个按键同时按下count_down_flag <= '0';elsif key = "01" then -- 第一个按键按下state <= count_up;count_down_flag <= '0';end if;end case;end if;end process;--数码管信号和显示模块的连接display : entity work.seg_displayport mapclk => clk,seg => segend architecture;```四、总结与展望通过FPGA实现多功能数字钟的设计,在硬件和软件的配合下,实现了时间的显示和闹钟的设置功能。

多功能时钟流程图

多功能时钟流程图

多功能时钟‎流程图一. 功能确认● 时钟功能:1. 时钟显示小‎时和分钟2. 用户可以通‎过按键调整‎时钟的时间‎3. 无论当前时‎钟是否在前‎台显示,时钟始终是‎运行的。

● 定时闹铃功‎能:1. 用户可以通‎过按键设置‎闹铃时间(小时和分钟‎),设置完成后‎可以按确定‎键退出设置‎。

2. 当系统时钟‎的时间等于‎预设的闹铃‎时间时,系统蜂鸣器‎响5秒钟。

3. 用户可以设‎置两个闹铃‎。

● 秒表功能:1. 用户可以通‎过按键进入‎秒表功能,也可以退出‎秒表状态。

2. 秒表高2位‎显示秒,低2位显示‎百分之一秒‎。

3. 可以通过按‎键暂停、(继续)运行秒表,可以通过按‎键对秒表清‎零。

二. 状态分析及‎模块分割根据以上的‎分析,系统共有三‎个大的功能‎:时钟、设置定时、秒表,各个功能之‎间可以通过‎按键来切换‎,且各个功能‎内部仍需要‎使用按键来‎处理,故可以考虑‎将系统定义‎为三个状态‎(statu ‎s ):时钟状态、设置定时状‎态、秒表状态。

显然,同一个按键‎在不同状态‎下的功能是‎不一样的。

这样,在某种状态‎下,按下某个按‎键,代表唯一确‎定的含义。

这种处理方‎法可以称为‎“状态—按键”法。

这样我们可‎以把程序对‎应地分成以‎下三个任务‎模块。

这个流程就‎可以作为主‎流程(main ()函数),当然,A 、B 、C 三框内部‎的流程仍(处理时钟状‎态下的所有‎事务)(处理设置闹‎铃状态下的‎所有事务)(处理秒表状‎态下的所有‎事务)有‎待于细化。

三.详细设计A框内部要‎处理的事务‎见第一部分‎:功能确认。

在此,为了完成时‎钟调整功能‎,我们可以定‎义K ey_‎2为小时调‎整键,Key_3‎为分钟调整‎键,每次按下键‎,小时数或分‎钟数加1。

当然,当用户没有‎按键的时候‎,我们还得经‎常保持显示‎屏上的时间‎刷新。

A框:时钟状态下‎的处理流程‎:B框要处理‎的功能是设‎置定时闹铃‎的事务,这里需要预‎设闹铃时间‎,同样可以定‎义Key_‎2为小时预‎设键,Key_3‎为分钟预设‎键,而Key_‎1则负责状‎态切换,当我们预设‎好时间之后‎,按下Key‎_1,就算完成了‎闹铃预设,让系统离开‎当前状态,转到秒表状‎态上去。

多功能数字钟电路设计

多功能数字钟电路设计

多功能数字钟电路设计
1.时钟显示:设计一个数字时钟显示电路,可以显示当前的时间(小
时和分钟)。

可以使用七段显示器来显示数字。

2.闹钟功能:设计一个闹钟功能,可以设置闹钟时间,并在到达闹钟
时间时发出提示声音或闹铃。

3.温度显示:设计一个温度传感器电路,并将当前温度显示在数字时
钟上。

4.日历功能:设计一个日历功能,可以显示当前的日期和星期。

5.定时器功能:设计一个定时器功能,可以设置一个特定的时间间隔,并在到达时间间隔时发出提示声音或闹铃。

6.闹钟休眠功能:设计一个闹钟休眠功能,可以设置一个特定的时间
间隔,在此时间间隔内按下按钮可以将闹钟功能暂时关闭。

7.闹钟重复功能:设计一个闹钟重复功能,可以设置一个特定的时间
间隔,使闹钟在每天相同的时间段重复响铃。

8.亮度调节功能:设计一个亮度调节功能,可以调整数字时钟的显示
亮度。

这些功能可以根据需求进行组合设计,可以使用逻辑门、计数器、显
示器驱动器、温度传感器、按钮等元件来完成电路设计。

用verilog-HDL多功能数字钟

用verilog-HDL多功能数字钟

用verilog-HDL多功能数字钟Verilog HDL实验报告基于Verilog HDL语言的多功能数字钟设计一、试验目的设计一个有如下功能的数字钟:(1)计时功能:包括时、分、秒。

(2)定时与闹钟功能:能在所设定的时间发出铃音。

(3)校时功能:对小时、分钟和秒钟进行手动校时。

(4)整点报时功能:每到整点能够发出“嘀嘀嘀嘀嘟”四短一长的报时。

二、试验原理ALERT HOUR[7..0]MIN[7..0]SEC[7..0]LD_ALERT LD_HOUR LD_MINCLK CLK_1K MODE TURN CHANGEclockCLK CLK_1K MODE TURN CHANGEALERTHOUR[7..0]MIN[7..0]SEC[7..0]LD_ALERT LD_HOUR LD_MIN多功能数字钟端口示意图数字钟设有五个输入端,分别为时钟输入(CLK )、模式(MODE )、产生声音的时钟信号(CLK_1K )、切换(TURN )和调时(CHANGE )键。

输出共七个,其中HOUR[7..0]、MIN[7..0]和SEC[7..0]采用BCD 计数方式,分别驱动2个数码管。

硬件电路原理图如下:三、试验内容1. 代码/*信号定义:clk: 标准时钟信号,其频率为4Hz;clk_1k:产生闹铃声、报时音的时钟信号,其频率为1024Hz;mode:功能控制信号;为0:计时功能;为1:闹钟功能;为2:手动校时功能;turn:接按键,在手动校时功能时,选择是调整小时还是分钟;若长时间按住改建,还可使秒信号清零,用于精确调时;change: 接按键,手动调整时,每按一次,计数器加1;如果长按,则连续快速加1,用于快速调时和定时;hour,min,sec:此三信号分别输出并显示时、分、秒信号,皆采用BCD码计数,分别驱动6个数码管显示时间;alert:输出到扬声器的信号,用于产生闹铃音和报时音;闹铃音为持续20秒的急促的“嘀嘀嘀”音,若按住“change”键,则可屏蔽该音;整点报时音为“嘀嘀嘀嘀嘟”四短一长音;LD_alert:接发光二极管,指示是否设置了闹钟功能;LD_hour:接发光二极管,指示当前调整的是小时信号;LD_min:接发光二极管,指示当前调整的是分钟信号*/moduleclock(clk,clk_1k,mode,change,turn,alert,hour,min,sec,LD_alert,LD_hour,LD_mi n);input clk,clk_1k,mode,change,turn;output alert,LD_alert,LD_hour,LD_min;output[7:0] hour,min,sec;reg[7:0] hour,min,sec,hour1,min1,sec1,ahour,amin;reg[1:0] m,fm,num1,num2,num3,num4;reg[1:0] loop1,loop2,loop3,loop4,sound;reg LD_hour,LD_min;reg clk_1Hz,clk_2Hz,minclk,hclk;reg alert1,alert2,ear;reg count1,count2,counta,countb;wire ct1,ct2,cta,ctb,m_clk,h_clk;always @(posedge clk)beginclk_2Hz<=~clk_2Hz;if(sound==3) begin sound<=0; ear<=1; end //ear信号用于产生或屏蔽声音else begin sound<=sound+1; ear<=0; endendalways @(posedge clk_2Hz) //由4Hz的输入时钟产生1Hz的时基信号clk_1Hz<=~clk_1Hz;always @(posedge mode) //mode信号控制系统在三种功能间转换begin if(m==2) m<=0; else m<=m+1; endalways @(posedge turn)fm<=~fm;always //产生count1,count2,counta,countb四个信号begincase(m)2:begin if(fm)begin count1<=change; {LD_min,LD_hour}<=2; endelsebegin counta<=change; {LD_min,LD_hour}<=1; end{count2,countb}<=0;end1:begin if(fm)begin count2<=change; {LD_min,LD_hour}<=2; endelsebegin countb<=change; {LD_min,LD_hour}<=1; end{count1,counta}<=2'b00;enddefault:{count1,count2,counta,countb,LD_min,LD_hour}<=0;endcaseendalways @(negedge clk) //如果长时间按下“change”键,则生成“num1”信号用于连续快速加1if(count2) beginif(loop2==3) num2<=1;elsebegin loop2<=loop2+1; num2<=0;endendelse begin loop2<=0; num2<=0; endalways @(negedge clk) //产生num2信号if(count1) beginif(loop3==3) num3<=1;elsebegin loop3<=loop3+1; num3<=0; endendelse begin loop3<=0; num3<=0; endalways @(negedge clk)if(counta) beginif(loop4==3) num4<=1;elsebegin loop4<=loop4+1; num4<=0; endendelse begin loop4<=0; num4<=0; endassign ct1=(num3&clk)|(!num3&m_clk); //ct1用于计时、校时中的分钟计数assign ct2=(num1&clk)|(!num1&count2); //ct2用于在定时状态下调整分钟信号assign cta=(num4&clk)|(!num4&h_clk); //cta用于计时、校时中的小时计数assign ctb=(num2&clk)|(!num2&countb); //ctb用于在定时状态下调整小时信号always @(posedge clk_1Hz) //秒计时和秒调整进程if(!(sec1^8'h59)|turn&(!m))beginsec1<=0;if(!(turn&(!m))) minclk<=1;end//按住“turn”按键一段时间,秒信号可清零,该功能用于手动精确调时else beginif(sec1[3:0]==4'b1001)begin sec1[3:0]<=4'b0000; sec1[7:4]<=sec1[7:4]+1; endelse sec1[3:0]<=sec1[3:0]+1; minclk<=0;endassign m_clk=minclk||count1;always @(posedge ct1) //分计时和分调整进程beginif(min1==8'h59) begin min1<=0; hclk<=1; endelse beginif(min1[3:0]==9)begin min1[3:0]<=0; min1[7:4]<=min1[7:4]+1; endelse min1[3:0]<=min1[3:0]+1; hclk<=0;endendassign h_clk=hclk||counta;always @(posedge cta) //小时计时和小时调整进程if(hour1==8'h23) hour1<=0;else if(hour1[3:0]==9)begin hour1[7:0]<=hour1[7:4]+1; hour1[3:0]<=0; endelse hour1[3:0]<=hour1[3:0]+1;always @(posedge ct2) //闹钟定时功能中的分钟调节进程if(amin==8'h59) amin<=0;else if(amin[3:0]==9)begin amin[3:0]<=0; amin[7:4]<=amin[7:4]+1; endelse amin[3:0]<=amin[3:0]+1;always @(posedge ctb) //闹钟定时功能中的小时调节进程if(ahour==8'h23) ahour<=0;else if(ahour[3:0]==9)begin ahour[3:0]<=0; ahour[7:4]<=ahour[7:4]+1; endelse ahour[3:0]<=ahour[3:0]+1;always //闹铃功能if((min1==amin)&&(hour1==ahour)&&(amin|ahour)&&(!change))//若按住“change”键不放,可屏蔽闹铃音if(sec1<8'h20) alert1<=1; //控制闹铃的时间长短else alert1<=0;else alert1<=0;always //时、分、秒的现实控制case(m)3'b00: begin hour<=hour1; min<=min1; sec<=sec1; end//计时状态下的时、分、秒显示3'b01: begin hour<=ahour; min<=amin; sec<=8'hzz; end//定时状态下的时、分、秒显示3'b10: begin hour<=hour1; min<=min1; sec<=8'hzz; end//校时状态下的时、分、秒显示endcaseassign LD_alert=(ahour|amin)?1:0; //指示是否进行了闹铃定时assign alert=((alert1)?clk_1k&clk:0)|alert2; //产生闹铃音或整点报时音always //产生整点报时信号alert2beginif((min1==8'h59)&&(sec1>8'h54)||(!(min1|sec1)))if(sec1>8'h54) alert2<=ear&clk_1k; //产生短音else alert2<=!ear&clk_1k; //产生长音else alert2<=0;endendmodule2. 仿真图四、小结及体会为了做多功能数字钟,我借了多本关于Verilog HDL的程序设计书。

基于-Quartus多功能数字钟设计

基于-Quartus多功能数字钟设计

基于Quartus的多功能数字钟设计该实验是利用QuartusII软件设计一个数字钟,进展试验设计和仿真调试,实现了计时,校时,校分,清零,保持和整点报时等多种根本功能,并下载到SmartSOPC实验系统中进展调试和验证。

此外还添加了显示星期,闹钟设定,秒表和彩铃等附加功能,使得设计的数字钟的功能更加完善。

一、设计要求1.设计一个数字计时器,可以完成00:00:00到23:59:59的计时功能,并在控制电路的作用下具有保持、清零、快速校时、快速校分、整点报时等根本功能。

2.具体要求如下:1)能进展正常的时、分、秒计时功能,最大计时显示23小时59分59秒。

2)分别由六个数码管显示时分秒的计时。

3)K1是系统的使能开关,K1=0正常工作,K1=1时钟保持不变。

4)K2是系统的清零开关,K2=0正常工作,K2=1时钟的分、秒全清零。

5)在数字钟正常工作时可以对数字钟进展快速校时和校分。

K3是系统的校分开关,K3=0正常工作K3=1时可以快速校分;K4是系统的校时开关,K4=0正常工作,K4=1时可以快速校时。

3.设计提高局部要求1)时钟具有整点报时功能,当时钟计到59’51〞时开场报时,在59’51〞,59’53〞, 59’55〞,59’57〞时报时频率为512Hz,59’59〞时报时频率为1KHz。

2)星期显示:星期显示功能是在数字钟界面显示星期,到计时到24小时时,星期上显示的数据进一位。

3)闹表设定:通过开关切换显示至闹钟界面,利用闹钟校时和校分开关对闹钟时间进展设定,且不影响数字钟计时。

当计时到闹钟设定时间蜂鸣器鸣叫,并响起彩铃。

4)秒表计时:通过开关切换显示至秒表界面,分秒局部是100进制的,即当值为99时向秒位进位。

4.仿真与验证用Quartus软件对设计电路进展功能仿真,并下载到实验板上对其功能进展验证。

二、工作原理数字计时器是由计时电路、译码显示电路、脉冲发生电路和控制电路等几局部组成的,控制电路按要求可由校分校时电路、清零电路和保持电路组成。

EDA课程设计 多功能数字钟设计程序清单 数字系统设计与verilog HDL(第四版) 王金明

EDA课程设计 多功能数字钟设计程序清单 数字系统设计与verilog HDL(第四版) 王金明

EDA课程设计多功能数字钟设计程序清单数字系统设计与verilog HDL(第四版)王金明/*引脚锁定基于DE2一70,芯片为EP2C70F896,信号定义如下: Clk50m: 50MHz 时钟输,mode:模式选择0:计时模式1:设置闹钟模式mcheck:手动调整时间turn:手动调整时间,在时、分之间选择change:对选中的数据调整led hourl,led_hour0,led_minul,led_minu0,led_secl,led sec0;alert: 闹钟输出ld_alert: 是否设置了闹钟ld_hour,id_min,ld_sec:在调整时,指示选中了时,分还是秒*/moduleclock(clk50m,mode,turn,change,mreset,led_hour1,led_hour0,led_minu1,led_minu0, led_sec1,led_sec0, alert,ld_alert,ld_check,ld_hour,ld_min,ld_sec);input clk50m;input mode; // key0键input turn; //keyl键input change; // key2 键input mreset; //switch0复位,低电平有效output alert; //gpioO->IOAOoutput ld_alert; //ledgO-led19output ld_check; //ledgl-led22output ld_hour; //ledr3-led13output ld_min; //ledr9-led9output ld_sec; //ledr7-led7output[6:0] led_hour1;output[6:0] led_hour0;output[6:0] led_minu1;output[6:0] led_minu0;output[6:0]led_sec1;output[6:0]led_sec0;reg [1:0] modestate;//00: 计时模式10:闹钟模式; 01:手动调整模式;11:非法模式wire nowmode;//记录当前模式,0:计时模式;1: 设置闹钟模式wire ischecking; //是否在手动调整时间assign {nowmode, ischecking}=modestate;always@(negedge mode)//两个按钮都是低电平有效begincase (modestate)2'b00 : modestate<=2'b10; //设置闹钟模式优先2'b10: modestate<=2'b01; //手动调整模式2'b01: modestate<=2'b00;default :modestate<=2'b00;endcaseendwire reset, clk_1hz;switch #(8) rmjitter(clk50m,mresetr,reset);clk50mtol genlhz (clk50m, clk_1hz) ; //生成1Hz的时钟wire [2 : 0] selcode; //对turn信号在不同模式bitsel seldecoder (nowmode, ischecking, turn, selcode, reset);wire [3:0] clocktime0,clocktimel,clocktime2,clocktime3,clocktime4,clockthre5;//计时输出的时钟数值wire clockalarmon; //整点报时的闹钟输出wire [2 : 0] counterselcode;assign counterselcode=(modestate==2'b01)?selcode:3'b000;counter_time clock_time (clk_1hz,counterselcode,~change,clocktime5,clocktime4,clocktime3,clocktime2,clock time1,clocktime0,clockalarmon,reset);wire[3:0] alarmtime0,alarmtime1,alarmtime2,alarmtime3;wire alarmon;alarm_time alarm_time ( clk_1hz , nowmode , selcode [ 2 : 1] , change ,{clocktime5, clocktime4, clocktime3, clocktime2, clocktime1},{alarmtime3, alarmtime2, alarmtime1, alarmtime0} , alarmon, reset) ;wire voiceout ;alarm alarmvoice (clk50m,{clockalarmon, alarmon} ,voiceout, raset) ;//显示输出部分assign {ld_hour,ld_min,ld_sec}=(ischecking||nowmode)?selcode:3'b000; assign alert=voiceout;reg[3:0] showout2,showout3,showout4,showout5;led led5 (showout5,led_hour1) ; //led译码显示led led4 (showout4,led_hour0) ;led led3 (showout3,led_minu1) ;led led2 (showout2,led_minu0) ;led led1 (clocktime1,led_sec1) ;led led0 (clocktime0,led_sec0) ;alwaysbegin if ( nowmode)begin showout5=alarmtime3 ; showout4=alarmtime2 ;showout3=alarmtime1; showout2=alarmtime0 ; end else beginshowout5=clocktime5; showout4=clocktime4 ;showout3=clocktime3 ; showout2=clocktime2 ; end endassign ld_alert=nowmode; assign ld_check=ischecking;endmodule/*alarm.V:闹铃模块Clk50m: 50MHz输入时钟alarmon:闹铃是否打开,2'b00:不打开:2'b01:闹钟;2'b10:整点报时ala rmoUt:闹铃声音输出*/module alarm(clk50m,alarmon,alarmout,reset);input[1:0] alarmon;input clk50m,reset;output reg alarmout;reg[15:0] counter_1k;wire clk_1k;assign clk_1k=counter_1k[4];always@(posedge clk50m)begin if (counter_1k==20) counter_1k<=0;else counter_1k<=counter_1k+1'b1; endwire ddd_du_out,ddd_out;sound_ddd_du ddd_du (clk_1k,alarmon[1] ,ddd_du_out) ;sound_ddd ddd(clk_1k,alarmon[0],ddd_out);alwaysbegin if (!reset)begin if (alarmon [0]==1'b1) //ddd,闹钟的响铃优先级更高alarmout=ddd_out ;else if (alarmon==2'b10) alarmout=ddd_du_out;else alarmout=0 ;end else alarmout=0 ;endendmodule/*alarm_time.V:闹钟时间设定模块enable:使能信号Sel:在时、分之间切换选择10:时;01:分inc:对选中的信号自增basetime:基准时钟*/module alarm_time (clk_1hz , enable, sel, inc, basetime, alarmouttime, alarm_on, reset) ;input clk_1hz,enable, inc,reset;input[1:0] sel;input[4*5-1:0] basetime;output reg alarm_on;output [4*4-1: 0] alarmouttime;reg [ 3 : 0] hour1, hour0 , minu1, minu0 ; //存储的设定时间always@ (posedge inc or posedge reset)begin if (reset) //reset=1时复位begin { hour1, hour0,minu1, minu0 } <=16'h0 ; endelse beginif (enable) beginif (sel==2'b10) //设置时begin if({hour1,hour0}==8'h23) {hour1,hour0}<=8'h00;else if (hour0==9)begin hour0<=0;hour1<=hour1+1'b1; endelse hour0<=hour0+1'b1;endelse if(sel===2'b01)//设置分begin if({minu1,minu0}==8'h59) {minu1,minu0}<=8'h00;else if (minu0==4'h9)begin minu0<=4'h0;minu1<=minu1+4'h1;endelse minu0<=minu0+4'h1; endelse {hour1,hour0,minu1,minu0}<=16'h0;end endendalways //闹钟开始条件beginif(({hour1,hour0,minu1,minu0}==basetime[ (4*5-1) :4]) && (basetime[3:0]<2)) alarm_on=1'b1;else alarm_on=1'b0; endassign alarmouttime={ hour1,hour0,minu1,minu0};endmodule/*counter time,v:计时模块,并留有调整接;check:调整信号,3位,分别调整时、分、秒,调整方法:将计数输出给加法器,把调整信息转换成异步置数信息,将加法器的输出作为置数值;hour1,hour0,minul, minu0, sec1,sec0:输出的计时时钟;alarmout:整点报时输出*/modulecounter_time(clk_1hz,check,inc,hour1,hour0,minu1,minu0,sec1,sec0,alarmout,reset); input clk_1hz,inc,reset;input[2:0] check;output[3:0] hour1,hour0,minu1,minu0,sec1,sec0;output reg alarmout;reg clk_1hz_md;wire [6: 0] carryclk;reg[5:0] incplus;//自增脉冲wire [5 : 0] carry; //进位时钟wire [3 : 0] adderout0,adderout1,adderout2,adderout3,adderout4,adderout5;wire [3 : 0] timerout0,timerout1,timerout2,timerout3,timerout4,timerout5; hexcounter counter_sec0(carryclk[0],reset,4'd9,4'b0,timerout0,carry[0]); hexcounter counter_sec1(carryclk[1],reset,4'd5,4'b0,timerout1,carry[1]); hexcounter counter_minu0(carryclk[2],reset,4'd9,4'b0,timerout2,carry[2]); hexcounter counter_minu1(carryclk[3],reset,4'd5,4'b0,timerout3,carry[3]);wire [3:0] hour0max;assign hour0max=(timerout5==4'h2)?(4'h3) : (4'h9);hexcounter counter_hour0(carryclk[4],reset,hour0max,4'b0,timerout4,carry[4]); hexcounter counter_hour1(carryclk[5],reset,4'd2,4'b0,timerout5,carry[5]);//每个计时器的时钟,由前级进位和自堦脉冲相加得到assign carryclk[0]=(check==4'h0) ? clk_1hz_md:incplus[0];assign carryclk[1]=carry[0]|incplus[1];assign carryclk[2]=(check==4'h0) ? carry[1]:incplus[2];assign carryclk[3]=carry[2]|incplus[3];assign carryclk[4]=(check==4'h0) ? carry[3]:incplus[4];assign carryclk[5]=carry[4]|incplus[5];always //对异步置位信号进行解码begin case (check)3 'b001: begin clk_1hz_md=0;incplus={5 'b00000, inc} ;end3 'b010 : begin clk_1hz_md=0;incplus={3'b000,inc,2'b00};end3 'b100 : begin //在正常的调节状态中clk_1hz_md=0;incplus={1'b0, inc, 4'b000};enddefault:begin incplus=6'b000000;clk_1hz_md=clk_1hz ;endendcaseendalways begin if (((reset|check)==0)&&(timerout3==0) && (timerout2==0) && (timerout1<2)) alarmout=1;//时间小于20秒的时间内else alarmout=0;endassign hour1=timerout5;assign hour0=timerout4;assign minu1=timerout3;assign minu0=timerout2;assign sec1=timerout1;assign sec0=timerout0;endmodule/*Clk50mtol.v: 50mhz 时钟分频到lhz */module clk50mtol(clk50m,clk1hz);input clk50m;output clk1hz;reg [25:0]counter_1hz;//从50mhz 分频到lhz 的计数器assign clk1hz=counter_1hz[14];//assign clk1hz=counter_1hz[25];always@ (posedge clk50m)beginif(counter_1hz==20000) counter_1hz<=0;else counter_1hz<=counter_1hz+1'b1;endendmodule/*led.v:7段数码管(led)译码显示模块datain:4位,10进制数输入ledout:7位,数码管的7段*/module led(datain,ledout);parameter INWIDTH=4;parameter OUTWIDTH=7;input[INWIDTH-1: 0] datain;output [OUTWIDTH-1:0] ledout;reg[OUTWIDTH-1:0] dataout;assign ledout=dataout;always begincase (datain)0 : dataout<=7'b1000000;1 : dataout<=7'b1111001;2 : dataout<=7'b0100100;3 : dataout<=7'b0110000;4 : dataout<=7'b0011001;5 : dataout<=7'b0010010;6 : dataout<=7'b0000010;7 : dataout<=7'b1111000;8 : dataout<=7'b0000000;9 : dataout<=7'b0010000;default : dataout<=7'b1000000;endcaseendendmodule/*switch-v:对按键开关的消抖电路,采用一个频率较低的时钟,对输入进行采样,消除抖动*/module switch(clk,keyin,keyout);parameter COUNTWIDTH=8;input clk, keyin;output reg keyout;reg [COUNTWIDTH-1: 0] counter;wire clk_use; //频率较低的时钟assign clk_use=counter [COUNTWIDTH-1];always@ (posedge clk)counter<=counter+1'b1;always@ (posedge clk_use)keyout<=keyin;endmodule/*bitsel-v:将输出解码成对时、分、秒的选择(并且分闹钟设置模式还是计时模式)Alarmmode:是否是在设置闹钟模式checkmode:是否是在调整时间模式*/module bitsel(alarmmode, checkmode, sel, selcode, reset) ;input alarmmode, checkmode, sel, reset;output reg [2:0] selcode;reg [2:0] check_code ;reg [1:0] alarm_code ;always@ (negedge sel or posedge reset)begin if (reset) check_code<=3'b000; //reset=1 复位else begincase (check_code)3 'b000: check_code<=3 'b001;3 'b001: check_code<=3 'b010;3 'b010: check_code<=3 'b100;3 'b100: check_code<=3 'b001;default: check_code<=3 'b000;endcaseendendalways@ (negedge sel or posedge reset)begin if (reset) alarm_code<=2 'b00; //低电平复位else begincase (alarm_code)2'b00 : alarm_code<=2'b01;2 'b01 : alarm_code<=2 'b10 ;2 'b10 : alarm_code<=2 'b01;default : alarm_code<=2 'b00;endcaseendendalwaysbegin if (alarmmode^checkmode) //两个当中只有1个为1 begin if (checkmode) selcode=check_code;else selcode={alarm_code,1'b0}; endelse selcode=3 'b000 ;endendmodule/*adder.v:加法器*/module adder(in1, in2, out);parameter in1width=8;parameter in2width=8;parameter outwidth=8;input [in1width-1: 0] in1;input [in2width-1: 0] in2;output[outwidth-1: 0] out;assign out=in1+in2;endmodule/*excounter-v:16进制计数的一个计数器*/module hexcounter (clk, set, max, setdata, dataout, carryout) ; input clk,set;input[3:0] max,setdata;output carryout;output[3:0] dataout;reg[3:0] counter;reg carrybit;assign carryout=carrybit;assign dataout=counter;always@ (posedge clk or posedge set)begin if (set) //set是高电平有效begin counter<=setdata;carrybit<=0 ;endelse begin if( (counter==max)||(counter>max) )begin counter<=0 ;carrybit<=1;endelse begin counter<=counter+1'b1;carrybit<=0 ;endendendendmodule/*sound_ddd.V:发出嘀嘀嘀闹铃声模块*/module sound_ddd(clk_1k, on, out);parameter soundspace=30;parameter shotstopspace=20; //20ms,两个嘀声的时间距离parameter longstopspace=50;//50ms,连续三个嘀后的时间距离input clk_1k,on;output reg out;reg sound;always@ (posedge clk_1k)begin sound<=~sound; endreg[10:0] mscount;always@ (posedge clk_1k)begin if (mscount== (soundspace*3+shotstopspace*2+longstopspace-1) )mscount<=0;else mscount<=mscount+1'b1;endalways@ (negedge clk_1k)begin if (on)begin if ( (mscount>=0) && (mscount<soundspace) ) out<=sound;else if ( (mscount>=soundspace) && (mscount< (soundspace+shotstopspace) ) )out<=0;else if ( (mscount>= (soundspace+shotstopspace) ) && (mscount< (soundspace+shotstopspace) +soundspace) )out<=sound;else if ( (mscount>= (soundspace+shotstopspace) +soundspace) && (mscount< (soundspace+shotstopspace) *2) )out<=0;else if ( (mscount>= (soundspace+shotstopspace) *2)&&(mscount< ((soundspace+shotstopspace) *2+soundspace) ) )out<=sound;else out<=0;endelse out<=0 ;endendmodule/* sound ddd du,v:发出声音嘀嘀嘀一嘟声音模块*/module sound_ddd_du (clk_1k, on, out) ;parameter SOUNDSPACE=30;parameter shotstopspace=20;//20ms,两个嘀声的时间距离parameter longsoundspace=60; //嘟的长度input clk_1k, on;output reg out;reg sound_di, sound_du;always@ (posedge clk_1k) sound_di<=~sound_di;always@ (posedge sound_di) sound_du<=~sound_du;reg [ 11 : 0 ] mscount ;always@ (posedge clk_1k)begin if (on)begin if (mscount< (SOUNDSPACE+shotstopspace) *3+longsoundspace+10)mscount<=mscount+1'b1;endelse mscount<=0 ;endalways@ (negedge clk_1k)begin if (on)begin if ( (mscount>=0) && (mscount<SOUNDSPACE) ) out<=sound_di;else if ( (mscount>=SOUNDSPACE) && (mscount< (SOUNDSPACE+shotstopspace) ) )out<=0 ;else if ( (mscount>= (SOUNDSPACE+shotstopspace) ) && (mscount< (SOUNDSPACE+shotstopspace) +SOUNDSPACE) )out<=sound_di ;else if ( (mscount>= (SOUNDSPACE+shotstopspace) +SOUNDSPACE) && (mscount< (SOUNDSPACE+shotstopspace) *2) )out<=0;else if ( (mscount>= (SOUNDSPACE+shotstopspace) *2) && (mscount< ( (SOUNDSPACE+shotstopspace) *2+SOUNDSPACE) ) )out<=sound_di;else if ( (mscount>= (SOUNDSPACE+shotstopspace) *2+SOUNDSPACE) && (mscount< (SOUNDSPACE+shotstopspace) *3) )out<=0;else if ( (mscount>= (SOUNDSPACE+shotstopspace) *3) && (mscount< ( (SOUNDSPACE+shotstopspace) *3+longsoundspace) ) )out<=sound_du;else out<=0;endendendmodule。

9基于状态机的设计

9基于状态机的设计
基于状态机的设计
状态机可以认为是组合逻辑和寄存器逻辑 的特殊组合,它一般包括两个部分:组合逻 辑部分和寄存器部分。 米里型(Mealy):输出是当前状态和当前 输入的函数。 摩尔型(Moore):输出只是当前状态的函 数。
摩尔型(Moore)
moore状态机比较容易用数学的方式来分析,因 此被更广泛的用在代数状态机理论中(algebraic FSM theory)。
PROCESS REG 时序进程 current_state next_state PROCESS COM 组合进程 LOCK
PROCESS LATCH 锁存器
LOCK1 CLK 模拟信号输入
AD574
CS A0 RC K12/8 STATUS D[11..0]
RAM
OR
FIFO
AD574采样状态机工作时序
米里型(Mealy)
Mealy 状态机通常可以有更少的状态变量,因此 在工程领域有更为广阔的应用, 状态变量越少,则所需的存储单元就越少。

状态A 进入100k量程 reset=1;std_f_sel=00; cntlow=1 clear=1 cntover=1 状态B 100k量程测量 reset=0;std_f_sel=00; cntover=1 状态D 10k量程测量 reset=0;std_f_sel=01; cntover=1 状态E 1k量程测量 reset=0;std_f_sel=11; cntlow=1
状态C 开始进入10k量程 reset=1;std_f_sel=01;
cntlow=1 状态E 进入1k量程 reset=1;std_f_sel=11;
状态编码
状态编码主要有5种编码方式: 1.顺序编码。 2.格雷码编码。 3.单热编码(one-hot)。 4.随机编码。 5.自动编码(面积最小化)。

EDA电子钟多功能数字时钟课程设计(含代码)[优秀]

EDA电子钟多功能数字时钟课程设计(含代码)[优秀]

多功能数字时钟设计说明:1.系统顶层框图:各模块电路功能如下:1.秒计数器、分计数器、时计数器组成最基本的数字钟,其计数输出送7段译码电路由数码管显示.2.基准频率分频器可分频出标准的1HZ频率信号,用于秒计数的时钟信号;分频出4HZ频率信号,用于校时、校分的快速递增信号;分频出64HZ频率信号,用于对按动“校时”,“校分”按键的消除抖动.2.多功能数字钟结构框图:一、系统功能概述已完成功能1.完成时/分/秒的依次显示并正确计数,利用六位数码管显示;2.时/分/秒各段个位满10正确进位,秒/分能做到满60向前进位,有系统时间清零功能;3.定时器:实现整点报时,通过扬声器发出高低报时声音;4.时间设置,也就是手动调时功能:当认为时钟不准确时,可以分别对分/时钟进行调整;5.闹钟:实现分/时闹钟设置,在时钟到达设定时间时通过扬声器响铃.有静音模式.待改进功能:1. 系统没有万年历功能,正在思考设计方法.2. 应添加秒表功能.二、系统组成以及系统各部分的设计1.时计数模块时计数模块就是一个2位10进制计数器,记数到23清零.VHDL的RTL描述如下:----cnt_h.vhdlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity cnt_h isport(en,clk,clr:in std_logic;dout:out std_logic_vector(7 downto 0);c:out std_logic);end cnt_h;architecture rtl of cnt_h issignal t:std_logic_vector(7 downto 0);beginprocess(en,clk,clr)variable t:std_logic_vector(7 downto 0);beginif en='1' then --异步使能if clk 'event and clk='1' thent:=t+1;if t(3 downto 0)=X"A" then --个位等于10则十位加1t(7 downto 4):=t(7 downto 4)+1;t(3 downto 0):=X"0"; --个位清零end if;if t>X"23" then --大于23清零t:=X"00";end if;end if;if clr='1' then --异步清零t:=X"00";end if;end if;dout<=t;end process;end rtl;时计数器模块仿真波形如下从仿真波形可知,当计数到23时,下一个时钟上升沿到来时就清零了,符合设计要求.时计数模块框图如下2.分及秒计数模块分及秒计数模块也是一个2位10进制计数器,记数到59清零.VHDL的RTL描述如下:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity cnt_s isport(en,clk,clr:in std_logic;dout:buffer std_logic_vector(7 downto 0);c:out std_logic);end cnt_s;architecture rtl of cnt_s isbeginprocess(en,clk,clr)beginif en='1' thenif clr='1' then --异步清零dout<=X"00";elsif clk 'event and clk='1' thenif dout(3 downto 0)<9 thendout(3 downto 0)<=dout(3 downto 0)+1;c<='0';elsif dout(7 downto 4)<5 thendout(3 downto 0)<=X"0";dout(7 downto 4)<=dout(7 downto 4)+1;elsedout<=X"00";c<='1';end if;end if;else dout<="ZZZZZZZZ";end if;end process;end rtl;分和秒计数器模块仿真波形如下从仿真波形可知,当计数到59时,下一个时钟上升沿到来时就清零了,并且产生进位信号,符合设计要求.分和秒计数模块框图如下3.按键消抖动模块按键消抖动有很多方案,这里选择的是计数消抖,即只当有效电平到来后开始计数,当计数值大于一定值后再输出该有效电平,否则不输出,从而达到消抖目的. VHDL的RTL描述如下:library ieee;use ieee.std_logic_1164.all;entity haoin isport(din,clk:in std_logic;dout:out std_logic); end haoin;architecture rtl of haoin isbeginprocess(din)variable t: integer range 0 to 63:=0;beginif din='1' thenif clk 'event and clk='1'thent:=t+1;if t>10 thendout<='1';t:=t-1;else dout<='0';end if;end if;else dout<='0';t:=0;end if;end process;end rtl;library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity ring isport(clk: in std_logic;clk500: in std_logic;clk1k:in std_logic;beep:out std_logic);end ring;architecture rtl of ring isbeginprocess(clk)variable t: std_logic;variable n: integer range 0 to 15:=0;beginif clk 'event and clk='1' thent:=not t;n:=n+1;end if;if t='1' and n<11 thenbeep<=clk500;elsif n=11 thenbeep<=clk1k;else beep<='Z';end if;end process;end rtl;library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_arith.all;use IEEE.std_logic_unsigned.all;entity clock isport(SA: in std_logic;SB: in std_logic;SC: in std_logic;SD: in std_logic;clk1: in std_logic;dout: buffer std_logic_vector(23 downto 0);--seg_data:out std_logic_vector(7 downto 0);--seg_co米:out std_logic_vector(3 downto 0);beep: out std_logic--led:out std_logic_vector(3 downto 0));end entity clock;architecture rtl of clock isco米ponent cnt_s isport(en,clk,clr:in std_logic;dout:buffer std_logic_vector(7 downto 0);c:out std_logic);end co米ponent;co米ponent cnt_h isport(en,clk,clr:in std_logic;dout:buffer std_logic_vector(7 downto 0));end co米ponent;--co米ponent seg米ain is--port(clk,reset_n:in std_logic;--datain:in std_logic_vector(15 downto 0);--seg_data:out std_logic_vector(7 downto 0);--seg_co米:out std_logic_vector(3 downto 0));--end co米ponent;--co米ponent ring is--port( en: in std_logic;-- clk: in std_logic;--clk500: in std_logic;--clk1k:in std_logic;--beep:out std_logic);--end co米ponent;co米ponent haoin isport(din,clk:in std_logic;dout:out std_logic);end co米ponent;co米ponent naoling isport (h,米:in std_logic_vector(7 downto 0);clk4hzh,clk4hz米:in std_logic;sys_en,sys_rst:in std_logic;h_o,米_o: out std_logic_vector(7 downto 0);beep:out std_logic);end co米ponent;signal reg_h:std_logic_vector(7 downto 0);signal reg_米:std_logic_vector(7 downto 0);signal reg_s:std_logic_vector(7 downto 0);signal reg_米_s:std_logic_vector(7 downto 0):=X"59"; signal reg_米_米:std_logic_vector(7 downto 0):=X"59";signal reg_米_h:std_logic_vector(7 downto 0):=X"59";signal clk_h:std_logic;signal clk_米:std_logic;signal clk_s:std_logic;signal c_s :std_logic;signal c_米:std_logic;signal c_h :std_logic;signal sys_clk1:std_logic;signal sys_clk4:std_logic;signal sys_clk64:std_logic;signal sys_clk500:std_logic;signal sys_clk1k:std_logic;signal clki:integer:=750000;signal sys_rst:std_logic:='0';signal sys_en:std_logic:='1';signal clk_ring,米h:std_logic;signal SAc,SBc,SCc,SDc:std_logic;signal en_r:std_logic;signal NL_reg_h,NL_reg_米:std_logic_vector(7 downto 0);signal NL_ring:std_logic;signal sys_clk4_NL_h,sys_clk4_NL_米:std_logic;beginh:cnt_h port 米ap(en=>sys_en,clk=>clk_h,clr=>sys_rst,dout=>reg_h);米:cnt_s port 米ap(en=>sys_en,clk=>clk_米,clr=>sys_rst,dout=>reg_米,c=>c_米);s:cnt_s port 米ap(en=>sys_en,clk=>sys_clk1,clr=>SCc,dout=>reg_s,c=>c_s);--sled:seg米ain port 米ap(clk=>clk1,reset_n=>SCc,seg_data=>seg_data,seg_co 米=>seg_co米,datain=>dout(15 downto 0));--ring0:ring port 米ap(en=>en_r,clk=>clk_ring,clk500=>sys_clk500,clk1k=>sys_clk1k,beep=>beep); haoin1:haoin port 米ap( SA,sys_clk64,SAc);haoin2:haoin port 米ap( SB,sys_clk64,SBc);haoin3:haoin port 米ap( SC,sys_clk64,SCc);haoin4:haoin port 米ap( SD,sys_clk64,SDc);NL:naoling port 米ap(beep=>NL_ring,h=>reg_h,米=>reg_米,clk4hzh=>sys_clk4_NL_h,clk4hz米=>sys_clk4_NL_米,sys_en=>sys_en,sys_rst=>sys_rst,h_o=>NL_reg_h,米_o=>NL_reg_米);beep<=clk_ring and 米h;--led<=reg_s(3 downto 0);p_sys_clk:process(clk1)variable t1,t4,t64,t500,t1k:integer range 0 to 50000000;beginif clk1 'event and clk1='1' thent1:=t1+1;t4:=t4+1;t64:=t64+1;t500:=t500+1;t1k:=t1k+1;if t1=clki/2 thent1:=0;sys_clk1<=not sys_clk1;end if;if t4=clki/8 thent4:=0;sys_clk4<=not sys_clk4;end if;if t64=clki/128 thent64:=0;sys_clk64<=not sys_clk64;end if;if t500=clki/1000 thent500:=0;sys_clk500<=not sys_clk500;end if;if t1k=clki/2000 thent1k:=0;sys_clk1k<=not sys_clk1k;end if;end if;end process p_sys_clk;p_c:process(SAc,SBc,SCc,SDc)beginif SAc='1' and SDc='0' thenclk_h<=sys_clk4;elseclk_h<=c_米;end if;if SAc='1' and SDc='1' thensys_clk4_NL_h<=sys_clk4;elsesys_clk4_NL_h<='0';end if;if SBc='1' and SDc='0'thenclk_米<=sys_clk4;elseclk_米<=c_s;end if;if SBc='1' and SDc='1'thensys_clk4_NL_米<=sys_clk4;elsesys_clk4_NL_米<='0';end if;if SDc='0' thendout(7 downto 0)<=reg_s;dout(15 downto 8)<=reg_米;dout(23 downto 16)<=reg_h;elsedout(7 downto 0)<="ZZZZZZZZ";dout(15 downto 8)<=NL_reg_米;dout(23 downto 16)<=NL_reg_h;end if;end process p_c;P_ring:process(reg_米,reg_s,sys_clk1k)variable clk_ring_t:std_logic;variable t:std_logic_vector(3 downto 0);beginif reg_米=X"59" and (reg_s=X"50" or reg_s=X"52" or reg_s=X"54" or reg_s=X"56" or reg_s=X"58") thenclk_ring_t:=sys_clk500;elsif reg_米=X"00" and reg_s=X"00" thenclk_ring_t:=sys_clk1k;else clk_ring_t:='Z';end if;if NL_ring='1' thenclk_ring_t:=sys_clk1k;end if;if sys_clk1k 'event and sys_clk1k='1' thent:=t+1;end if;if t>1 then 米h<='1';end if;clk_ring<=clk_ring_t;end process p_ring;end rtl;。

多功能数字钟的设计及制作

多功能数字钟的设计及制作

多功能数字钟的设计及制作1.设计分析本次设计的数字钟具有校时功能。

我们需要在先设计一个基本的数字钟,然后在此基础上增加校时电路。

一个基本的数字钟由三个部分组成:秒脉冲产生电路,计数电路,译码显示电路,然后就是加上校时电路,一个四部分构成了本次设计的多功能数字钟,其总体方框图如图1-1图1-1 总体方框图2.设计内容2.1秒脉冲产生部分本设计使用由555定时器构成的多谐振荡器来产生1HZ的信号。

虽然此振荡器没有石英晶体稳定度和精确度高,由于设计简单而成为了设计时的首选。

只要在555定时器电路外部配上两个电阻及两个电容元件,并将某些引脚相连,就可以方便地构成多谐振荡器。

555定时器是数字脉冲产生的核心芯片,所以在了解其原理之前,我们需了解555定时器。

555定时器逻辑符号如图2-1所示:图2-1 555定时器逻辑符号管脚功能如表2-1所示:图2-2 秒脉冲电路根据原理和元件图,结合一阶电路暂态过程的三要素法,可以计算出充放电的时间,两者相加即为脉冲周期,脉冲周期的倒数即为脉冲频率。

充电过程的方程式: 2/3Vcc=Vcc+(1/3Vcc-Vcc)e(t1/RC)t1=(R1+R2)C*㏑2=0.7(R1+R2)C放电过程的方程式: 1/3Vcc=0+(2/3Vcc-0)e(t1/RC)t2=R2*C㏑2=0.7R2*C脉冲周期为: t=t1+t2=0.7(R1+2R2)C脉冲频率为: f=1/t=1.43/(R1+2R2)C令R1=15k,R2=68k,C=0. 01F,(其中0.01F的电容的作用是防干扰的)代入数据,计算得,f=0.94HZ≈1HZ基本满足实验要求。

2.2计数部分计数部分的核心芯片是74LS9074LS90是二---五---十进制异步计数器。

它有两个时钟输入CKA和CKB,其中,CPA和Q0组成一位二进制计数器,CKB和Q1Q2Q3组成五进制计数器,若将Q0与CKB相连接,时钟脉冲从CKA输入,则构成了84212BCD码十进制计数器。

多功能电子钟设计实验报告

多功能电子钟设计实验报告

GAL16V8 做 编 码器,整合入校 时电路

显示模块




记 数 模

时 钟 发 生 器
图 1:多功能数字钟整体设计
第 4 页 共 17 页
多功能电子钟设计实验报告.doc
时钟发生模块
频率振荡器(555 及外部电路):电路参数及引脚都标示在图中,由于以前做过相似电 路,在此不再赘述。
vcc
10K 欧
4. 时间计数模块…………………………………………………………….8
5. 校时模块………………………………………………………………….10
6. 扩展功能:
闹时电路………………………………………………………………. 10
仿电台报时电路………………………………………………………. 11
报整点时数电路……………………………………………………… 12
第 2 页 共 17 页
多功能电子钟设计实验报告.doc
多功能数字钟整体设计
模块名 时间显示模块
时间计数模块 校时模块 频率发生模块 扩展功能
子模块
秒六十翻一计数 分六十翻一计数 十二翻一计数
频率发生器 分频电路 闹时电路 仿电台报时电路
功能描述
完成时间的显示
秒计数 分计数
小时计数
实现电路的慢校 时 振荡发生 1KHz 的频率 将 1KHz 频率逐 步分频直至产生 1Hz 的频率 实现 7:30 报时 实现 4 高 1 低的 报时
DECLARATIONS
"INPUT PIN
CLK,HG2,HG1,HG0,CP1K PIN 1,2,3,4,5; !OE,MS2,MS1,MS0,MG3,MG2,MG1,MG0 PIN ISTYPE'REG';

基于CPLD的高频电路多功能时钟模块设计

基于CPLD的高频电路多功能时钟模块设计

组具有 “ 记忆 ”功能的寄存器,这些寄存器 的功 能是记忆有 限状态机 的内部状态 ,它们常被称为状态 寄存器 。在有 限状 态机 中,状态寄存器的的下一个状 态不仅 与输入信号有关 ,
图 1 CL P D结 构 示 意 图
据用户需要可 自行 构造逻辑功能 的数字集成 电路。它具有编 程灵活、集成度高、开发 周期短 、适用范围广、设计 成本低 、
保 密 性 强 等 特 点 , 广 泛 应用 于 电 子产 品 的 设计 和 生 产 中 。
2 有限状态机介绍
有 限状 态 机 ( i ie S a e M c i e F n t t t ah n )在 数 字 电路 设 计
现今 日益 复杂 的电路设计 ,对系统的集成度有很高的要 求,一块 高集成度 电路板上往往有几种不 同频率的同步时钟 输 出需求 。如果还 采用分离 时钟源设计 的话 ,就显得 比较麻
一 , ~ 一 一 —
{∞
— —— — — — —

』、
烦 , 系统可靠性差 。因此 ,采用高集成度的 C L 且 P D设计一个
sr f edfee t rq e c n ho co ko tusi ec mp iae ihfe u n ycrut a syt i rn e u n ys c r lc u t t o l tdhg q e c i i i h f y p nh c r c .
Ke r s CP D; o k Di i o ; i i tt a h n s y wo d : L Clc v s n F n t S a eM c i e i e
CL P D元件主要 由许多个逻辑单元组成 , 逻辑单元间 的相 互关系则 由可编程的连 线架 构,将整个逻辑 电路组合而成 。 由于 C L P D的连续式布 线结构决 定了它 的时序延迟是均匀的

多功能数字钟电路设计

多功能数字钟电路设计

多功能数字钟电路设计
多功能数字钟电路可以用来显示时间、日期、闹钟和定时器等功能。

下面是一个简单的多功能数字钟电路设计,它基于CD4511七段译码器和CD4543 BCD-七段译码器。

1. 时间显示功能
为了显示时间,我们需要使用CD4543 BCD-七段译码器。

该译码器接收来自实时时钟(RTC)模块的BCD编码输出。

RTC模块可以用来跟踪时间和日期,它通常包括一个晶体振荡器、计数器和存储器。

BCD 编码输出通过CD4543译码器转换为七段LED显示。

2. 日期显示功能
类似于时间显示功能,日期显示也需要使用RTC模块。

RTC模块可以提供年份、月份和日期的BCD编码输出。

这些编码输出通过CD4543译码器转换为七段LED显示。

3. 闹钟功能
闹钟功能可以通过计时器和比较器实现。

我们可以使用555定时器作
为计时器,它可以生成一个固定的时间间隔。

然后,我们可以使用一个比较器来比较当前时间和闹钟时间。

如果它们匹配,闹钟就会响起。

4. 定时器功能
定时器功能可以通过555定时器来实现。

我们可以设置计时器的时间间隔,并使用CD4511七段译码器来显示剩余时间。

当定时器完成计时时,它可以触发一个报警器或执行其他操作。

总之,多功能数字钟电路可以实现时间、日期、闹钟和定时器等多种功能。

这些功能可以通过RTC模块、CD4511七段译码器、CD4543 BCD-七段译码器和555定时器等元件来实现。

一种基于I~2C总线的多功能电子时钟设计

一种基于I~2C总线的多功能电子时钟设计

一种基于I~2C总线的多功能电子时钟设计
张昌平
【期刊名称】《科技信息(学术版)》
【年(卷),期】2011(000)003
【摘要】介绍了基于I2C总线的可预置、可存储多功能电子时钟系统的设计,给出了系统的硬件结构及软件体系结构。

使用有限状态机思想设计了人机界面,对I2C 总线模拟软件包VIIC进行了分析,并介绍了它在四位单片机上的移植方法。

【总页数】2页(P95-96)
【作者】张昌平
【作者单位】滨州学院物理与电子科学系,山东滨州256603
【正文语种】中文
【中图分类】TP332
【相关文献】
1.基于单片机的多功能电子时钟的设计
2.基于FPGA的多功能电子时钟设计
3.基于51单片机的多功能电子时钟设计
4.一种基于I^2C总线的新型可编程增益放大电路的设计
5.一种I^2C总线接口的串行时钟芯片
因版权原因,仅展示原文概要,查看原文内容请购买。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于状态机的多功能时钟的设计周文敏121035011 电子与通信工程一、实验目的:1.学习常见LCD 驱动程序设计,按键处理等人机对话。

2.学习状态机在监控程序中的应用。

二、实验器材(平台)1、南京师范大学物科院机电控制实验板及其附件(包括一块STC89C52RC单片机和一块1602LCD液晶显示器等);2、装有Keil uVision4单片机开发软平台和STC烧录软件STC_ISP_V483的计算机一台。

三、实验内容1、根据有限状态机的原理和1602液晶显示器以及4X4矩阵键盘的使用方法,在Keil uVision4单片机开发软平台上用C语言编写和调试程序,使该程序能分别实现时钟和闹钟的时、分的调整以及跑表等功能。

2、连接好硬件,利用STC烧录软件STC_ISP_V483下载生成的HEX文件到实验板,在硬件上实现和调试预设的时钟功能。

四、实验电路五、实验原理1、状态机状态机流程图如下所示:图1-1 流程图本时钟一共用到两个按键,R和F。

各个状态的意义:状态0:时钟正常运行;状态1:设置时钟的时;状态2:设置时钟的分;状态3:设置时钟的秒;状态4:进入闹钟设置状态;状态5:设置闹钟的时;状态6:设置闹钟的分;状态7:设置闹钟的秒;各个状态之间的转换关系如图1-1所示。

2、矩阵键盘的构成本设计所用的矩阵键盘如图2-1所示:图2-1 4*4矩阵键盘使用P3口作为数据输入输出口,采用行列反转法来扫描键盘。

采用行列反转法来读取按键,先对行线全部输出为0,然后读入列线值,如果有按键按下,则读入列线值,并输出该列线值,读取行线值,将列线和行线值组合起来返回给主程序判断按下的是什么键。

3、1602液晶显示模块液晶显示器LCD有着显示直观、耗电小、体积小及重量轻等优点,在仪器仪表、家用电器和各类电子装置中得到广泛的应用。

1602可以显示16*2个字符,其基本指令如下:六、实验结果根据图1-1的状态转换关系进行变成,并在硬件上进行实现,具体实现情况由下面的一系列图片来显示:图4-1上电启动,时钟正常开始计时。

图4-2对时间进行设置,图4-2显示的是正在对时针进行设置。

图4-3对闹钟进行设置,图4-3设置的时间为1:06:00。

图4-4当时间运行到1:06:00之后,代表闹铃的P1.1口的LED灯亮起,如图4-5所示。

图4-5图4-6所使用的开发板。

七、总结通过本次设计,我比较深入地了解了通过状态机来进行程序设计的一般方法,并且强化了51单片机编程的语法语句,通过此次的学习,在单片机的开发上我又有了进一步的提高,对单片机的理解也更加深刻。

附录一实验程序://-------------------------------------变量定义------------------------------------------#include "string.h"#include "stdio.h"#include "reg52.h"unsigned char i;//-----LCD16液晶显示控制引脚定义---------sbit E=0xb6; //老板为E=0xb4;sbit RS=0xb7;sfr lcd_dat_port=0x80; //lcd数据口unsigned char lcd_buf[32];//------按键端口定义---------------------sfr key_port=0xa0; //P2口接键盘unsigned char code key_index[16]={0xdb,0xee,0xde,0xbe, //0,1,2,30x7e,0xed,0xdd,0xbd, //4,5,6,70x7d,0xeb,0xbb,0x7b, //8,9,上,下0xe7,0xd7,0xb7,0x77};//左,右,功能,确认unsigned long time_count=0; //时间计数器unsigned long atime_count=0; //闹钟计数器bit ten_ms_flag=0;bit one_s_flag=0;bit half_s_flag=0;unsigned char mode=0; //工作模式变量//mode=0;实时时钟//mode=1;闹钟//mode=2;码表unsigned int sec=0;unsigned int min=0;unsigned int hour=0;unsigned int asec=0;unsigned int amin=12;unsigned int ahour=12;unsigned char state=0; //状态机变量//state=0: 显示实时时钟//state=1:设置小时,秒数置0//state=2: 设置分钟,秒数置0//-----------------------------变量定义结束------------------------------------------------/*----------------- 约延时100us --------------------*/delay(unsigned int dy){unsigned int ii;while(--dy)for(ii=0;ii<22;ii++) ;}//--------------写一个字节到液晶------------------------void lcd_write(bit slr,unsigned char write_dat){RS=slr;lcd_dat_port=write_dat;E=1;delay(2);E=0;}//--------------液晶初始化-----------------------------void ini_lcd(){delay(50);lcd_write(0,0x38);lcd_write(0,0x0F);lcd_write(0,0x06);lcd_write(0,0x01);delay(50);}//-------------------------液晶显示--------------------------void display(unsigned char *P_LCD) //将指针P_LCD所指内容显示{unsigned char ii;lcd_write(0,0x80); //光标复位for(ii=0;ii<16;ii++){lcd_write(1,*P_LCD);P_LCD++;}lcd_write(0,0xc0);for(ii=0;ii<16;ii++){lcd_write(1,*P_LCD);P_LCD++;}}//------定时器T0计10ms,作为最小计时单位--------void Timer0() interrupt 1{TH0=(65536-18400)/256; //22.1184MHz晶振,18432个机器周期约为10毫秒 TL0=(65536-18400)%256;time_count++;if(time_count % 100==0) one_s_flag=1; //100*10ms=1sif(time_count % 50==0) half_s_flag=1; //50*10ms=0.5s}//----------- T0初始化设置,--------------------------//功能: 设置T0定时10msvoid ini_T0(){TMOD=0x01; //T0:定时方式1,16位定时器TH0=(65536-18400)/256; //22.1184MHz晶振,18400个机器周期约为10毫秒 TL0=(65536-18400)%256;EA=1;ET0=1; //开定时器T0中断TR0=1; //计时开始}//-----------显示时间时,闪烁时分、分秒之间的分割点------void second_point_flash(){if (half_s_flag==1 && one_s_flag==1){half_s_flag=0;one_s_flag=0;lcd_buf[21]=':';}else if (half_s_flag==1 && one_s_flag==0){half_s_flag=0;lcd_buf[21]=' ';}}//-----------整形数转换为两位ASCII码-------------------void Int2Char (unsigned char IntNumber,unsigned char *P){if (IntNumber < 100){*P =IntNumber/10+'0';P++;*P= IntNumber%10 +'0';}}//-----------显示即时时间 -----------------------------void display_real_time(){//lcd_write(0,0x0c); //关光标sec=(time_count/100)%60;min=(time_count/100/60)%60;hour=(time_count/100/3600)%24;Int2Char(hour,lcd_buf+16);//时分秒转换成ASCII码,并存入lcd_buf相关单元内 Int2Char(min,lcd_buf+19);Int2Char(sec,lcd_buf+22);display(lcd_buf);if(sec==0&&min==amin&&hour==ahour){ini_lcd();strcpy(lcd_buf,"time is up ");display(lcd_buf);delay(10000); //10msini_lcd();strcpy(lcd_buf,"Real-time Clock 00-00:00 0");display(lcd_buf);delay(10000); //10ms}}void display_alarm_time(){//lcd_write(0,0x0c); //关光标Int2Char(ahour,lcd_buf+16);//时分秒转换成ASCII码,并存入lcd_buf相关单元内 Int2Char(amin,lcd_buf+19);Int2Char(asec,lcd_buf+22);display(lcd_buf);}//-------------- 线路反转法按键子程序 ----------------------unsigned char get_key(){unsigned char key1,key2,ii;key_port=0xf0;if (key_port!=0xf0){key1=key_port;delay(100); //10ms消抖动if(key1==key_port) //延时10ms后键不变{key_port=0x0f; //高低4位0,1反转key2=key_port;key1=key1|key2;for(ii=0;ii<16;ii++){if(key1==key_index[ii]){key_port=0xf0; //等待释放按键while(key_port!=0xf0);delay(100);while(key_port!=0xf0);return(ii);}}return(0xff);}else return(0xff);}else return(0xff);}//------------------移动当前光标 ----------------------void move_cursor(unsigned char position){if(position<16) lcd_write(0,0x80+position); //第一行光标闪烁else if (position<32) lcd_write(0,0x80+0x40+position-16); //第二行光标闪烁}//------------------状态转换---------------------------void state_convert(unsigned key){if(mode==0){if(state==0){if(key==13){state=1; //右箭头键move_cursor(17);}else if(key==11){mode=1;}}else if(state==1){if(key==13){state=2; //右箭头键move_cursor(20);}else if(key==11){min=(time_count/100/60)%60;hour=(time_count/100/3600)%24;if(hour<23) hour++;else hour=0;time_count=hour*3600L*100L+min*60L*100L;display_real_time();move_cursor(17);}}else if(state==2){if(key==13) state=0; //右箭头键else if(key==11)min=(time_count/100/60)%60;hour=(time_count/100/3600)%24;if(min<59) min++;else min=0;time_count=hour*3600L*100L+min*60L*100L;display_real_time();move_cursor(20);}}}else if(mode==1){if(state==0){if(key==13){state=1; //右箭头键move_cursor(17);}if(key==11){mode=0;}}else if(state==1){if(key==13){state=2; //右箭头键move_cursor(20);}else if(key==11){asec=(atime_count/100)%60;amin=(atime_count/100/60)%60;ahour=(atime_count/100/3600)%24;if(ahour<23) ahour++;else ahour=0;atime_count=ahour*3600L*100L+amin*60L*100L; display_alarm_time();move_cursor(17);}else if(state==2){if(key==13) state=0; //右箭头键else if(key==11){asec=(atime_count/100)%60;amin=(atime_count/100/60)%60;ahour=(atime_count/100/3600)%24;if(amin<59) amin++;else amin=0;atime_count=ahour*3600L*100L+amin*60L*100L;display_alarm_time();move_cursor(20);}}}}//----------------------主程序------------------------------ main(){unsigned char key;unsigned char sec,min,hour;ini_lcd();ini_T0();while(1){strcpy(lcd_buf,"Real-time Clock 00-00:00 0");display(lcd_buf);while(mode==0){key=get_key();if(key!=0xFF){state_convert(key);}if(state==0) //状态0需要不断更新显示{second_point_flash();display_real_time();}ini_lcd();strcpy(lcd_buf,"Alarm Clock 00-00:00 0"); display(lcd_buf);while(mode==1){key=get_key();if(key!=0xFF) state_convert(key);if(state==0){second_point_flash();display_alarm_time();}}ini_lcd();}}。

相关文档
最新文档