前言
- 版本 : v1.0
- Created by :jiang quan cai
- Created date :2023/07/22 21:27:08
- Language :verilog
- 注:如需实物设计联系🐧1391074994 ^^请备注来意谢谢^^
功能说明
- 实现年月日,时分秒显示;
- 实现闹钟功能–响应:蜂鸣器;
- 显示方式:lcd1602/oled12864
- FPGA平台:Altera/可移植其他平台
实物照片以及演示视频
- 照片
LCD1602显示格式:
年-月-日-时-分
秒-闹钟的-时-分-秒
- 演示视频
202307301048-FPGA多功能时钟
实现过程
编程思想
- 控制方式:按键
- 通过按键取设置年月日-时分秒,以及闹钟的时间,我定义了四个按键取进行控制,key1(key_data_1)是作为不同模式下的数值+,key2(key_data_2)是作为不同模式下的数值-,key3(key_data_3)是作为模式切换://功能按键 :秒设置,分设置,时设置,日设置,月设置,年设置,闹钟设置. ,key4(key_data_4)是确认按键.代码如下:
- //按键值
input key_data_1 ,//对应不同功能的数值+
input key_data_2 ,//对应不同功能的数值-
input key_data_3 ,//功能按键 :秒设置,分设置,时设置,日设置,月设置,年设置,闹钟设置.
input key_data_4 ,//确认按键
- 我们这个项目都是和时间有关系,在数字电路里面谁和时间有关系呢?第一就要想到计数器,我们基础的是不是第一步设计一个1s的计数器呢,代码如下:
//1s计数器
always@(posedge clk or negedge rst_n)
begin
if(! rst_n)
fre_cnt1<='d0 ;
else if( fre_cnt1== clk_num)
fre_cnt1<=0 ;
else
fre_cnt1<= fre_cnt1+1'b1;
end
- 那么我们对于时分秒,年月日的设计是不是都是需要通过许多个计数器来实现呢.好了设计6个计数器作为年月日,时分秒的计数,代码如下:
//=================================================================
//年月日 时分秒 时间设置
//=================================================================
//秒计数
always@(posedge clk or negedge rst_n)
begin
if(! rst_n)
second_cnt<='d0;
else if( second_cnt =='d60) //满60s 清0
second_cnt<=0;
else if( second_set && key_data_1 == 1 ) //秒设置+
second_cnt<= second_cnt+1'b1;
else if( second_set && key_data_2 == 1 && second_cnt > 0 )//秒设置-
second_cnt<= second_cnt-1'b1;
else if(key_3_cnt == 0 && fre_cnt1== clk_num) //key_3_cnt == 0运行状态
second_cnt<= second_cnt + 1;
else ;
end
//分计数
always@(posedge clk or negedge rst_n)
begin
if(! rst_n)
minute_cnt<='d35;
else if( minute_cnt =='d60) //满60分 清0
minute_cnt<=0;
else if( minute_set && key_data_1 == 1 ) //分设置+
minute_cnt<= minute_cnt+1'b1;
else if( minute_set && key_data_2 == 1 && minute_cnt > 0 )//分设置-
minute_cnt<= minute_cnt-1'b1;
else if(key_3_cnt == 0 && second_cnt =='d60) //满60s ,//key_3_cnt == 0运行状态
minute_cnt<= minute_cnt + 1;
else ;
end
//时计数
always@(posedge clk or negedge rst_n)
begin
if(! rst_n)
hour_cnt<='d21;
else if( hour_cnt =='d24) //满24时 清0
hour_cnt<=0;
else if( hour_set && key_data_1 == 1 ) //时设置+
hour_cnt<= hour_cnt+1'b1;
else if( hour_set && key_data_2 == 1 && hour_cnt > 0 ) //时设置-
hour_cnt<= hour_cnt-1'b1;
else if(key_3_cnt == 0 && minute_cnt =='d60) //满60分 ,//key_3_cnt == 0运行状态
hour_cnt<= hour_cnt + 1;
else ;
end
//天计数
always@(posedge clk or negedge rst_n)
begin
if(! rst_n)
day_cnt<='d22;
else if( day_cnt =='d31) //满31天 清0
day_cnt<=0;
else if( day_set && key_data_1 == 1 ) //天设置+
day_cnt<= day_cnt+1'b1;
else if( day_set && key_data_2 == 1 && day_cnt > 0 ) //天设置-
day_cnt<= day_cnt-1'b1;
else if(key_3_cnt == 0 && hour_cnt =='d24) ///满24时 ,//key_3_cnt == 0运行状态
day_cnt<= day_cnt + 1;
else ;
end
//月计数
always@(posedge clk or negedge rst_n)
begin
if(! rst_n)
month_cnt <= 'd07;
else if( month_cnt =='d12) //满12月 清0
month_cnt<=0;
else if( month_set && key_data_1 == 1 ) //月设置+
month_cnt<= month_cnt+1'b1;
else if( month_set && key_data_2 == 1 && month_cnt > 0 )//月设置-
month_cnt<= month_cnt-1'b1;
else if(key_3_cnt == 0 && day_cnt =='d31) //满31天 ,//key_3_cnt == 0运行状态
month_cnt<= month_cnt + 1;
else ;
end
//年计数
always@(posedge clk or negedge rst_n)
begin
if(! rst_n)
year_cnt <='d2023;
else if( year_cnt =='d9999) //满9999年 清0
year_cnt<=0;
else if( year_set && key_data_1 == 1 ) //年设置+
year_cnt<= year_cnt+1'b1;
else if( year_set && key_data_2 == 1 && year_cnt > 0 ) //年设置-
year_cnt<= year_cnt-1'b1;
else if(key_3_cnt == 0 && month_cnt =='d12) //满12月 ,//key_3_cnt == 0运行状态
year_cnt<= year_cnt + 1;
else ;
end
- 其中我们在设置秒计数的时候会考虑满60s的时候分钟+1,当满60分钟的时候时钟+1,满24小时的时候天+1,当满31(可以根据时间情况修改)天的时候月+1,当满12月的时候年+1.