⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hc164_driver.v

📁 用verilog写的HC164的驱动程序
💻 V
字号:
`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    17:19:29 11/13/2007 // Design Name: // Module Name:    hc164_driver // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module hc164_driver (
        iCLK50M     ,         // system clock
        iRST_N      ,         // system reset, Active--Low
        iLED_SEL    ,         // led select, Width---4, Active---Low
        iDOT_SEL    ,         // dot select, Width---4, Active---High
        iLED_VALUE  ,         // led value,  Width---16
        oHC_SI      ,         // serial data signal
        oHC_CP                   // hc164 clock pulse 
                     );


        input           iCLK50M        ;         // system clock
        input           iRST_N      ;         // system reset
        input   [3:0]   iLED_SEL    ;         // led select, Width---4, Active---Low
        input   [3:0]   iDOT_SEL    ;         // dot select, Width---4, Active---high
        input   [15:0]  iLED_VALUE  ;         // led value,  Width---16
        output          oHC_SI         ;         // serial data signal
        output          oHC_CP         ;         // hc164 clock pulse 
        

/*==================================================*/
//                  sr_clk_counter                  //
/*==================================================*/ 
      reg     [15:0]    sr_clk_counter ;
                  
      always @ ( posedge iCLK50M or negedge iRST_N )        
        if( !iRST_N )
            sr_clk_counter <= 16'd0;
        else
            sr_clk_counter <= sr_clk_counter + 1;
            
/*==================================================*/
//                  sr_LED_num    
//选位信号为65535/50*10^6,即763Hz,则遍历四段数码管只需0.05s,在视觉上人眼感觉数字在停留
/*==================================================*/  
      reg     [1:0]   sr_LED_num;
      
      always @ ( posedge iCLK50M or negedge iRST_N )
        if ( !iRST_N)
          sr_LED_num <= 2'b00;
        else if ( sr_clk_counter == 16'hffff)
           sr_LED_num <= sr_LED_num + 1'b1;        

/*==================================================*/
//                  sr_dot_select                   //
//           小数点选择信号,共四个小数点
/*==================================================*/
      reg          sr_dot_select ;
      
      always @ ( sr_LED_num or iDOT_SEL )
            sr_dot_select = iDOT_SEL[sr_LED_num];
            
            
/*==================================================*/
//                  sr_hex                          //
//  七段译码管的值直接通过iLED_VALUE赋值输入即可
/*==================================================*/
      reg   [3:0]   sr_hex ;
      
      always @ ( sr_LED_num or iLED_VALUE ) 
         case ( sr_LED_num )
            2'b00: sr_hex = iLED_VALUE[3:0];
            2'b01: sr_hex = iLED_VALUE[7:4];
            2'b10: sr_hex = iLED_VALUE[11:8];
            2'b11: sr_hex = iLED_VALUE[15:12];
            default: sr_hex = 4'b0000;
         endcase
            
/*==================================================*/
//                  sr_led_sel   
//        选段信号,每间隔763Hz,跳转一位.0.05s遍历一遍                  
/*==================================================*/
        reg   [3:0]   sr_led_sel;
        
        always @ ( sr_LED_num or iRST_N)
          if ( !iRST_N )
              sr_led_sel = 4'b0000;
          else
          case( sr_LED_num )
            2'b00: sr_led_sel = 4'b1110;
            2'b01: sr_led_sel = 4'b1101;
            2'b10: sr_led_sel = 4'b1011;
            2'b11: sr_led_sel = 4'b0111;
            endcase
 
/*==================================================*/
//                  sr_hex2led                      //
// segment encoding
//      11
//      ---  
//  10 |   | 7
//      ---   <- 5
//  1  |   | 4
//      --- .  3
//       2 
//  Q[6:0] = p11 p10 p7 p5 _ p4 p2 p1 
/*==================================================*/   
        reg   [6:0]   sr_hex2led;
        
        always @ ( sr_hex )
          case ( sr_hex )
	          4'H1  : sr_hex2led = 7'b0010_100;	  //1          
	          4'H2  : sr_hex2led = 7'b1011_011;	  //2   
	          4'H3  : sr_hex2led = 7'b1011_110;	  //3   
	          4'H4  : sr_hex2led = 7'b0111_100;	  //4   
	          4'H5  : sr_hex2led = 7'b1101_110;	  //5   
	          4'H6  : sr_hex2led = 7'b1101_111;	  //6   
	          4'H7  : sr_hex2led = 7'b1010_100;	  //7   
	          4'H8  : sr_hex2led = 7'b1111_111;	  //8   
	          4'H9  : sr_hex2led = 7'b1111_100;	  //9   
	          4'HA  : sr_hex2led = 7'b1111_101;	  //A   
	          4'HB  : sr_hex2led = 7'b0101_111;	  //b   
	          4'HC  : sr_hex2led = 7'b1100_011;	  //C   
	          4'HD  : sr_hex2led = 7'b0011_111;	  //d   
	          4'HE  : sr_hex2led = 7'b1101_011;	  //E   
	          4'HF  : sr_hex2led = 7'b1101_001;	  //F   
	          default : sr_hex2led = 7'b1110_111;	//0   
          endcase

/*==================================================*/
//                  sr_hc_data_buffer               //
/*==================================================*/ 
// ---------------------------------------------------------------------------
//
//  信号命名说明
//  hc_data : 送到两个hc164中16bit的数据(每个hc164有8bit),hc164 data input
//  iLED_SEL: hc_data的第四个4BIT数据,
//            LED显示信号,对应原理图中HC_Q15,HC_Q14,HC_Q13,HC_Q12四位,
//            用来点亮D5,D4,D3,D2四位LED灯,高电平有效。
//  sr_led_sel: hc_data的第三个4bit数据,即hc_data[11:8];对应原理图中
//              HC_Q11,HC_Q10,HC_Q9,HC_Q8数码管位选信号,低电平有效。
//  sr_dot_select: hc_data的第三个1bit数据,即hc_data[2];对应原理图中HC_Q2,数
//                 码管小数点位,高电平有效。 
//  sr_hex2led[7:0]: 包括hc_data_31bit,这8bit用来做为数码管段选信号,高电平有效
//
// ---------------------------------------------------------------------------
        reg   [15:0]    sr_hc_data_buffer ;
        
        always @ ( sr_hex2led or sr_led_sel or sr_dot_select or iLED_SEL )
            sr_hc_data_buffer[15:0] = { iLED_SEL,            //15->12
                                        sr_led_sel[3:0],    //11->8
                                        sr_hex2led[6:2],    //7->3
                                        sr_dot_select  ,    //2
                                        sr_hex2led[1:0]     //1->0
                                        };
                                        
                                        
/*==================================================*/
//                  sr_shift_counter                //
/*==================================================*/ 
        reg   [5:0]   sr_shift_counter;
        
        always @ ( posedge iCLK50M or negedge iRST_N )
          if ( !iRST_N )
            sr_shift_counter <= 6'b000_000;
         else if ( sr_clk_counter[15] ) 
                sr_shift_counter <= 6'b000_000;
              else if ( (!sr_clk_counter[15]) & (sr_shift_counter <= 32) )
                sr_shift_counter <= sr_shift_counter + 1'b1;   
                
/*==================================================*/
//                  sr_cp 
//   通过系统时钟给入,使hc164能进行动作,每进入16个二进制数,重复上一次动作,以此往复               //
/*==================================================*/
          reg       sr_cp;
          
          always @ ( posedge iCLK50M or negedge iRST_N )
            if ( !iRST_N )
              sr_cp <= 1'b0;
            else if ( sr_clk_counter[15] ) 
                    sr_cp <= 1'b0;                                                                
                 else if ( (!sr_clk_counter[15]) & ( sr_shift_counter < 6'd32 ))
                    sr_cp <= ~sr_cp;
                    
/*===================================================*/
//               oHC_CP, oHC_SI                       //
/*====================================================*/
         assign   oHC_CP = sr_cp;
         
         wire   [15:0] s_hc_data ;
         assign s_hc_data = {
                          sr_hc_data_buffer[0],
                          sr_hc_data_buffer[1],
                          sr_hc_data_buffer[2],
                          sr_hc_data_buffer[3],
                          sr_hc_data_buffer[4],
                          sr_hc_data_buffer[5],
                          sr_hc_data_buffer[6],
                          sr_hc_data_buffer[7],
                          sr_hc_data_buffer[8],
                          sr_hc_data_buffer[9],
                          sr_hc_data_buffer[10],
                          sr_hc_data_buffer[11],
                          sr_hc_data_buffer[12],
                          sr_hc_data_buffer[13],
                          sr_hc_data_buffer[14],
                          sr_hc_data_buffer[15]
                          };
                          
          assign    oHC_SI = s_hc_data[sr_shift_counter[4:1]];                          
                    
                    
                      
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -