这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » wenyangzeng 进程贴 数字频率计

共45条 2/5 1 2 3 4 5 跳转至
工程师
2012-10-14 09:04:05     打赏
11楼

进程4 LED动态、静态显示

动态显示:

module scan_led(clk,rst,sm_seg,sm_bit);
input clk,rst;
output[7:0] sm_seg;
output[7:0] sm_bit;
reg[7:0] sm_seg;
reg[7:0] sm_bit;

reg[15:0] cnt_scan;
reg[4:0] dataout_buf;

always@(posedge clk or negedge  rst)
begin
 if(!rst) begin
  cnt_scan<=0;
  
  end
 else begin
  cnt_scan<=cnt_scan+1'b1;
  
  end
end

always @(cnt_scan)
begin
   case(cnt_scan[15:13])
       3'b000 :
          sm_bit = 8'b1111_1110;
       3'b001 :
          sm_bit = 8'b0111_1111;
       3'b010 :
          sm_bit = 8'b1011_1111;
       3'b011 :
          sm_bit = 8'b1101_1111;
       3'b100 :
         sm_bit = 8'b1110_1111;
       3'b101 :
         sm_bit = 8'b1111_0111;
       3'b110 :
          sm_bit = 8'b1111_1011;
       3'b111 :
         sm_bit = 8'b1111_1101;
       default :
          sm_bit = 8'b1111_1110;
    endcase
end

always@(sm_bit)
begin
 case(sm_bit)
  8'b1111_1110:
   dataout_buf=8;
  8'b1111_1101:
   dataout_buf=7;
  8'b1111_1011:
   dataout_buf=6;
  8'b1111_0111:
   dataout_buf=5; 
  8'b1110_1111:
   dataout_buf=4;
  8'b1101_1111:
   dataout_buf=3;
  8'b1011_1111:
   dataout_buf=2;
  8'b0111_1111:
   dataout_buf=1;
  default:
   dataout_buf=0;
  endcase
end

always@(dataout_buf)
begin
 case(dataout_buf)
      4'h0 : sm_seg = 8'hc0;   // "0"
   4'h1 : sm_seg = 8'hf9;   // "1"
   4'h2 : sm_seg = 8'ha4;   // "2"
   4'h3 : sm_seg = 8'hb0;   // "3"
   4'h4 : sm_seg = 8'h99;   // "4"
   4'h5 : sm_seg = 8'h92;   // "5"
   4'h6 : sm_seg = 8'h82;   // "6"
   4'h7 : sm_seg = 8'hf8;   // "7"
   4'h8 : sm_seg = 8'h80;   // "8"
   4'h9 : sm_seg = 8'h90;   // "9"
   4'ha : sm_seg = 8'h88;   // "a"
   4'hb : sm_seg = 8'h83;   // "b"
   4'hc : sm_seg = 8'hc6;   // "c"
   4'hd : sm_seg = 8'ha1;   // "d"
   4'he : sm_seg = 8'h86;   // "e"
   4'hf : sm_seg = 8'h8e;   // "f"
  endcase
end

endmodule



                 图1 生成的顶层原理图



                 图2 运行结果

静态显示:

module led_display(sm_seg,sm_bit,clk,);
 input clk;       
 output [7:0] sm_seg;    //
 output [7:0] sm_bit;    //
    reg [7:0] sm_seg;
    reg [7:0] sm_bit;
    reg [3:0] disp_dat;
    reg [36:0] count;
 always @ (posedge clk )
 begin
  count = count + 1'b1;
  sm_bit = 8'b00000000;
 end
 always @ (count[24])
 begin
  disp_dat = {count[28:25]};
    end
    always @ (disp_dat)
 begin
  case (disp_dat) 
   4'h0 : sm_seg = 8'hc0;   // "0"
   4'h1 : sm_seg = 8'hf9;   // "1"
   4'h2 : sm_seg = 8'ha4;   // "2"
   4'h3 : sm_seg = 8'hb0;   // "3"
   4'h4 : sm_seg = 8'h99;   // "4"
   4'h5 : sm_seg = 8'h92;   // "5"
   4'h6 : sm_seg = 8'h82;   // "6"
   4'h7 : sm_seg = 8'hf8;   // "7"
   4'h8 : sm_seg = 8'h80;   // "8"
   4'h9 : sm_seg = 8'h90;   // "9"
   4'ha : sm_seg = 8'h88;   // "a"
   4'hb : sm_seg = 8'h83;   // "b"
   4'hc : sm_seg = 8'hc6;   // "c"
   4'hd : sm_seg = 8'ha1;   // "d"
   4'he : sm_seg = 8'h86;   // "e"
   4'hf : sm_seg = 8'h8e;   // "f"
  endcase
    end
endmodule 

生成顶层原理图(图1)与动态式相同


                                                                     图3 运行结果

tcl_script.tcl文件

#Pin_Setup.tcl
# Setup pin setting

set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED"
set_global_assignment -name ENABLE_INIT_DONE_OUTPUT ON

set_location_assignment PIN_129 -to clk
set_location_assignment PIN_191 -to sm_seg[0]
set_location_assignment PIN_197 -to sm_seg[1]
set_location_assignment PIN_205 -to sm_seg[2]
set_location_assignment PIN_200 -to sm_seg[3]
set_location_assignment PIN_198 -to sm_seg[4]
set_location_assignment PIN_193 -to sm_seg[5]
set_location_assignment PIN_206 -to sm_seg[6]
set_location_assignment PIN_201 -to sm_seg[7]
set_location_assignment PIN_188 -to sm_bit[7]
set_location_assignment PIN_189 -to sm_bit[6]
set_location_assignment PIN_192 -to sm_bit[5]
set_location_assignment PIN_195 -to sm_bit[4]
set_location_assignment PIN_199 -to sm_bit[3]
set_location_assignment PIN_203 -to sm_bit[2]
set_location_assignment PIN_207 -to sm_bit[1]
set_location_assignment PIN_208 -to sm_bit[0]


工程师
2012-10-14 15:50:47     打赏
12楼

进程5、字符型LCD

DIV16.V
module div16(clk,rst,clk_16);
input clk,rst;
output clk_16;

reg[3:0] count;

always @(posedge clk or negedge rst)
begin
  if (!rst)
    count <= 'b0;
  else
    count <= count +1;
end

assign clk_16 = count[3];

endmodule
//-----------------
.//LCD.V
//----------------
module lcd(clk,rst,lcd_e,lcd_rw,lcd_rs,data);
 input clk,rst;
 output lcd_e,lcd_rw,lcd_rs;
 output [7:0] data;
 reg lcd_e,lcd_rw,lcd_rs;
 reg [7:0] data;
 
 reg [9:0] state;
 reg [5:0] address;
 
 
 parameter IDLE  =10'b0000000000;
 parameter CLEAR  =10'b0000000001;  
 parameter RETURNCURSOR =10'b0000000010;  
 parameter SETMODE =10'b0000000111;  
 parameter SWITCHMODE =10'b0000001111; 
 parameter SHIFT  =10'b0000011100;  
 parameter SETFUNCTION =10'b0000111100; 
 parameter SETCGRAM =10'b0001000000;  
 parameter SETDDRAM1 =10'b0010000001; 
 parameter SETDDRAM2 =10'b0010000010;
 parameter READFLAG =10'b0100000000; 
 parameter WRITERAM2 =10'b1000000010;  
 parameter READRAM =10'b1100000000;  
 parameter cur_inc       =1;
 parameter cur_dec       =0;
 parameter cur_shift     =1;
 parameter cur_noshift   =0;
 parameter open_display  =1;
 parameter open_cur      =0;
 parameter blank_cur     =0;
 parameter shift_display =1;
 parameter shift_cur     =0;
 parameter right_shift   =1;
 parameter left_shift    =0;
 parameter datawidth8    =1;
 parameter datawidth4    =0;
 parameter twoline       =1;
 parameter oneline       =0;
 parameter font5x10      =1;
 parameter font5x7       =0;

 function [7:0] ddram;    input [5:0] n;
  begin
   case(n)
   6'b000_000:ddram=8'b0010_0000;//
   6'b000_001:ddram=8'b0010_0000;//    
   6'b000_010:ddram=8'b0100_0101;//E
   6'b000_011:ddram=8'b0100_0101;//E
   6'b000_100:ddram=8'b0101_0000;//P
   6'b000_101:ddram=8'b0101_0111;//w
   6'b000_110:ddram=8'b0010_1110;//.
   6'b000_111:ddram=8'b0110_0011;//c
   
   6'b010_000:ddram=8'b0110_1111;//o
   6'b010_001:ddram=8'b0110_1101;//m 
   6'b010_010:ddram=8'b0010_1110;//.
   6'b010_011:ddram=8'b0110_0011;//c
   6'b010_100:ddram=8'b0110_1110;//n
   6'b010_101:ddram=8'b0010_0000;//
   6'b010_110:ddram=8'b0010_0000;//
   6'b010_111:ddram=8'b0010_0000;// 
    endcase
  end
 endfunction
 reg [15:0] clkcnt;                
 always @ (posedge clk)
 if(!rst)
 clkcnt<=16'b0000_0000_0000_0000;
 else
 begin
  if(clkcnt==16'b0110_0001_1010_1000) //16'b1001_1100_0100_0000
   clkcnt<=16'b0000_0000_0000_0000;
  else
   clkcnt<=clkcnt+1;
 end
 wire tc_clkcnt;           
 assign tc_clkcnt=(clkcnt==16'b0110_0001_1010_1000)?1:0;//16'b1001_1100_0100_0000:40000
 reg clkdiv;              //T 为50000个clk
 always @ (posedge tc_clkcnt)
 if(!rst)
  clkdiv<=0;
 else
  clkdiv<=~clkdiv;
 
 reg clk_int;  
 always @ (posedge clkdiv) //原为clkdiv
 if(!rst)
  clk_int<=0;
 else
  clk_int<=~clk_int;
  
 always @ (negedge clkdiv) 
 if(!rst)
  lcd_e<=0;
 else
  lcd_e<=~lcd_e;
  
 always @ (posedge clk_int or negedge rst)
  if(!rst)
  begin
   state<=IDLE;
   address<=6'b000000;
   data<=8'b00000000;
   lcd_rs<=0;
   lcd_rw<=0;
  end
  else
  begin
   case(state)
   IDLE      :begin
        data<=8'bzzzz_zzzz;
        state<=CLEAR;
       end
         
   CLEAR   :begin lcd_rs<=0;lcd_rw<=0;data<=8'b0000_0001;
         state<=SETFUNCTION;end
         
   SETFUNCTION  :begin lcd_rs<=0;lcd_rw<=0;data[7:5]<=3'b001; 
                          data[4]<=datawidth8;data[3]<=twoline;
                          data[2]<=font5x10;data[1:0]<=2'b00;
           state<=SWITCHMODE;end
        
   SWITCHMODE   :begin lcd_rs<=0;lcd_rw<=0;data[7:3]<=5'b00001; 
                          data[2]<=open_display;data[1]<=open_cur;
                          data[0]<=blank_cur;
           state<=SETMODE;end 
        
   SETMODE   :begin lcd_rs<=0;lcd_rw<=0;data[7:2]<=6'b000001; 
                          data[1]<=cur_inc;data[0]<=cur_noshift;
           state<=SHIFT;end
   SHIFT   :begin lcd_rs<=0;lcd_rw<=0;data[7:4]<=4'b0001;  
                          data[3]<=shift_cur;data[2]<=left_shift;data[1:0]<=2'b00;
           state<=SETDDRAM1;end
        
   RETURNCURSOR :begin lcd_rs<=0;lcd_rw<=0;data<=8'b00000010;             state<=WRITERAM;end
   
   SETCGRAM  :begin lcd_rs<=0;lcd_rw<=0;data<=8'b01000000;                             state<=SETDDRAM;end*/
   SETDDRAM1  :begin lcd_rs<=0;lcd_rw<=0;data<=8'b10000000;                             state<=WRITERAM1;end
   SETDDRAM2  :begin lcd_rs<=0;lcd_rw<=0;data<=8'b11000000;  
80+40
                          state<=WRITERAM2;end
   WRITERAM1  :begin
       if(address<=6'b001_111)
       begin
        lcd_rs<=1;
        lcd_rw<=0;
        data<=ddram(address);
        address<=address+1;
        state<=WRITERAM1;
       end
       else
       begin
        lcd_rs<=0;
        lcd_rw<=0;
        state<=SETDDRAM2;
       end
       end
   WRITERAM2      :begin
                  if(address<=6'b011_100)
                  begin
        lcd_rs<=1;
        lcd_rw<=0;
        data<=ddram(address);
        address<=address+1;
        state<=WRITERAM2;
         end
         else
       begin
        lcd_rs<=0;
        lcd_rw<=0;
        state<=SHIFT;
        address<=6'b000000;
       end
       end
   endcase
  end
endmodule



                                 图1  原理图



                                图2  运行结果

我的字符型液晶使用单行字符型,字符方向也倒了180度。呵呵!


工程师
2012-10-16 11:00:11     打赏
13楼

进程6  LCD显示PS2键盘键值

尊照51FPGA提供的演示程序练习了PS2键盘输入键值在LCD上进行显示。
新建工程ps2_lcd\top.qpf
//---------------------------
//PS2_KEYBOARD.V
//---------------------------
`resetall
`timescale 1ns/100ps

`define TOTAL_BITS   11
`define EXTEND_CODE  16'hE0
`define RELEASE_CODE 16'hF0
`define LEFT_SHIFT   16'h12
`define RIGHT_SHIFT  16'h59
module ps2_keyboard_interface (
  clk,
  reset,
  ps2_clk,
  ps2_data,
  rx_extended,
  rx_released,
  rx_shift_key_on,
  rx_scan_code,
  rx_ascii,
  rx_data_ready,       // rx_read_o
  rx_read,             // rx_read_ack_i
  tx_data,
  tx_write,
  tx_write_ack_o,
  tx_error_no_keyboard_ack
  );
parameter TIMER_60USEC_VALUE_PP = 2950; // Number of sys_clks for 60usec.
parameter TIMER_60USEC_BITS_PP  = 12;   // Number of bits needed for timer
parameter TIMER_5USEC_VALUE_PP = 186;   // Number of sys_clks for debounce
parameter TIMER_5USEC_BITS_PP  = 8;     // Number of bits needed for timer
parameter TRAP_SHIFT_KEYS_PP = 0;       // Default: No shift key trap.
parameter m1_rx_clk_h = 1;
parameter m1_rx_clk_l = 0;
parameter m1_rx_falling_edge_marker = 13;
parameter m1_rx_rising_edge_marker = 14;
parameter m1_tx_force_clk_l = 3;
parameter m1_tx_first_wait_clk_h = 10;
parameter m1_tx_first_wait_clk_l = 11;
parameter m1_tx_reset_timer = 12;
parameter m1_tx_wait_clk_h = 2;
parameter m1_tx_clk_h = 4;
parameter m1_tx_clk_l = 5;
parameter m1_tx_wait_keyboard_ack = 6;
parameter m1_tx_done_recovery = 7;
parameter m1_tx_error_no_keyboard_ack = 8;
parameter m1_tx_rising_edge_marker = 9;
parameter m2_rx_data_ready = 1;
parameter m2_rx_data_ready_ack = 0;
input clk;
input reset;
inout ps2_clk;
inout ps2_data;
output rx_extended;
output rx_released;
output rx_shift_key_on;
output [7:0] rx_scan_code;
output [7:0] rx_ascii;
output rx_data_ready;
input rx_read;
input [7:0] tx_data;
input tx_write;
output tx_write_ack_o;
output tx_error_no_keyboard_ack;
reg rx_extended;
reg rx_released;
reg [7:0] rx_scan_code;
reg [7:0] rx_ascii;
reg rx_data_ready;
reg tx_error_no_keyboard_ack;
wire timer_60usec_done;
wire timer_5usec_done;
wire extended;
wire released;
wire shift_key_on;
wire rx_output_event;  
wire rx_output_strobe;
wire tx_parity_bit;
wire rx_shifting_done;
wire tx_shifting_done;
wire [11:0] shift_key_plus_code;
reg [`TOTAL_BITS-1:0] q;
reg [3:0] m1_state;
reg [3:0] m1_next_state;
reg m2_state;
reg m2_next_state;
reg [3:0] bit_count;
reg enable_timer_60usec;
reg enable_timer_5usec;
reg [TIMER_60USEC_BITS_PP-1:0] timer_60usec_count;
reg [TIMER_5USEC_BITS_PP-1:0] timer_5usec_count;
reg [7:0] ascii; 
reg left_shift_key;
reg right_shift_key;
reg hold_extended;  
reg hold_released;  
reg ps2_clk_s;     
reg ps2_data_s;     
reg ps2_clk_hi_z;    
reg ps2_data_hi_z; 
assign ps2_clk = ps2_clk_hi_z?1'bZ:1'b0;
assign ps2_data = ps2_data_hi_z?1'bZ:1'b0;
always @(posedge clk)
begin
  ps2_clk_s <= ps2_clk;
  ps2_data_s <= ps2_data;
end
always @(posedge clk)
begin : m1_state_register
  if (!reset) m1_state <= m1_rx_clk_h;
  else m1_state <= m1_next_state;
end
always @(m1_state
         or q
         or tx_shifting_done
         or tx_write
         or ps2_clk_s
         or ps2_data_s
         or timer_60usec_done
         or timer_5usec_done
         )
begin : m1_state_logic
  ps2_clk_hi_z <= 1;
  ps2_data_hi_z <= 1;
  tx_error_no_keyboard_ack <= 0;
  enable_timer_60usec <= 0;
  enable_timer_5usec <= 0;
  case (m1_state)
    m1_rx_clk_h :
      begin
        enable_timer_60usec <= 1;
        if (tx_write) m1_next_state <= m1_tx_reset_timer;
        else if (~ps2_clk_s) m1_next_state <= m1_rx_falling_edge_marker;
        else m1_next_state <= m1_rx_clk_h;
      end
    m1_rx_falling_edge_marker :
      begin
        enable_timer_60usec <= 0;
        m1_next_state <= m1_rx_clk_l;
      end
    m1_rx_rising_edge_marker :
      begin
        enable_timer_60usec <= 0;
        m1_next_state <= m1_rx_clk_h;
      end
    m1_rx_clk_l :
      begin
        enable_timer_60usec <= 1;
        if (tx_write) m1_next_state <= m1_tx_reset_timer;
        else if (ps2_clk_s) m1_next_state <= m1_rx_rising_edge_marker;
        else m1_next_state <= m1_rx_clk_l;
      end
    m1_tx_reset_timer:
      begin
        enable_timer_60usec <= 0;
        m1_next_state <= m1_tx_force_clk_l;
      end
    m1_tx_force_clk_l :
      begin
        enable_timer_60usec <= 1;
        ps2_clk_hi_z <= 0;  // Force the ps2_clk line low.
        if (timer_60usec_done) m1_next_state <= m1_tx_first_wait_clk_h;
        else m1_next_state <= m1_tx_force_clk_l;
      end
    m1_tx_first_wait_clk_h :
      begin
        enable_timer_5usec <= 1;
        ps2_data_hi_z <= 0;        // Start bit.
        if (~ps2_clk_s && timer_5usec_done)
          m1_next_state <= m1_tx_clk_l;
        else
          m1_next_state <= m1_tx_first_wait_clk_h;
      end
    m1_tx_first_wait_clk_l :
      begin
        ps2_data_hi_z <= 0;
        if (~ps2_clk_s) m1_next_state <= m1_tx_clk_l;
        else m1_next_state <= m1_tx_first_wait_clk_l;
      end
    m1_tx_wait_clk_h :
      begin
        enable_timer_5usec <= 1;
        ps2_data_hi_z <= q[0];
        if (ps2_clk_s && timer_5usec_done)
          m1_next_state <= m1_tx_rising_edge_marker;
        else
          m1_next_state <= m1_tx_wait_clk_h;
      end
    m1_tx_rising_edge_marker :
      begin
        ps2_data_hi_z <= q[0];
        m1_next_state <= m1_tx_clk_h;
      end
    m1_tx_clk_h :
      begin
        ps2_data_hi_z <= q[0];
        if (tx_shifting_done) m1_next_state <= m1_tx_wait_keyboard_ack;
        else if (~ps2_clk_s) m1_next_state <= m1_tx_clk_l;
        else m1_next_state <= m1_tx_clk_h;
      end
    m1_tx_clk_l :
      begin
        ps2_data_hi_z <= q[0];
        if (ps2_clk_s) m1_next_state <= m1_tx_wait_clk_h;
        else m1_next_state <= m1_tx_clk_l;
      end
    m1_tx_wait_keyboard_ack :
      begin
        if (~ps2_clk_s && ps2_data_s)
          m1_next_state <= m1_tx_error_no_keyboard_ack;
        else if (~ps2_clk_s && ~ps2_data_s)
          m1_next_state <= m1_tx_done_recovery;
        else m1_next_state <= m1_tx_wait_keyboard_ack;
      end
    m1_tx_done_recovery :
      begin
        if (ps2_clk_s && ps2_data_s) m1_next_state <= m1_rx_clk_h;
        else m1_next_state <= m1_tx_done_recovery;
      end
    m1_tx_error_no_keyboard_ack :
      begin
        tx_error_no_keyboard_ack <= 1;
        if (ps2_clk_s && ps2_data_s) m1_next_state <= m1_rx_clk_h;
        else m1_next_state <= m1_tx_error_no_keyboard_ack;
      end
    default : m1_next_state <= m1_rx_clk_h;
  endcase
end
always @(posedge clk)
begin : m2_state_register
  if (!reset) m2_state <= m2_rx_data_ready_ack;
  else m2_state <= m2_next_state;
end
always @(m2_state or rx_output_strobe or rx_read)
begin : m2_state_logic
  case (m2_state)
    m2_rx_data_ready_ack:
          begin
            rx_data_ready <= 1'b0;
            if (rx_output_strobe) m2_next_state <= m2_rx_data_ready;
            else m2_next_state <= m2_rx_data_ready_ack;
          end
    m2_rx_data_ready:
          begin
            rx_data_ready <= 1'b1;
            if (rx_read) m2_next_state <= m2_rx_data_ready_ack;
            else m2_next_state <= m2_rx_data_ready;
          end
    default : m2_next_state <= m2_rx_data_ready_ack;
  endcase
end
always @(posedge clk)
begin
  if (   !reset
      || rx_shifting_done
      || (m1_state == m1_tx_wait_keyboard_ack)        // After tx is done.
      ) bit_count <= 0;  // normal reset
  else if (timer_60usec_done
           && (m1_state == m1_rx_clk_h)
           && (ps2_clk_s)
      ) bit_count <= 0;  // rx watchdog timer reset
  else if ( (m1_state == m1_rx_falling_edge_marker)   // increment for rx
           ||(m1_state == m1_tx_rising_edge_marker)   // increment for tx
           )
    bit_count <= bit_count + 1;
end
assign rx_shifting_done = (bit_count == `TOTAL_BITS);
assign tx_shifting_done = (bit_count == `TOTAL_BITS-1);
assign tx_write_ack_o = (  (tx_write && (m1_state == m1_rx_clk_h))
                         ||(tx_write && (m1_state == m1_rx_clk_l))
                         );
assign tx_parity_bit = ~^tx_data;
always @(posedge clk)
begin
  if (!reset) q <= 0;
  else if (tx_write_ack_o) q <= {1'b1,tx_parity_bit,tx_data,1'b0};
  else if ( (m1_state == m1_rx_falling_edge_marker)
           ||(m1_state == m1_tx_rising_edge_marker) )
    q <= {ps2_data_s,q[`TOTAL_BITS-1:1]};
end
always @(posedge clk)
begin
  if (~enable_timer_60usec) timer_60usec_count <= 0;
  else if (~timer_60usec_done) timer_60usec_count <= timer_60usec_count + 1;
end
assign timer_60usec_done = (timer_60usec_count == (TIMER_60USEC_VALUE_PP - 1));
always @(posedge clk)
begin
  if (~enable_timer_5usec) timer_5usec_count <= 0;
  else if (~timer_5usec_done) timer_5usec_count <= timer_5usec_count + 1;
end
assign timer_5usec_done = (timer_5usec_count == TIMER_5USEC_VALUE_PP - 1);
assign extended = (q[8:1] == `EXTEND_CODE) && rx_shifting_done;
assign released = (q[8:1] == `RELEASE_CODE) && rx_shifting_done;
always @(posedge clk)
begin
  if (!reset || rx_output_event)
  begin
    hold_extended <= 0;
    hold_released <= 0;
  end
  else
  begin
    if (rx_shifting_done && extended) hold_extended <= 1;
    if (rx_shifting_done && released) hold_released <= 1;
  end
end
always @(posedge clk)
begin
  if (!reset) left_shift_key <= 0;
  else if ((q[8:1] == `LEFT_SHIFT) && rx_shifting_done && ~hold_released)
    left_shift_key <= 1;
  else if ((q[8:1] == `LEFT_SHIFT) && rx_shifting_done && hold_released)
    left_shift_key <= 0;
end
always @(posedge clk)
begin
  if (!reset) right_shift_key <= 0;
  else if ((q[8:1] == `RIGHT_SHIFT) && rx_shifting_done && ~hold_released)
    right_shift_key <= 1;
  else if ((q[8:1] == `RIGHT_SHIFT) && rx_shifting_done && hold_released)
    right_shift_key <= 0;
end
assign rx_shift_key_on = left_shift_key || right_shift_key;
always @(posedge clk)
begin
  if (!reset)
  begin
    rx_extended <= 0;
    rx_released <= 0;
    rx_scan_code <= 0;
    rx_ascii <= 0;
  end
  else if (rx_output_strobe)
  begin
    rx_extended <= hold_extended;
    rx_released <= hold_released;
    rx_scan_code <= q[8:1];
    rx_ascii <= ascii;
  end
end
assign rx_output_event  = (rx_shifting_done
                          && ~extended
                          && ~released
                          );
assign rx_output_strobe = (rx_shifting_done
                          && ~extended
                          && ~released
                          && ( (TRAP_SHIFT_KEYS_PP == 0)
                               || ( (q[8:1] != `RIGHT_SHIFT)
                                    &&(q[8:1] != `LEFT_SHIFT)
                                  )
                             )
                          );
assign shift_key_plus_code = {3'b0,rx_shift_key_on,q[8:1]};
always @(shift_key_plus_code)
begin
  casez (shift_key_plus_code)

 //字符库省略
  ..........
  endcase
end

endmodule
//------------------------
//LCD代码省略
//------------------------



                      图1  配置成功的管脚图



                  
                                    图2  从PS2键盘输入"0123456789abcdef ",运行结果


菜鸟
2012-10-17 09:28:50     打赏
14楼
学习中~~~

工程师
2012-10-19 21:11:11     打赏
15楼

进程7、按键控制LED
8只按键分别控制8只LED的亮灭。

module key_led(
            CLK,RESET,
            KEY[7:0],
            LED[7:0]
            );
input   CLK;
input   RESET;   
input   [7:0]KEY;
output  [7:0]LED;

reg[7:0] key_rst;
always @(posedge CLK  or negedge RESET)
    if (!RESET) key_rst <= 8'b1111_1111;
    else key_rst <= (KEY[7:0]);
reg[7:0] key_rst_r;  
always @ ( posedge CLK  or negedge RESET )
    if (!RESET) key_rst_r <= 8'b1111_1111;
    else key_rst_r <= key_rst;
wire[7:0] key_an = key_rst_r & ( ~key_rst);

reg[19:0]  cnt;  
always @ (posedge CLK  or negedge RESET)
    if (!RESET) cnt <= 20'd0; 
    else if(key_an) cnt <=20'd0;
    else cnt <= cnt + 1'b1;
 
reg[7:0] low_sw;
always @(posedge CLK  or negedge RESET)
    if (!RESET) low_sw <= 8'b1111_1111;
    else if (cnt == 20'hfffff)    
      low_sw <=(KEY[7:0]);

reg  [7:0] low_sw_r; 
always @ ( posedge CLK  or negedge RESET )
    if (!RESET) low_sw_r <= 8'b1111_1111;
    else low_sw_r <= low_sw;
 
wire[7:0] led_ctrl = low_sw_r[7:0] & ( ~low_sw[7:0]);
reg d1;
reg d2;
reg d3;
reg d4;
reg d5;
reg d6;
reg d7;
reg d8;
 
always @ (posedge CLK or negedge RESET)
    if (!RESET) begin
        d1 <= 1'b0;
        d2 <= 1'b0;
        d3 <= 1'b0;
        d4 <= 1'b0;
        d5 <= 1'b0;
        d6 <= 1'b0;
        d7 <= 1'b0;
        d8 <= 1'b0;
      end
    else begin      
        if ( led_ctrl[0] ) d1 <= ~d1;   
        if ( led_ctrl[1] ) d2 <= ~d2;
        if ( led_ctrl[2] ) d3 <= ~d3;
        if ( led_ctrl[3] ) d4 <= ~d4;   
        if ( led_ctrl[4] ) d5 <= ~d5;
        if ( led_ctrl[5] ) d6 <= ~d6;
        if ( led_ctrl[6] ) d7 <= ~d7;   
        if ( led_ctrl[7] ) d8 <= ~d8;
      end
assign LED[0] = d1 ? 1'b1 : 1'b0;       
assign LED[1] = d2 ? 1'b1 : 1'b0;
assign LED[2] = d3 ? 1'b1 : 1'b0;
assign LED[3] = d4 ? 1'b1 : 1'b0;
assign LED[4] = d5 ? 1'b1 : 1'b0;
assign LED[5] = d6 ? 1'b1 : 1'b0;      
assign LED[6] = d7 ? 1'b1 : 1'b0;
assign LED[7] = d8 ? 1'b1 : 1'b0;
endmodule



                       控制结果:奇数LED亮,偶数LED灭


工程师
2012-10-19 21:18:50     打赏
16楼


 
                                                    引脚分配图

工程师
2012-10-22 20:21:40     打赏
17楼

进程8、LED数码管显示DIP开关状态

设定外设板上8位DIP开关从左到右分别为D7到D0位,开关拨向下时该位为1,向上为0,读取8位开关的0-255状态值显示在3位LED数码管上。
//----------
//顶层文件
//dip_to_led.v
//----------
module dip_to_led
(
  CLK, RSTn,
  Number_Data,
  Row_Scan_Sig, Column_Scan_Sig
);
        input CLK;
  input RSTn;
  input [7:0]Number_Data;
  output [7:0]Row_Scan_Sig;
  output [2:0]Column_Scan_Sig;
  wire [3:0]Hund_Data;
  wire [3:0]Ten_Data;
  wire [3:0]One_Data;
  number_mod_module U1
  (
      .CLK( CLK ),
    .RSTn( RSTn ),
    .Number_Data( Number_Data ),
    .Hund_Data ( Hund_Data ),
    .Ten_Data( Ten_Data ),
    .One_Data( One_Data )
  );
  wire [7:0]Hund_SMG_Data;
  wire [7:0]Ten_SMG_Data;
  wire [7:0]One_SMG_Data;
  smg_encoder_module U2
  (
      .CLK( CLK ),
    .RSTn( RSTn ),
    .Hund_Data( Hund_Data ),
    .Ten_Data( Ten_Data ),
    .One_Data( One_Data ),
   
    .Hund_SMG_Data( Hund_SMG_Data ),
    .Ten_SMG_Data( Ten_SMG_Data ),
    .One_SMG_Data( One_SMG_Data )
 );
  smg_scan_module U3
  (
      .CLK( CLK ),
    .RSTn( RSTn ),
    .Hund_SMG_Data(Hund_SMG_Data ),
    .Ten_SMG_Data( Ten_SMG_Data ),
    .One_SMG_Data( One_SMG_Data ),
    .Row_Scan_Sig( Row_Scan_Sig ),
    .Column_Scan_Sig( Column_Scan_Sig )
  );
endmodule
//-----------------
//smg_scan_module.v
//----------------
module smg_scan_module
(
 CLK,RSTn,
 Hund_SMG_Data,Ten_SMG_Data,One_SMG_Data,
 Row_Scan_Sig,Column_Scan_Sig
 
);
 input CLK;
 input RSTn;
 input [7:0] Hund_SMG_Data;
 input [7:0] Ten_SMG_Data;
 input [7:0] One_SMG_Data;
 output [7:0]Row_Scan_Sig;
 output [2:0] Column_Scan_Sig;
  row_scan_module U1
(
 .CLK (CLK ),
 .RSTn ( RSTn ),
 .Hund_SMG_Data(Hund_SMG_Data ),
 .Ten_SMG_Data (Ten_SMG_Data),
 .One_SMG_Data(One_SMG_Data),
 .Row_Scan_Sig(Row_Scan_Sig)
);
 column_scan_module U2
(
 .CLK (CLK ),
 .RSTn ( RSTn ),
 .Column_Scan_Sig(Column_Scan_Sig)

);
endmodule
//--------------------
//column_scan_module.v
//--------------------
module column_scan_module
(
  CLK,RSTn,Column_Scan_Sig
);
 input CLK;
 input RSTn;
 output [3:0]Column_Scan_Sig;
 parameter T10MS = 18'd199_999;
 reg [17:0]Count1;
 
 always @ (posedge CLK or negedge RSTn)
  if ( !RSTn )
   Count1 <= 18'd0;
  else if (Count1 == T10MS )
   Count1 <= 18'd0;
  else
   Count1 <= Count1 + 18'b1;
   
 reg [1:0] t;
 
 always @  (posedge CLK or negedge RSTn)
  if ( !RSTn )
   t <= 2'd0;
  else if( t == 2'd3 )
   t <= 2'd0;
  else if ( Count1 == T10MS )
   t <= t + 1'b1;
   
 reg [2:0] rColumn_Scan;
 always @  (posedge CLK or negedge RSTn)
     if ( !RSTn )
         rColumn_Scan <=3'b110;
       else if(Count1 == T10MS )
         case (t)
   2'd0 : rColumn_Scan <= 3'b110;
   2'd1 : rColumn_Scan <= 3'b101;
   2'd2 : rColumn_Scan <= 3'b011;
  endcase
  
 assign Column_Scan_Sig = rColumn_Scan;
endmodule
//-------------------
//number_mod_module.v
//-------------------
module number_mod_module
(
 CLK,RSTn,
 Number_Data,
 Hund_Data,Ten_Data,One_Data
);

 input CLK;
 input RSTn;
 input [7:0]Number_Data;
 output [3:0] Hund_Data; 
 output [3:0] Ten_Data;
 output [3:0] One_Data;

 reg [31:0]rHund;
 reg [31:0]rTen;
 reg [31:0]rOne;
 
 always @ (posedge CLK or negedge RSTn )
  if( !RSTn )
   begin
    rHund <=32'd0;
    rTen <= 32'd0;
    rOne <= 32'd0;
   end
  else
   begin
    rHund <= Number_Data/100;
    rTen <= Number_Data %100/10;
    rOne <= Number_Data %10;
   end
 assign Hund_Data = rHund[3:0];  
 assign Ten_Data = rTen[3:0];
 assign One_Data = rOne[3:0];
 
endmodule
//------------------------
//row_scan_module.v
//------------------------
module row_scan_module
(
  CLK,RSTn,
  Hund_SMG_Data,Ten_SMG_Data ,One_SMG_Data,
  Row_Scan_Sig
);

 input CLK;
 input RSTn;
 input [7:0] Hund_SMG_Data;
 input [7:0] Ten_SMG_Data;
 input [7:0] One_SMG_Data;
 output [7:0] Row_Scan_Sig;
 
 parameter T10MS = 18'd199_999;
 
 reg [17:0]Count1;
 
 always @ ( posedge CLK or negedge RSTn )
  if( !RSTn )
   Count1 <= 18'd0;
  else if ( Count1 == T10MS )
   Count1 <= 18'd0;
  else
   Count1 <= Count1 + 18'b1;
   
   reg [1:0] t;
  
   always @ ( posedge CLK or negedge RSTn )
  if( !RSTn )
   t <= 2'd0;
  else if ( t == 2'd3)
   t <= 2'd0;
  else if (Count1 == T10MS )
       t <= t + 1'b1;
      
   reg [7:0]rData;
  
   always @ ( posedge CLK or negedge RSTn )
  if( !RSTn )
      rData <= 8'd0;
   else if ( Count1 == T10MS )
   case (t )
   2'd2 : rData <= Hund_SMG_Data;
   2'd1 : rData <= Ten_SMG_Data;
   2'd0 : rData <= One_SMG_Data;
  endcase
  
 assign Row_Scan_Sig = rData;
 
endmodule
//---------------------
//smg_encoder_module.v
//---------------------
module smg_encoder_module
(
 CLK, RSTn,
 Hund_Data,Ten_Data,One_Data,
 Hund_SMG_Data,Ten_SMG_Data,One_SMG_Data
);

 input CLK;
 input RSTn;
 
 input [7:0]Hund_Data;
 input [3:0] Ten_Data;
 input [3:0] One_Data;
 
 output [7:0] Hund_SMG_Data;
 output [7:0] Ten_SMG_Data;
 output [7:0] One_SMG_Data;
 
 parameter _0 = 8'b1100_0000, _1 = 8'b1111_1001, _2 = 8'b1010_0100,
           _3 = 8'b1011_0000, _4 = 8'b1001_1001, _5 = 8'b1001_0010,
           _6 = 8'b1000_0010, _7 = 8'b 1111_1000, _8 = 8'b1000_0000,
           _9 = 8'b1001_0000;
 reg [7:0] rHund_SMG_Data;

 always @ (posedge CLK or negedge RSTn )
   if( !RSTn)
     begin
   rHund_SMG_Data <= 8'b1111_1111;
  end
  else
   case (Hund_Data)
    
    4'd0 : rHund_SMG_Data <= _0;
    4'd1 : rHund_SMG_Data <= _1;
    4'd2 : rHund_SMG_Data <= _2;
    4'd3 : rHund_SMG_Data <= _3;
    4'd4 : rHund_SMG_Data <= _4;
    4'd5 : rHund_SMG_Data <= _5;
    4'd6 : rHund_SMG_Data <= _6;
    4'd7 : rHund_SMG_Data <= _7;
    4'd8 : rHund_SMG_Data <= _8;
    4'd9 : rHund_SMG_Data <= _9;
   endcase
          
 reg [7:0] rTen_SMG_Data;

 always @ (posedge CLK or negedge RSTn )
   if( !RSTn)
     begin
   rTen_SMG_Data <= 8'b1111_1111;
  end
  else
   case (Ten_Data)
    
    4'd0 : rTen_SMG_Data <= _0;
    4'd1 : rTen_SMG_Data <= _1;
    4'd2 : rTen_SMG_Data <= _2;
    4'd3 : rTen_SMG_Data <= _3;
    4'd4 : rTen_SMG_Data <= _4;
    4'd5 : rTen_SMG_Data <= _5;
    4'd6 : rTen_SMG_Data <= _6;
    4'd7 : rTen_SMG_Data <= _7;
    4'd8 : rTen_SMG_Data <= _8;
    4'd9 : rTen_SMG_Data <= _9;
   endcase
   
  reg [7:0] rOne_SMG_Data;
  always @ ( posedge CLK or negedge RSTn)
   if( !RSTn)
    begin
     rOne_SMG_Data <= 8'b1111_1111;
    end
   else
    case (One_Data)
   
    4'd0 : rOne_SMG_Data <= _0;
    4'd1 : rOne_SMG_Data <= _1;
    4'd2 : rOne_SMG_Data <= _2;
    4'd3 : rOne_SMG_Data <= _3;
    4'd4 : rOne_SMG_Data <= _4;
    4'd5 : rOne_SMG_Data <= _5;
    4'd6 : rOne_SMG_Data <= _6;
    4'd7 : rOne_SMG_Data <= _7;
    4'd8 : rOne_SMG_Data <= _8;
    4'd9 : rOne_SMG_Data <= _9;
   endcase
  assign Hund_SMG_Data = rHund_SMG_Data; 
  assign Ten_SMG_Data = rTen_SMG_Data;
  assign One_SMG_Data = rOne_SMG_Data;
 endmodule

 


工程师
2012-10-22 20:23:50     打赏
18楼





                           0x0f(b00001111) = 15


  
                                   0xcf(b11001111) = 207


                
                               0xff(b11111111) = 255


工程师
2012-10-22 20:25:10     打赏
19楼


                                                               引脚分配图

工程师
2012-10-29 15:13:38     打赏
20楼

进程9 、串行通讯

        为了验证那片5V的MAX232工作在3V能否胜任,即进入RS232通讯练习,估计5V器件工作在3V时,性能会打折扣,故波特率只设定在9600,波特率设定:
module bps_module
(
   CLK, RSTn,
  Count_Sig,
  BPS_CLK
);

    input CLK;
  input RSTn;
  input Count_Sig;
  output BPS_CLK;
  reg [12:0]Count_BPS;
    always @ ( posedge CLK or negedge RSTn )
     if( !RSTn )
       Count_BPS <= 13'd0;
   else if( Count_BPS == 13'd5208 )
       Count_BPS <= 13'd0;
   else if( Count_Sig )
       Count_BPS <= Count_BPS + 1'b1;
   else
       Count_BPS <= 13'd0;
    assign BPS_CLK = ( Count_BPS == 13'd2604 ) ? 1'b1 : 1'b0;

endmodule
//----------------------
//  发送控制:
//---------------------
module tx_control_module
(
    CLK, RSTn,
  TX_En_Sig, RX_Data, BPS_CLK,
    TX_Done_Sig, TX_Pin_Out
);

   input CLK;
  input RSTn;
  input TX_En_Sig;
  input [7:0]RX_Data;
  input BPS_CLK;
  output TX_Done_Sig;
  output TX_Pin_Out;
  reg [3:0]i;
  reg rTX;
  reg isDone;
  always @ ( posedge CLK or negedge RSTn )
      if( !RSTn )
        begin
            i <= 4'd0;
      rTX <= 1'b1;
      isDone  <= 1'b0;
    end
    else if( TX_En_Sig )
        case ( i )
        4'd0 :
      if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b0; end
      4'd1, 4'd2, 4'd3, 4'd4, 4'd5, 4'd6, 4'd7, 4'd8 :
      if( BPS_CLK ) begin i <= i + 1'b1; rTX <= RX_Data[ i - 1 ]; end
      4'd9 :
      if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b1; end
      4'd10 :
      if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b1; end
      4'd11 :
      if( BPS_CLK ) begin i <= i + 1'b1; isDone <= 1'b1; end
     
      4'd12 :
      begin i <= 1'b0; isDone <= 1'b0; end
         endcase
       assign TX_Pin_Out = rTX;
  assign TX_Done_Sig = isDone;
endmodule
//-------------------
//接收控制
//-------------------
module rx_control_module
(
    CLK, RSTn,
  H2L_Sig, RX_Pin_In, BPS_CLK, RX_En_Sig,
    Count_Sig, RX_Data, RX_Done_Sig,TX_En_Sig
 
);

    input CLK;
  input RSTn;
  input H2L_Sig;
  input RX_En_Sig;
  input RX_Pin_In;
  input BPS_CLK;
   output Count_Sig;
  output [7:0]RX_Data;
  output RX_Done_Sig;
  output TX_En_Sig;
  reg [3:0]i;
  reg [7:0]rData;
  reg isCount;
  reg isDone;
  reg isTxen;
  always @ ( posedge CLK or negedge RSTn )
      if( !RSTn )
        begin
            i <= 4'd0;
      rData <= 8'd0;
      isCount <= 1'b0;
      isDone <= 1'b0;
      isTxen <= 1'b0;
    end
    else if( RX_En_Sig )
        case ( i )
           4'd0 :
      if( H2L_Sig ) begin i <= i + 1'b1; isCount <= 1'b1; end
      4'd1 :
      if( BPS_CLK ) begin i <= i + 1'b1; end
      4'd2, 4'd3, 4'd4, 4'd5, 4'd6, 4'd7, 4'd8, 4'd9 :
      if( BPS_CLK ) begin i <= i + 1'b1; rData[ i - 2 ] <= RX_Pin_In; end
      4'd10 :
      if( BPS_CLK ) begin i <= i + 1'b1; end
      4'd11 :
      if( BPS_CLK ) begin i <= i + 1'b1; end
      4'd12 :
      begin i <= i + 1'b1; isDone <= 1'b1; isCount <= 1'b0; end
      4'd13 :
      begin i <= 1'b0; isDone <= 1'b0; isTxen <= 1'b1;end     
    endcase
  assign Count_Sig = isCount;
  assign RX_Data = rData;
  assign RX_Done_Sig = isDone;
 assign TX_En_Sig = isTxen;
endmodule

其余代码省略

      使用串口助手进行调试,接口板上8只LED显示接收到的1个字节的数据,同时每隔2秒钟向上位机发送所接收到的数据。
     
还好,这只MAX232马马虎虎还能在3V下正常工作。大家可以不用对它动手术了。

点击下载
串口通讯演示软件.rar测试一下你的MAX232。


 
                                     引脚分配图
运行结果见下页


共45条 2/5 1 2 3 4 5 跳转至

回复

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