找回密码
 注册
关于网站域名变更的通知
查看: 226|回复: 1
打印 上一主题 下一主题

FPGA开发--数码管扫描

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-3-27 10:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
FPGA开发--数码管扫描
) P/ ^+ A  {5 _- l, z

$ g* c% ~& \. G/ L, [5 T, T
6 w( V7 C  z. y8 U, e文章摘要:本文主要描述了数码管扫描电路的实现方案;
" n+ b. T, o; ?# N4 R/ V; t$ ]& k知识要点:有限状态机,模块例化;
- U' E) V9 T4 P+ D/ E' S: z& h
硬件平台: EP4CE6F17C8
/ G- K" d/ Z9 p开发环境: Quartus II 13.15 l  ?3 N( n+ a! N
0 L1 @3 |; H3 p
数码管扫描模块:
  • /*
  • *  功能描述: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
    & V3 _$ l6 q- ~* g/ V" {  u
0 q2 V6 J9 q( e" z- v6 W& }
[color=rgb(51, 102, 153) !important]复制代码
. u7 ?# _" Z- W* O
$ F. _+ ?0 B4 n7 e
, ~+ R4 w; P; {  j( ^6 ~9 t& I4 T1 w) D/ q" g* z; z& l: K! z2 c
译码器计数器模块:9 H/ d  k1 s. y3 ?" }% n
  • /*
  • *  功能描述:异步十进制译码计数器
  • */
  • 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
  • endmodule9 H: ?( j" e( u% I% f3 \# ?3 W

- B2 W7 x0 q& C6 [7 v2 [# w[color=rgb(51, 102, 153) !important]复制代码4 q- p6 e/ |, m  a4 m: G% f( ]

' W' @% i( k8 z' F: \! {& r
1 I: {/ c7 s, I7 t8 w( g+ [4 J2 z
建立顶层模块(测试用)
& u3 t/ R& Y) m. ?
  • /*
  • *  功能描述:数码管测试程序
  • */
  • 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()       // 进位
  • );
  • endmodule! N6 r  j" u* b% p$ w: X3 M5 H  M

2 S9 ~& a- x2 k/ }: {( P+ a* |2 V, [, ?. O8 \3 A; y& a
- w/ U% k- @" d
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-10-8 20:48 , Processed in 0.125000 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表