这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » FPGA——数码管篇

共4条 1/1 1 跳转至

FPGA——数码管篇

菜鸟
2012-11-01 17:03:34     打赏

2.数码管篇

2.1 静态数码管显示

  1. 实现8个数码管从0-F循环显示 

 

2. 拨码开关控制数码管的显示

     利用拨码开关控制8个数码管的显示,拨动SW1,显示1; 关闭SW1,打开SW2,显示2...依此类推,拨动SW8,显示8。
工程下载:
seg7_control.zip


代码如下:

module seg7_ctr(
    sw   ,
    seg_cs_n ,
    seg_db  
    );
  
input [7:0] sw;    // 8个拨码开关,控制数码管显示的值
output [7:0] seg_cs_n;  // 位选信号,低电平有效
output [7:0] seg_db;   // 段选信号

 
// 定义寄存器
reg  [7:0] seg_db;


/******************共阳数码管的编码编码**********************
 0 0xc0 1 0xf9 2 0xa4 3 0xb0
 4 0x99 5 0x92 6 0x82 7 0xf8
 8 0x80 9 0x90 A 0x88 b 0x83
 c 0xc6 d 0xa1 E 0x86 F 0x8e
 
 **********************************************************/

always @(sw)
begin
 case(sw)
  8'b0111_1111: seg_db <= 8'hf9; // 1
  8'b1011_1111: seg_db <= 8'ha4; // 2
  8'b1101_1111: seg_db <= 8'hb0; // 3
  8'b1110_1111: seg_db <= 8'h99; // 4
  8'b1111_0111: seg_db <= 8'h92; // 5
  8'b1111_1011: seg_db <= 8'h82; // 6
  8'b1111_1101: seg_db <= 8'h90; // 7
  8'b1111_1110: seg_db <= 8'h80; // 8
  default: seg_db <= 8'hc0;  //其他情况显示0
 endcase
 
end

assign seg_cs_n = 8'b0000_0000;  // 8个数码管均点亮
 
endmodule




2.2 数码管滚动显示

       实现8个数码管的滚动显示,即第1个显示1,时间1s,然后关闭;接着然后第2个显示2,时间1s,关闭...,一直到最后一个显示8,关闭后返回显示第一个数码管。工程下载:seg7_move.zip

代码如下:
module seg7_move(
    sys_clk  ,
    sys_rst_n ,
    seg_cs_n ,
    seg_db  
    );


input   sys_clk;  // 系统时钟,50MHz
input   sys_rst_n;  // 复位信号,低电平有效
output [7:0] seg_cs_n;  // 位选信号,低电平有效
output [7:0] seg_db;   // 段选信号

//  定义寄存器
reg  [25:0] cnt;  // 计数1s
reg  [7:0] seg_cs_n; // 位选寄存器
reg  [7:0] seg_db;  // 段选寄存器
reg  [2:0] disp_data; // 计数寄存器,以改变位选信号


/******************共阳数码管的编码编码**********************
 0 0xc0 1 0xf9 2 0xa4 3 0xb0
 4 0x99 5 0x92 6 0x82 7 0xf8
 8 0x80 9 0x90 A 0x88 b 0x83
 c 0xc6 d 0xa1 E 0x86 F 0x8e
 
 **********************************************************/
parameter seg0 = 8'hc0, 
   seg1 = 8'hf9,
   seg2 = 8'ha4,
   seg3 = 8'hb0,
   seg4 = 8'h99,
   seg5 = 8'h92,
   seg6 = 8'h82,
   seg7 = 8'hf8,
   seg8 = 8'h80,
   seg9 = 8'h90,
   sega = 8'h88,
   segb = 8'h83,
   segc = 8'hc6,
   segd = 8'ha1,
   sege = 8'h86,
   segf = 8'h8e;

