EDA课程设计 百进制计数器.docx
《EDA课程设计 百进制计数器.docx》由会员分享,可在线阅读,更多相关《EDA课程设计 百进制计数器.docx(11页珍藏版)》请在冰豆网上搜索。
EDA课程设计百进制计数器
郑州航空工业管理学院
《EDA技术及应用》
课程设计报告
2012届通信工程专业1213071班级
题目:
百进制计数器
姓名学号
同组人
2014年6月25日
任务书
百进制计数器
设计要求
(1)技术范围为0~199
(2)可以在数码管上显示出计数值,且数值为十进制数
(3)计数方向:
双向(即可递增递减计数)
在EDA实验箱上完成。
1.晶振为48MHz
2.FPGA器件为ALTERA的EP1C6Q240C8
3.采用数码管显示
一、设计方案规划:
1.整体规划(确定输入与输出)
时钟输入clk,递增递减控制dir,输入按键key,数码管选择输出引脚dig,数码管段输出引脚seg,
具体如下:
inputclk;//输入时钟
inputdir;//递增递减控制键
input[1:
0]key;//输入按键
output[2:
0]dig;//数码管选择输出引脚
output[7:
0]seg;//数码管段输出引脚
2.功能划分与模块划分
a.秒信号产生部分
分频模块:
计算机本身频率较大,显示时间短,为显示人眼可见,将高频率改为低频率,即增减周期。
b.按键消抖处理部分
按键消抖模块:
作为机械开关键盘,在按键操作时,机械触点的弹性以及电压突跳等原因,在触点闭合或开启的瞬间出现电压抖动,所以处理后消除误触发。
c.计数处理部分
递增递减计数模块:
计数要求在0-199之间可增可减。
d.数码管动态扫描显示部分
选择扫描显示数据和选择数码管显示位
e.显示译码部分
显示相对应的数据
3.各功能或各模块的功能细分,
a.分频模块
定义clk上升沿触发器
q定义计数器寄存器,计数部分
b.按键消抖模块
key输入按键
key_done按键消抖输出
c.递增递减计数模块
清零部分控制键dir,递增部分,递减部分,sum计数缓存器
d.数码管动态扫描显示部分
显示不同各位的数据,选择对应的不同数码管,dig数码管选择
e.显示译码部分
共阳数码管,低电平有效,seg数码管译码结果
二、各模块的实现方法,技术、要点
分频模块:
always@(posedgeclk)//定义clk上升沿触发器。
分频//秒信号产生部分
begin
q=q+1'b1;
if(q==26'd24000000)
begin
q=0;//计数器清零
sec=~sec;//致位秒标志
end
end
按键消抖:
always@(posedgeq[16])
begin
dout1<={dir,key};
dout2<=dout1;
dout3<=dout2;
end
always@(negedgekey_done[0])
begin
keyen=~keyen;
end
regr_dir;
always@(negedgekey_done[2])
begin
r_dir=~r_dir;
end
计数块
递增计数:
always@(posedgesecornegedgekey_done[1])//200进制计数
begin
if(!
key_done[1])//是清零键吗?
sum<=12'h000;
else
beginif(r_dir)
begin
if(!
keyen)
beginif(sum>12'h198)sum<=12'h000;
else
sum[3:
0]<=sum[3:
0]+4'h1;//个位加1
if(sum[3:
0]==4'h9)
begin
sum[3:
0]<=0;
sum[7:
4]<=sum[7:
4]+4'h1;//十位加1
if(sum[7:
4]==4'h9)
begin
sum[7:
4]<=0;
sum[11:
8]<=sum[11:
8]+4'h1;//百位加1
end
if(sum==12'h199)sum[11:
0]<=12'h000;
end
end
end
递减计数:
elseif(!
keyen)
beginif(sum==12'h000)sum<=12'h199;
else
sum[3:
0]<=sum[3:
0]-4'h1;//个位减1
if(sum[3:
0]==4'h0)
begin
sum[3:
0]<=4'h9;
sum[7:
4]<=sum[7:
4]-4'h1;//十位减1
if(sum[7:
4]==4'h0)
begin
sum[7:
4]<=4'h9;
sum[11:
8]<=sum[11:
8]-4'h1;//百位减1
end
if(sum==12'h000)sum[11:
0]<=12'h199;
end
end
数码管动态扫描显示部分:
always@(posedgeclk)//count[17:
15]大约1ms改变一次
begin
case(q[16:
15])//选择扫描显示数据
2'd0:
disp_temp=sum[3:
0];//显示个位
2'd1:
disp_temp=sum[7:
4];//显示十位
2'd2:
disp_temp=sum[11:
8];//显示百位
2'd3:
disp_temp=4'hf;//为15,全灭
endcase
case(q[16:
15])//选择数码管显示位
2'd0:
dig_r=3'b110;//选择第一个数码管显示
2'd1:
dig_r=3'b101;//选择第二个数码管显示
2'd2:
dig_r=3'b011;//选择第三个数码管显示
default:
dig_r=3'b111;//选择第四个数码管显示
endcase
end
七段码显示模块:
always@(posedgeclk)//显示译码,共阳数码管(低电平有效,即为0时亮)
begin
case(disp_temp)
4'h0:
seg_r=8'hc0;//显示0
4'h1:
seg_r=8'hf9;//显示1
4'h2:
seg_r=8'ha4;//显示2
4'h3:
seg_r=8'hb0;//显示3
4'h4:
seg_r=8'h99;//显示4
4'h5:
seg_r=8'h92;//显示5
4'h6:
seg_r=8'h82;//显示6
4'h7:
seg_r=8'hf8;//显示7
4'h8:
seg_r=8'h80;//显示8
4'h9:
seg_r=8'h90;//显示9
default:
seg_r=8'hff;//不显示
endcase
end
三、模块的编写
modulecount199(clk,key,dir,dig,seg);
inputclk;//输入时钟
inputdir;//递增递减控制
input[1:
0]key;//输入按键
output[2:
0]dig;//数码管选择输出引脚
output[7:
0]seg;//数码管段输出引脚
reg[7:
0]seg_r;//定义数码管输出寄存器
reg[2:
0]dig_r;//定义数码管选择输出寄存器
reg[25:
0]q;//定义计数器寄存器分频计数器,最大2^6*2^20<64*10^6分频
reg[3:
0]disp_temp;//定义显示数据寄存器
reg[11:
0]sum;//计数缓存器
regsec,keyen;//定义标志位
reg[2:
0]dout1,dout2,dout3;//寄存器
wire[2:
0]key_done;//按键消抖输出
assigndig=dig_r;//输出数码管选择
assignseg=seg_r;//输出数码管译码结果
always@(posedgeclk)//定义clk上升沿触发器。
分频//秒信号产生部分
begin
q=q+1'b1;
if(q==26'd24000000)
begin
q=0;//计数器清零
sec=~sec;//致位秒标志
end
end
//按键消抖处理部分
assignkey_done=(dout1|dout2|dout3);//按键消抖输出
always@(posedgeq[16])
begin
dout1<={dir,key};
dout2<=dout1;
dout3<=dout2;
end
always@(negedgekey_done[0])
begin
keyen=~keyen;
end
regr_dir;
always@(negedgekey_done[2])
begin
r_dir=~r_dir;
end
always@(posedgesecornegedgekey_done[1])//200进制计数
begin
if(!
key_done[1])//是清零键吗?
sum<=12'h000;
else
beginif(r_dir)
begin
if(!
keyen)
beginif(sum>12'h198)sum<=12'h000;
else
sum[3:
0]<=sum[3:
0]+4'h1;//个位加1
if(sum[3:
0]==4'h9)
begin
sum[3:
0]<=0;
sum[7:
4]<=sum[7:
4]+4'h1;//十位加1
if(sum[7:
4]==4'h9)
begin
sum[7:
4]<=0;
sum[11:
8]<=sum[11:
8]+4'h1;//百位加1
end
if(sum==12'h199)sum[11:
0]<=12'h000;
end
end
end
elseif(!
keyen)
beginif(sum==12'h000)sum<=12'h199;
else
sum[3:
0]<=sum[3:
0]-4'h1;//个位减1
if(sum[3:
0]==4'h0)
begin
sum[3:
0]<=4'h9;
sum[7:
4]<=sum[7:
4]-4'h1;//十位减1
if(sum[7:
4]==4'h0)
begin
sum[7:
4]<=4'h9;
sum[11:
8]<=sum[11:
8]-4'h1;//百位减1
end
if(sum==12'h000)sum[11:
0]<=12'h199;
end
end
end
end
//数码管动态扫描显示部分
always@(posedgeclk)//count[17:
15]大约1ms改变一次
begin
case(q[16:
15])//选择扫描显示数据
2'd0:
disp_temp=sum[3:
0];//显示个位
2'd1:
disp_temp=sum[7:
4];//显示十位
2'd2:
disp_temp=sum[11:
8];//显示百位
2'd3:
disp_temp=4'hf;//为15,全灭
endcase
case(q[16:
15])//选择数码管显示位
2'd0:
dig_r=3'b110;//选择第一个数码管显示
2'd1:
dig_r=3'b101;//选择第二个数码管显示
2'd2:
dig_r=3'b011;//选择第三个数码管显示
default:
dig_r=3'b111;//选择第四个数码管显示
endcase
end
always@(posedgeclk)//显示译码,共阳数码管(低电平有效,即为0时亮)
begin
case(disp_temp)
4'h0:
seg_r=8'hc0;//显示0
4'h1:
seg_r=8'hf9;//显示1
4'h2:
seg_r=8'ha4;//显示2
4'h3:
seg_r=8'hb0;//显示3
4'h4:
seg_r=8'h99;//显示4
4'h5:
seg_r=8'h92;//显示5
4'h6:
seg_r=8'h82;//显示6
4'h7:
seg_r=8'hf8;//显示7
4'h8:
seg_r=8'h80;//显示8
4'h9:
seg_r=8'h90;//显示9
default:
seg_r=8'hff;//不显示
endcase
end
endmodule
四、仿真及调试
1.仿真
2.调试
对程序进行全程编译,发现错误并改正,直到成功。
拿出试验箱的配置连接线连接,下载程序到fpga器件中,观察动态数码管显示,并按键测试程序。
五、优化与改进
在计数的基础上,把原来的单向计数改进成双向计数,并定义dir为递增递减控制;同事增加了按键消抖功能。
六、任务完成情况说明
按照实验要求基本上完成实验。
七、课程设计体会与总结
指导老师评语: