|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1 d- S1 p! k) q2 v- n& d
$ _! H' Z& ]8 a
6 B: O1 w& p( N; {文章摘要:本文主要描述了数码管扫描电路的实现方案;. K: ~2 m* C5 O# W
知识要点:有限状态机,模块例化;
8 v4 a/ F8 }# ~硬件平台: EP4CE6F17C8
; ?9 V2 P) r" O1 D' N" @. @开发环境: Quartus II 13.1' p2 Y1 F' ~$ C7 [
4 @6 Z# C! K5 D数码管扫描模块:- /*
- * 功能描述:6位数码管扫描模块
- */
- module smg_scan(
- input clk, // 时钟信号
- input rst_n, // 复位信号
- output reg[7:0]data_pin, // 数据引脚,共阳数码管
- output reg[5:0]sel_pin, // 选通引脚,低电平导通
- input [7:0]seg0, // 数据0
- input [7:0]seg1, // 数据1
- input [7:0]seg2, // 数据2
- input [7:0]seg3, // 数据3
- input [7:0]seg4, // 数据4
- input [7:0]seg5 // 数据5
- );
- //--------------------------------------------------
- // 有限状态机
- parameter S_SEG0 = 4'd1;
- parameter S_SEG1 = 4'd2;
- parameter S_SEG2 = 4'd3;
- parameter S_SEG3 = 4'd4;
- parameter S_SEG4 = 4'd5;
- parameter S_SEG5 = 4'd6;
- reg[3:0] state; // 记录当前状态
- /*
- * 全部刷新时间不能超过10ms,否则人眼可以感觉到闪烁
- * 如果刷新时间缩短至5ms以内,则低速摄像机也扑捉不到闪烁
- */
- parameter FLUSH_COUNT = 50_000; // 单个刷新时间1ms,全部刷新时间为6ms
- reg[31:0] count; // 刷新记数器
- always @(posedge clk, negedge rst_n) begin
- if(!rst_n) begin
- sel_pin <= 6'b111111; // 复位时关闭显示
- state <= S_SEG0; // 回到初始状态
- end
- else if(count >= FLUSH_COUNT) begin // 定时时间到
- count <= 0; // 重新计数
- case(state)
- S_SEG0: begin
- state <= S_SEG1;
- sel_pin <= 6'b111110; // 片选
- data_pin <= seg0; // 数据
- end
- S_SEG1: begin
- state <= S_SEG2;
- sel_pin <= 6'b111101;
- data_pin <= seg1;
- end
- S_SEG2: begin
- state <= S_SEG3;
- sel_pin <= 6'b111011;
- data_pin <= seg2;
- end
- S_SEG3: begin
- state <= S_SEG4;
- sel_pin <= 6'b11_0111;
- data_pin <= seg3;
- end
- S_SEG4: begin
- state <= S_SEG5;
- sel_pin <= 6'b10_1111;
- data_pin <= seg4;
- end
- S_SEG5: begin
- state <= S_SEG0; // 最后一个显示完,下一次该显示示第一个了
- sel_pin <= 6'b01_1111;
- data_pin <= seg5;
- end
- default: begin
- state <= S_SEG0; // 未知状态,返回第一个状态
- end
- endcase
- end
- else begin
- count <= count + 1'b1; // 最后一个时钟沿其实是没计数的;
- end
- end
- endmodule) I0 `8 m* n, e8 o
( V3 r A* b$ R+ A p0 v3 L3 U A[color=rgb(51, 102, 153) !important]复制代码) J, F) N4 q/ ?" q! h1 N, Y
# [# i" k' r. P7 v# K/ v" d# J$ G& a
7 H( q# f. X) R; L( k2 ^* ~8 K1 u2 ]! c5 N. g
译码器计数器模块:# N" v, L& W0 z2 p; U; \( a! v2 a
- /*
- * 功能描述:异步十进制译码计数器
- */
- module decoder(
- clk, // 计数时钟
- rst_n, // 异步复位
- seg, // 译码输出
- carry // 进位(做为下级时钟)
- );
- input clk;
- input rst_n;
- output reg [7:0] seg;
- output reg carry;
- //------------------------------------------
- reg [3:0] count; // 计数器
- // 十进制计数器
- always @(posedge clk or negedge rst_n) begin
- if(~rst_n) begin
- count <= 0;
- carry <= 1'b0;
- end
- else if(count < 9) begin
- count <= count + 1'b1;
- carry <= 1'b0;
- end
- else begin
- count <= 0;
- carry <= 1'b1; // 产生进位
- end
- end
- // 组合逻辑
- always @(*) begin
- if(~rst_n) begin
- seg <= 8'b1111_1111; // 全灭
- end
- else begin
- case(count)
- 4'd0:
- seg <= 8'b1100_0000;
- 4'd1:
- seg <= 8'b1111_1001;
- 4'd2:
- seg <= 8'b1010_0100;
- 4'd3:
- seg <= 8'b1011_0000;
- 4'd4:
- seg <= 8'b1001_1001;
- 4'd5:
- seg <= 8'b1001_0010;
- 4'd6:
- seg <= 8'b1000_0010;
- 4'd7:
- seg <= 8'b1111_1000;
- 4'd8:
- seg <= 8'b1000_0000;
- 4'd9:
- seg <= 8'b1001_0000;
- 4'd10:
- seg <= 8'b1000_1000;
- default:
- seg <= 8'hff;
- endcase
- end
- end
- endmodule& j4 p$ g" n4 m1 m) }
) _6 b) m9 @+ V
[color=rgb(51, 102, 153) !important]复制代码8 J1 c- Z% G# E& o
/ ?+ H' x+ y: C k* h
0 f4 M) H% }! H1 w* |# A! R建立顶层模块(测试用)3 b, c+ f, g7 a. S F4 m* Y
- /*
- * 功能描述:数码管测试程序
- */
- module smg_test(
- input clk, // 系统时钟
- input rst_n, // 系统复位
- output [7:0]data_pin, // 数据管数据脚
- output [5:0]sel_pin // 数码管片选脚
- );
- reg[31:0] timer; // 定时器
- reg tick;
- // 模块连接线
- wire[7:0]seg0;
- wire[7:0]seg1;
- wire[7:0]seg2;
- wire[7:0]seg3;
- wire[7:0]seg4;
- wire[7:0]seg5;
- wire[7:0]seg6;
- wire c0; // 计数器进位
- wire c1;
- wire c2;
- wire c3;
- wire c4;
- //-----------------------------------------------
- always @(posedge clk or negedge rst_n) begin
- if(~rst_n)
- begin
- timer <= 0;
- tick <= 0;
- end
- else if(timer == 32'd25_000_000)
- begin
- tick <= 1'b1;
- timer <= 0;
- end
- else begin
- tick <= 0;
- timer <= timer + 1'b1;
- end
- end
- // 例化数码管显示模块
- smg_scan s0(
- .clk(clk), // 时钟信号
- .rst_n(rst_n), // 复位信号
- .data_pin(data_pin), // 数据引脚,共阳数码管
- .sel_pin(sel_pin), // 选通信号,低电平导通
- .seg0(seg0), // 数据
- .seg1(seg1), // 数据
- .seg2(seg2), // 数据
- .seg3(seg3), // 数据
- .seg4(seg4), // 数据
- .seg5(seg5) // 数据
- );
- // 例化6个显示译码器,用于将数字转化为显示段码;
- decoder u0(
- .clk(tick), // 计数时钟
- .rst_n(rst_n), // 异步复位
- .seg(seg0), // 译码输出
- .carry(c0) // 进位
- );
- decoder u1(
- .clk(c0), // 计数时钟
- .rst_n(rst_n), // 异步复位
- .seg(seg1), // 译码输出
- .carry(c1) // 进位
- );
- decoder u2(
- .clk(c1), // 计数时钟
- .rst_n(rst_n), // 异步复位
- .seg(seg2), // 译码输出
- .carry(c2) // 进位
- );
- decoder u3(
- .clk(c2), // 计数时钟
- .rst_n(rst_n), // 异步复位
- .seg(seg3), // 译码输出
- .carry(c3) // 进位
- );
- decoder u4(
- .clk(c3), // 计数时钟
- .rst_n(rst_n), // 异步复位
- .seg(seg4), // 译码输出
- .carry(c4) // 进位
- );
- decoder u5(
- .clk(c4), // 计数时钟
- .rst_n(rst_n), // 异步复位
- .seg(seg5), // 译码输出
- .carry() // 进位
- );
- endmodule5 U# C" V" e4 C, {) f
, t0 e6 D5 e7 Q2 X0 c9 P5 O& g* e7 s; O# I7 j
2 P* ~4 R/ K, t6 E
|
|