//-----------------计数 1 s---------------------------
always @(posedge sys_clk or negedge sys_rst_n)
begin
 if(!sys_rst_n)
  cnt <= 26'd0;
 else if(26'd49_999_999 == cnt)
  cnt <= 26'd0;
 else
  cnt <= cnt + 1'b1;
end


//------------------改变寄存器的值-----------------------

always @(posedge sys_clk or negedge sys_rst_n)
begin
 if(!sys_rst_n)
  disp_data <= 3'd0;
 else if(26'd49_999_999 == cnt) // 间隔1一次s,改变
  disp_data <= disp_data +1'b1;

end

//-----------------改变位选信号-------------------------

always @(disp_data)
begin
 case(disp_data)
  3'b000: seg_cs_n <= 8'b0111_1111;
  3'b001: seg_cs_n <= 8'b1011_1111;
  3'b010: seg_cs_n <= 8'b1101_1111;
  3'b011: seg_cs_n <= 8'b1110_1111;
  3'b100: seg_cs_n <= 8'b1111_0111;
  3'b101: seg_cs_n <= 8'b1111_1011;
  3'b110: seg_cs_n <= 8'b1111_1101;
  3'b111: seg_cs_n <= 8'b1111_1110;
  default:seg_cs_n <= 8'b1111_1111;  
 endcase
end

//----------------改变数码管的显示值---------------------------------

always @(disp_data) // disp_data发生改变,改变显示的值
begin
 case(disp_data)
  4'h0: seg_db <= seg1;
  4'h1: seg_db <= seg2;
  4'h2: seg_db <= seg3;
  4'h3: seg_db <= seg4;
  4'h4: seg_db <= seg5;
  4'h5: seg_db <= seg6;
  4'h6: seg_db <= seg7;
  4'h7: seg_db <= seg8; 
  default: ;  
 endcase
end
endmodule




2.3 数码管动态显示

1. 实现数码管动态显示“I LOVE U”。工程下载:seg7_static.zip

代码:
module seg7_static(
    sys_clk  ,
    sys_rst_n ,
    seg_cs_n ,
    seg_db  
    );

input   sys_clk;  // 系统时钟,50MHz
input   sys_rst_n;  // 复位信号,低电平有效
output [7:0] seg_cs_n;  // 位选信号,低电平有效
output [7:0] seg_db;   // 段选信号

reg  [7:0] seg_cs_n;  // 片选寄存器
reg  [7:0] seg_db;   // 位选寄存器
reg  [15:0] cnt;   // 计数存储器,计数约1.28 ms
reg  [2:0] disp_data;  // 计数寄存器,改变位选信号

//-------------------设定扫描频率-------------------------------
always @(posedge sys_clk or negedge sys_rst_n)
begin
 if(!sys_rst_n)
  cnt <= 16'd0;
 else
  cnt <= cnt + 1'b1;
end


//--------------------改变数码管显示值-----------------------------

always @(posedge sys_clk or negedge sys_rst_n)
begin
 if(!sys_rst_n)
  disp_data <= 3'd0;
 else if(16'hffff == cnt)
  begin
   if(3'd7 == disp_data)
    disp_data <= 3'd0;
   else
    disp_data <= disp_data + 1'b1;
  end
end

//--------------------改变位选信号------------------------------

always @(disp_data)
begin
 case(disp_data)
  3'b000: seg_cs_n <= 8'b0111_1111; //第8个数码管
  3'b001: seg_cs_n <= 8'b1011_1111; //第7个数码管
  3'b010: seg_cs_n <= 8'b1101_1111;
  3'b011: seg_cs_n <= 8'b1110_1111;
  3'b100: seg_cs_n <= 8'b1111_0111;
  3'b101: seg_cs_n <= 8'b1111_1011;
  3'b110: seg_cs_n <= 8'b1111_1101; //第3个数码管
  3'b111: seg_cs_n <= 8'b1111_1110; //第2个数码管
  default:seg_cs_n <= 8'b1111_1111; //第1个数码管
 endcase
  
end


/******************共阳数码管的编码编码**********************
 0 0xc0 1 0xf9 2 0xa4 3 0xb0
 4 0x99 5 0x92 6 0x82 7 0xf8
 8 0x80 9 0x90 A 0x88 b 0x83
 c 0xc6 d 0xa1 E 0x86 F 0x8e
 
 **********************************************************/

 
always @(disp_data) // 当disp_data发生改变,数码管的值改变
begin
 case(disp_data)
  4'h0: seg_db <= 8'hf9; // 显示1
  4'h1: seg_db <= 8'hff; // 不显示
  4'h2: seg_db <= 8'hc7; // 显示L
  4'h3: seg_db <= 8'hc0; // 显示0
  4'h4: seg_db <= 8'hc1; // 显示U
  4'h5: seg_db <= 8'h86; // 显示E
  4'h6: seg_db <= 8'hff; // 不显示
  4'h7:   seg_db <= 8'hc1; // 显示U
  default: ;
 endcase
end
endmodule




2. 两个数码管显示模为60的加法计数器。计数器从0开始计数,计数到59后清零,重头开始计数。工程下载:seg7_counter.zip

代码如下:

module seg7_counter(
     sys_clk  ,
     sys_rst_n ,
     seg_cs_n ,
     seg_db  
     );

input sys_clk;    // 系统时钟,50MHz
input sys_rst_n;    // 复位信号,低电平有效
output [1:0] seg_cs_n;  // 位选信号,低电平有效
output [7:0] seg_db;   // 段选信号


reg  [7:0] seg_db;  // 段选寄存器
reg  [15:0] scan_cnt; // 扫描计数器,扫描频率1Khz
reg  [25:0] d_cnt;  // 计数器,计数1 s
reg  [7:0] disp_data; // 寄存器,存储显示的数据
reg    disp_sel; // 在2位数码管中选择
reg  [3:0] shi;  // 计数器十位
reg  [3:0] ge;   // 计数器个位


/******************共阳数码管的编码编码**********************
 0 0xc0 1 0xf9 2 0xa4 3 0xb0
 4 0x99 5 0x92 6 0x82 7 0xf8
 8 0x80 9 0x90 A 0x88 b 0x83
 c 0xc6 d 0xa1 E 0x86 F 0x8e
 
 **********************************************************/
parameter seg0 = 8'hc0, 
   seg1 = 8'hf9,
   seg2 = 8'ha4,
   seg3 = 8'hb0,
   seg4 = 8'h99,
   seg5 = 8'h92,
   seg6 = 8'h82,
   seg7 = 8'hf8,
   seg8 = 8'h80,
   seg9 = 8'h90,
   sega = 8'h88,
   segb = 8'h83,
   segc = 8'hc6,
   segd = 8'ha1,
   sege = 8'h86,
   segf = 8'h8e;

//-------------------扫描频率1 Khz------------------------

always @(posedge sys_clk or negedge sys_rst_n)
begin
 if(!sys_rst_n)
  scan_cnt <= 16'd0;
 else
  begin
   if(16'd49_999 == scan_cnt)
    scan_cnt <= 16'd0;
   else
    scan_cnt <= scan_cnt +1'b1;
  end
end

//-------------------控制寄存器的计数------------------------
 
always @(posedge sys_clk or negedge sys_rst_n)
begin
 if(!sys_rst_n)
  disp_sel <= 1'b0;
 else
  begin
   if(16'd49_999 == scan_cnt)
    disp_sel <= ~disp_sel;
   else
    disp_sel <= disp_sel;
  end
  
end

assign seg_cs_n = (disp_sel == 1'b1)?2'b01:2'b10;

//----------------计数 1 s---------------------------

always @(posedge sys_clk or negedge sys_rst_n)
begin
 if(!sys_rst_n)
  d_cnt <= 26'd0;
 else
  begin
   if(26'd49_999_999 == d_cnt)
    d_cnt <= 26'd0;
   else
    d_cnt <= d_cnt + 1'b1;
  end
end

 

//----------------60 S 计数器------------------------------
always @(posedge sys_clk or negedge  sys_rst_n)
begin
 if(!sys_rst_n)
  begin
   shi <= 4'd0;
   ge  <= 4'd0;
  end
 else
  begin
   if(26'd49_999_999 == d_cnt )
    begin
     if(4'd9 == ge)
      begin
       if(4'd5 == shi)
        begin
         shi <= 4'd0;
         ge  <= 4'd0;
        end
       else
        begin
         shi <= shi + 4'd1;
         ge  <= 4'd0;
        end
      end
     else
      ge = ge + 4'b1;   
    end
  end
  
end

//-----------------数码管显示数据的选择--------------------
always @(disp_sel)
begin
 case(disp_sel)
  1'b0: disp_data <= ge;
  1'b1: disp_data <= shi;
  default:  ;
 endcase
end


//-------------------数据译码--------------------------------
 
always @(disp_data)
begin
 case(disp_data)
  4'h0: seg_db <= seg0;
  4'h1: seg_db <= seg1;
  4'h2: seg_db <= seg2;
  4'h3: seg_db <= seg3;
  4'h4: seg_db <= seg4;
  4'h5: seg_db <= seg5;
  4'h6: seg_db <= seg6;
  4'h7: seg_db <= seg7;
  4'h8: seg_db <= seg8;
  4'h9: seg_db <= seg9;
  default:  ;
 endcase
end
endmodule




关键词: 数码     管篇     显示     信号     寄存器     begin     b11    

菜鸟
2012-11-01 20:20:03     打赏
2楼
好东西!可以现在学习的人不多了。www.repair8.cn

菜鸟
2012-11-01 20:25:23     打赏
3楼
好东西!可以现在学习的人不多了。www.repair8.cn

菜鸟
2012-11-01 20:29:51     打赏
4楼
好东西!可以现在学习的人不多了。也请到我的小站一坐www.repair8.cn

共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]