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

FPGA开发--数码管扫描

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
FPGA开发--数码管扫描

8 r1 m8 S+ }; m+ j; K. U+ ?5 ^$ ~6 v8 d& u; }4 n& }9 I
) Y1 p8 I& ?: E  J2 T0 c, e' P, i* i- b
文章摘要:本文主要描述了数码管扫描电路的实现方案;
1 N# ?, e+ f$ A0 k; C  }6 u知识要点:有限状态机,模块例化;
0 P# p0 d! A" X" \
硬件平台: EP4CE6F17C8
0 N& V. H$ C( d2 w开发环境: Quartus II 13.1
2 p; s. \2 c  ~6 B2 }( ?: k7 t1 Z4 n0 L1 n  j
数码管扫描模块:
  • /*
  • *  功能描述: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
    5 n4 V) Q' ]$ u6 U) K

; ]; \! `3 W1 ?& y. [' Y; u. o5 _[color=rgb(51, 102, 153) !important]复制代码# r  h1 H1 Z$ h9 o5 @: `5 `

4 v* h0 r- {# A+ N) [6 a+ h% c" W5 }% s& H% J
- R/ ~! S7 G( M  }" o
译码器计数器模块:
  J) ~% E; N1 j* u$ M
  • /*
  • *  功能描述:异步十进制译码计数器
  • */
  • 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
    ' y$ q( ^9 k* B; R% _  Y+ }

: ^+ X! `/ q  j% L; {) O3 M[color=rgb(51, 102, 153) !important]复制代码
' n' S9 a# N. o: l) S. W& a0 a# G, x% q. T+ ]& x/ c% i5 ^

. {0 Y3 g7 `+ ^7 g
建立顶层模块(测试用)) Z/ r" s2 v! |. n6 o, J8 y% N
  • /*
  • *  功能描述:数码管测试程序
  • */
  • 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
    ' A9 V' C' S6 c- h' S, N

8 ^7 y7 u& U9 @( A7 H0 S3 v/ S3 ]) `: K4 F
7 R* m& Y4 X# |) f
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-29 03:28 , Processed in 0.125000 second(s), 23 queries , Gzip On.

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

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

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