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

共30条 3/3 1 2 3 跳转至
工程师
2012-11-07 11:03:57     打赏
21楼

进程11、交通灯

     交通灯是通过将进程4中的LED数码动态显示模块与本模块组合成的交通信号灯。秒信号计数器从50MHZ分频得到,初值设定为35秒,计数到5秒后黄灯开始闪烁,计数到0秒后黄灯熄灭。绿灯与红灯交换亮起。

秒信号:
 /************************************/
 
  parameter T1S = 26'd49_999_999;
 
  /************************************/
 
  reg [25:0]Count1;
 
  always @ ( posedge CLK or negedge RSTn )
      if( !RSTn )
        Count1 <= 26'd0;
    else if( Count1 == T1S )
        Count1 <= 26'd0;
    else
        Count1 <= Count1 + 1'b1;

控制过程:
 reg [7:0]Counter_Sec;
  reg rRED;
  reg rYELLOW;
 
  always @ ( posedge CLK or negedge RSTn )
      if( !RSTn )
        begin
            Counter_Sec <= 8'd35;            //秒计数初值
            rRED <= 1'd1;                         //红灯灭
            rYELLOW <= 1'd1;                 //黄灯灭
      end
    else if( Count1 == T1S )

        begin
          if( Counter_Sec > 8'd0 )
               begin
                     Counter_Sec <= Counter_Sec - 1'b1;
                         if((Counter_Sec == 8'd6)||(Counter_Sec == 8'd4)||(Counter_Sec == 8'd2) )
         rYELLOW <= 1'd0;                //黄灯闪烁亮期间
        else
         rYELLOW <= 1'd1;               //黄灯闪烁灭期间
      end
            else
      begin
       Counter_Sec <= 8'd35;
       rRED <= ~rRED;                 //2个秒计数周期红绿灯交换亮灭
       rYELLOW = 1'd1;
      end
      end
  
    /******************************************/

  assign RED = rRED;                //输出
  assign GREEN = ~rRED;
  assign YELLOW = rYELLOW;


                                     I/O分配图



     通行期间绿灯亮,  计数到5秒后黄灯闪烁期的黄灯熄灭期间



   禁行期间红灯亮,  计数到5秒后黄灯闪烁期的黄灯亮起期间

点击下载交通灯演示SOFsample_demo.rar


工程师
2012-11-13 22:25:36     打赏
22楼

进程12、TLC549ADC

       有点可惜,接口板的ADC芯片只有8位转换精度。板上的那只多圈电位器就取消了,焊上一只3脚插座,外接一只电位器代用,省得再对PCB板进行动手术。

 ADC_CLK转换时钟从50MHZ晶振分频成1MHZ得到:

@(posedge CLK or negedge RSTn) //rAD_CLK = 1MHz
 begin
    if(!RSTn)
        begin
            rDCLK_DIV <= 1'b0;
           rAD_CLK <= 1'b0;
       end
 else
      if(rDCLK_DIV < 6'd50) rDCLK_DIV <= rDCLK_DIV+1'b1;
        else
           begin
               rDCLK_DIV <= 0;
             rAD_CLK <= ~rAD_CLK;
          end
  end
/**************************************
// 读出的8位ADC值存放在result中:

rAD_CLK : 1'b0;
reg[7:0] rData_reg;
always @(negedge rAD_CLK)
begin
  if(rCount >= 5'd2 && rCount <= 5'd9) 
     begin
       rData_reg[0] <= AD_DATA;
       rData_reg[7:1] <= rData_reg[6:0];
     end
  else  result <= rData_reg;
 end
显示部分代码就省略了

 
                      逻辑框图



                      IO分配图


   
                                  运行结果
      感觉转换结果的个位数不是很稳定。

点击下载tlc549_top.rar


工程师
2012-11-25 20:55:59     打赏
23楼

进程13、VGA彩条

         练习中接口板上的VGA接口使用了10、31、37(RGB)和4、6(行场同步)共5条信号线。运行后在屏幕上显示8条水平彩条。由彩条控制模块和同步控制模块组合而成。

彩条控制模块
module vga_control_module
(
    CLK, RSTn,
  Ready_Sig, Column_Addr_Sig, Row_Addr_Sig,
  Red_Sig, Green_Sig, Blue_Sig
);
    input CLK;
  input RSTn;
  input Ready_Sig;
  input [10:0]Column_Addr_Sig;
  input [10:0]Row_Addr_Sig;
  output Red_Sig;
  output Green_Sig;
  output Blue_Sig;
  reg isRectangle;
  always @ ( posedge CLK or negedge RSTn )
      if( !RSTn )
        isRectangle <= 1'b0;
    else if( Column_Addr_Sig > 11'd0 && Row_Addr_Sig < 11'd600 )
            isRectangle <= 1'b1;
    else
        isRectangle <= 1'b0;
     wire color0,color1,color2,color3,color4,color5,color6,color7;
   assign color7 = ( (Row_Addr_Sig>=0  ) && (Row_Addr_Sig<=75) );
   assign color6 = ( (Row_Addr_Sig>=75) && (Row_Addr_Sig<=150) );
   assign color5 = ( (Row_Addr_Sig>=150) && (Row_Addr_Sig<=225) );
   assign color4 = ( (Row_Addr_Sig>=225) && (Row_Addr_Sig<=300) );
   assign color3 = ( (Row_Addr_Sig>=300) && (Row_Addr_Sig<=375) );
   assign color2 = ( (Row_Addr_Sig>=375) && (Row_Addr_Sig<=450) );
   assign color1 = ( (Row_Addr_Sig>=450) && (Row_Addr_Sig<=525) );
   assign color0 = ( (Row_Addr_Sig>=525) && (Row_Addr_Sig<=600) );
  assign Red_Sig = Ready_Sig && isRectangle ?  (color0 | color3 | color4 | color6 ): 1'b0;
  assign Green_Sig = Ready_Sig && isRectangle ? (color1 | color3 | color5 | color6) : 1'b0;
  assign Blue_Sig = Ready_Sig && isRectangle ? (color2 | color4 | color5 | color6 ) : 1'b0;
endmodule
/****************************************/
同步控制模块

 module sync_module
(
    CLK, RSTn,
  VSYNC_Sig, HSYNC_Sig, Ready_Sig,
  Column_Addr_Sig, Row_Addr_Sig
);

    input CLK;
  input RSTn;
  output VSYNC_Sig;
  output HSYNC_Sig;
  output Ready_Sig;
  output [10:0]Column_Addr_Sig;
  output [10:0]Row_Addr_Sig;
  reg [10:0]Count_H;   
  reg [9:0]Count_V;   
  always @ ( posedge CLK or negedge RSTn )
      if( !RSTn ) Count_H <= 11'd0;
  else if( Count_H == 11'd1039 )   Count_H <= 11'd0;
  else  Count_H <= Count_H + 1'b1;
  always @ ( posedge CLK or negedge RSTn )
      if( !RSTn )  Count_V <= 10'd0;
  else if( Count_V == 10'd665 )Count_V <= 10'd0;
  else if( Count_H == 10'd1039 )Count_V <= Count_V + 1'b1;
  reg isReady;
   always @ ( posedge CLK or negedge RSTn )
      if( !RSTn )
        isReady <= 1'b0;
        else if((Count_H > 11'd215) &&( Count_H < 11'd1015 ) &&
           ( Count_V > 10'd32) &&( Count_V < 10'd632 ) )
        isReady <= 1'b1;
    else
        isReady <= 1'b0;
  assign VSYNC_Sig = ( Count_V <= 11'd6 ) ? 1'b0 : 1'b1;
  assign HSYNC_Sig = ( Count_H <= 11'd120 ) ? 1'b0 : 1'b1;
  assign Ready_Sig = isReady; 
  assign Column_Addr_Sig = isReady ? Count_H - 11'd217 : 11'd0;   assign Row_Addr_Sig = isReady ? Count_V - 11'd28 : 11'd0; 
endmodule


 
                                IO分配表



                                显示结果

点击下载 vga_module.rar


工程师
2012-12-05 19:40:01     打赏
24楼

进程14、音乐彩灯、警笛声、电子琴

14.1音乐彩灯

        练习中将音乐《铃儿响叮当》自动演奏和LDE灯相结合,组成音乐彩灯。

module music(clk,beep,led);     
input clk;      
output beep;      
output [10:0]led;

reg r_BEEP;      
reg[7:0] r_STATE;       
reg[16:0]r_r_COUNT,r_NOTES;
reg[23:0]r_COUNT1;
reg[10:0]r_r_LED_OUT;

parameter    L_1 = 17'd95566,
  L_2 = 17'd85121,
  L_3 = 17'd75850,           
  L_4 = 17'd71592,
  L_5 = 17'd63776,           
  L_6 = 17'd56818,       
  L_7 = 17'd50618,   
  M_1 = 17'd47774,   
  M_2 = 17'd42568,   
  M_3 = 17'd37919,   
  M_4 = 17'd35791,
  M_5 = 17'd31888,   
  M_6 = 17'd28409,   
  M_7 = 17'd25309,
parameter TIME = 6000000;  
 
assign beep = r_BEEP;   
  
always@(posedge clk)
begin
 r_COUNT <= r_COUNT + 1'b1;    
 if(r_COUNT == r_NOTES)
     begin
        r_COUNT <= 17'h0;     
       r_BEEP <= !r_BEEP;    
     end
end
always @(posedge clk)
begin
 if(r_COUNT1 < TIME)     
      r_COUNT1 = r_COUNT1 + 1'b1;
 else
 begin
     r_COUNT1 = 24'd0;
       if(r_STATE == 8'd120)
          r_STATE = 8'd0;
      else
        r_STATE = r_STATE + 1'b1;

  case(r_STATE)
   8'd1: r_NOTES = L_5;
   8'd3: r_NOTES = M_3;
   8'd5: r_NOTES = M_2;
   8'd7: r_NOTES = M_1;
   8'd9: r_NOTES = L_5;
   8'd13: r_NOTES = 0;
   8'd15: r_NOTES = L_5;
   8'd17: r_NOTES = M_3; 
   8'd19: r_NOTES = M_2;
   8'd21: r_NOTES = M_1;
   8'd23: r_NOTES = L_6;
   8'd27: r_NOTES = 0;
   8'd29: r_NOTES = L_6;
   8'd31: r_NOTES = M_4;
   8'd33: r_NOTES = M_3;
   8'd35: r_NOTES = M_2;
   8'd37: r_NOTES = M_5;
   8'd39: r_NOTES = 0; 
   8'd41: r_NOTES = M_5;
   8'd42: r_NOTES = 0;    
   8'd45: r_NOTES = M_6;  
   8'd47: r_NOTES = M_5;   
   8'd49: r_NOTES = M_4;
   8'd51: r_NOTES = M_2;
   8'd53: r_NOTES = M_1;
   8'd57: r_NOTES = 0;
   8'd58: r_NOTES = M_3;
   8'd59: r_NOTES = 0;
   8'd60: r_NOTES = M_3;
   8'd61: r_NOTES = 0;
   8'd62: r_NOTES = M_3; 
   8'd64: r_NOTES = 0;
   8'd65: r_NOTES = M_3;
   8'd66: r_NOTES = 0;
   8'd67: r_NOTES = M_3;
   8'd68: r_NOTES = 0;
   8'd69: r_NOTES = M_3; 
   8'd70: r_NOTES = 0;
   8'd73: r_NOTES = M_3;    
   8'd75: r_NOTES = M_5;
   8'd77: r_NOTES = M_1;
   8'd79: r_NOTES = M_2;    
   8'd81: r_NOTES = M_3;  
   8'd85: r_NOTES = 0;
   8'd86: r_NOTES = M_4;
   8'd87: r_NOTES = 0;
   8'd88: r_NOTES = M_4;
   8'd89: r_NOTES = 0;
   8'd90: r_NOTES = M_4;
   8'd92: r_NOTES = 0;
   8'd94: r_NOTES = M_3;
   8'd95: r_NOTES = 0;
   8'd96: r_NOTES = M_3;
   8'd97: r_NOTES = 0;
   8'd98: r_NOTES = M_3; 
   8'd100: r_NOTES = 0;
   8'd102: r_NOTES = M_5;
   8'd103: r_NOTES = 0; 
   8'd104: r_NOTES = M_5;
   8'd105: r_NOTES = M_4;
   8'd107: r_NOTES = M_2;
   8'd109: r_NOTES = M_1;
   8'd113: r_NOTES = 0; 
  endcase
 end
end

always @(posedge clk)
begin
  case (r_NOTES)
    L_5: r_LED_OUT = 11'b11101010100;
    L_6: r_LED_OUT = 11'b11011101001;
    M_1: r_LED_OUT = 11'b11110100111;
    M_2: r_LED_OUT = 11'b10101001110;
    M_3: r_LED_OUT = 11'b11010011101;
    M_4: r_LED_OUT = 11'b10100111011;
    M_5: r_LED_OUT = 11'b01001110110;
    M_6: r_LED_OUT = 11'b10011101111;
    M_7: r_LED_OUT = 11'b00111011101;
    0:r_LED_OUT  = 11'b11111111111;
    endcase
end
assign led=r_LED_OUT;
endmodule


                           IO分配图



                           运行结果
点击下载
music.rar


14.2 警车鸣笛声

module beep(CLK, BEEP);   
input CLK;   
output BEEP;   
reg BEEP; 
reg [27:0] tone;
    reg [14:0] counter;
always @(posedge CLK)
begin
    tone <= tone+1;
end     
wire [6:0] fastsweep = (tone[22] ? tone[21:15] : ~tone[21:15]);   
wire [6:0] slowsweep = (tone[25] ? tone[24:18] : ~tone[24:18]);   
wire [14:0] clkdivider = {2'b01, (tone[27] ? slowsweep : fastsweep), 6'b000000};   
 
always @(posedge CLK)
 begin
 if(counter==0) counter <= clkdivider;
 else counter <= counter-1;
 end     
always @(posedge CLK)
begin
if(counter==0)
BEEP <= ~BEEP;
end    
endmodule   



                      I/O分配

点击下载
beep.rar

14.3 电子琴

module key_music(CLK,KEY,BEEP,LED);
input CLK;
input[7:0]KEY;
output BEEP;
output[7:0]LED;
reg r_BEEP;
reg[7:0]r_LED;
reg[7:0]r_KEY;
reg[22:0]r_count,r_count_end;
reg r_KEY_flag;

  initial r_KEY_flag = 1'b0;
 
always@(posedge CLK)
   begin
     r_count=r_count+1;
     if(r_count == r_count_end)
  begin
   r_count=0;
    if(r_KEY_flag==1'b1)
    r_BEEP= ~r_BEEP;
   else
    r_BEEP = 1'b0;
   end
  end
 
always@(r_count[10:9])
 begin
   r_KEY = KEY;
    if(r_KEY!=8'hff)r_KEY_flag = 1'b1;
    else
  r_KEY_flag = 1'b0;
  case (r_KEY)
   8'b11111110:r_count_end = 20'd47774;
   8'b11111101:r_count_end = 20'd42568;
   8'b11111011:r_count_end = 20'd37919;
   8'b11110111:r_count_end = 20'd35791;
   8'b11101111:r_count_end = 20'd31888;
   8'b11011111:r_count_end = 20'd28409;
   8'b10111111:r_count_end = 20'd25309;
   8'b01111111:r_count_end = 20'd23912;
      default r_count_end = 20'hfffff;
  endcase
 end
assign BEEP=r_BEEP;
assign LED = r_KEY;
endmodule



               I/O分配表

点击下载key_music.rar


工程师
2012-12-18 20:01:07     打赏
25楼

进程15、DS18B20温度计

     单总线的DS18B20硬件连接确实简单,软件读写过程却挺复杂的,花费了不少的时间。部分代码:

//----------芯片复位-----------
 begin        
  cnt <= cnt + 1;
   if(cnt < 'd500)
     begin
        link <= 1;
        dq_out <= 0;
   end
  else if(cnt < 'd1000)
   begin
       link <= 0;
   end
  else  begin
      cnt <= 0;
     state <= WRITE_CC1;
     data_w <= 8'hcc;
     cnt_bit <= 0;
   end
  end 
   
//-------写命令44H---------------
 begin          
   cnt <= cnt + 1;
      if(cnt < 'd5)
         begin
    l       ink <= 1;
           dq_out <= 0;
        end 
    else if(cnt < 'd60)
     begin
          dq_out <= data_w[cnt_bit];
     end
    else if(cnt < 'd65)
       begin
           link <= 0;
      end
    else begin
        cnt <= 0;
        cnt_bit <= cnt_bit + 1;
            if(cnt_bit == 'd7)
               begin
                cnt_bit <= 0;
                state <= WAIT_800MS;
              end
     end
    end
//-------------读温度--------------
 begin                
cnt <= cnt + 1;
   if(cnt < 'd3)
      begin
        link <= 1;
        dq_out <= 0;
     end
  else if(cnt == 'd3)
      link <= 0;
  else if(cnt == 'd12)
       data_r[cnt_bit] <= dq_in;
 else if(cnt > 'd65)
 begin
     cnt <= 0;
     cnt_bit <= cnt_bit + 1;
      if(cnt_bit == 'd7)
         begin
          cnt_bit <= 0;
         temp[15:8] <= data_r;
         state <= RESET1;
    end
  end

end 

//-------------BCD码处理---------------
module bin2bcd(data,bcd_out);
input [15:0] data;
output [11:0] bcd_out;
reg [11:0] bcd_out;
reg [13:0] temp;
reg [11:0] result;
always @(data)
 begin
 temp[13:0] = data[3:0]*625;
 result[3:0] = temp/1000;  //小数部分要乘以 0.625,这里避免浮点运算
  bcd_out[11:8]=data[11:4]/10;
  bcd_out[7:4] = data[11:4]%10;
  bcd_out[3:0] = result[3:0];
 end
endmodule

 LED数码显示部分省略。


                                      
                                          运行结果


                              I/O分配表

点击下载ds18b20.rar
              


工程师
2012-12-18 20:55:15     打赏
26楼
版主过奖了,感觉要入门FPGA还是需要费一番功夫的,我还是菜鸟。

工程师
2013-01-01 14:21:29     打赏
27楼

 2013年第一天,祝愿各位学习进步!

进程16、可逆计数器
    实验使用了3只按键,对按键过程进行了消抖处理,分别作为“清零”、“向下计数”、“向上计数”使用。使用了5位数码LED来显示双向可逆计数值,计数范围从0到99999 。该试验如果连接外部机械开关或光电开关,可以很方便的改装成生产线上实用的产品计数器。

//按键消抖:
always @ (posedge clk or negedge rst_n)
    begin
  if(!rst_n)
   begin
    key3_samp <= 1'b1;
    key2_samp <= 1'b1;
    key1_samp <= 1'b1;
   end
  else
   begin
    key3_samp <=sw3;
    key2_samp <=sw2;
    key1_samp <=sw1;
   end
 end
always @ (posedge clk or negedge rst_n)
    begin
  if(!rst_n)
   begin
    key3_samp_r <= 1'b1;
    key2_samp_r <= 1'b1;
    key1_samp_r <= 1'b1;
   end
  else
   begin
    key3_samp_r <=key3_samp;
    key2_samp_r <=key2_samp;
    key1_samp_r <=key1_samp;
   end
 end 
assign key3_sacn=key3_samp_r&(~key3_samp);
assign key2_sacn=key2_samp_r&(~key2_samp);
assign key1_sacn=key1_samp_r&(~key1_samp);

always @ (posedge clk or negedge rst_n)
    begin
  if(!rst_n)
   delay_cnt <=20'h0;
  else if(key3_scan||key2_scan||key1_scan)
   delay_cnt <=20'h0;
  else
   delay_cnt <=delay_cnt +1'b1;
 end

always @ (posedge clk or negedge rst_n)
    begin
  if(!rst_n)
   begin
    key3_rst <= 1'b1;
    key2_rst <= 1'b1;
    key1_rst <= 1'b1;
   end
  else
   if(delay_cnt==20'hfffff)
    begin
     key3_rst <=sw3;
     key2_rst <=sw2;
     key1_rst <=sw1;
    end
 end 

always @ (posedge clk or negedge rst_n)
    begin
  if(!rst_n)
   begin
    key3_rst_r <= 1'b1;
    key2_rst_r <= 1'b1;
    key1_rst_r <= 1'b1;
   end
  else
   begin
    key3_rst_r <=key3_rst;
    key2_rst_r <=key2_rst;
    key1_rst_r <=key1_rst;
   end
 end  
assign key3_low=key3_rst_r &(~key3_rst);
assign key2_low=key2_rst_r &(~key2_rst);
assign key1_low=key1_rst_r &(~key1_rst);

//计数:
always @ (posedge clk or negedge rst_n)
    begin
  if(!rst_n)
   Number <= 0;
  else
   if(key3_low)
    begin
    Number<= Number+1'b1;
    if(Number >99998)Number <=0
;//加1溢出时,由于非阻塞语句,使得上下2条语句同时执行,比较值要少1
    end
   else
   if(key2_low)
    begin
     Number<= Number-1'b1;
     if(Number ==5'h20000)Number <=99999
;//减1溢出时,道理同上
    end
   else
   if(key1_low)
    Number<= 0;
  end

//数码LED段码扫描:
always @(cnt_scan)
begin
   case(cnt_scan[15:13])
       3'b000 :
          DIG = 8'b1111_1110;
       3'b001 :
          DIG = 8'b0111_1111;
       3'b010 :
          DIG = 8'b1011_1111;
       3'b011 :
          DIG = 8'b1101_1111;
       3'b100 :
         DIG = 8'b1110_1111;
       3'b101 :
         DIG = 8'b1111_0111;
       3'b110 :
          DIG = 8'b1111_1011;
       3'b111 :
         DIG = 8'b1111_1101;
       default :
          DIG = 8'b1111_1110;
    endcase
end
always@(DIG)
为了大家不偷懒,就不上传完整代码了。

                               I/O分配图


                            运行结果

点击下载key_count.rar


工程师
2013-01-04 20:47:22     打赏
28楼

进程17、LCD数字时钟

     将1602LCD组合到DS1302数字时钟模块中,实现LCD数字时钟+LED数字时钟。
顶层模块:
module DS1302(
  CLK, RSTn, 
  SEG, DIG,
  RST,
  SCLK,
  SIO,
  SEC_Data,
  MIN_Data,
  HOU_Data,
  LED,
  YELLOW,
  lcd_rs,
  lcd_rw,
  lcd_en,
  lcd_data,
 );

     input CLK;
  input RSTn;
  input [7:0]KEY;
  output [7:0]SEG;
  output [7:0]DIG;
 
  output RST;
  output SCLK;
  inout SIO;
  output [7:0]SEC_Data;
  output [7:0]MIN_Data;
  output [7:0]HOU_Data;
  output [7:0]LED;
     output [2:0]YELLOW;
  wire [3:0]Data7;
  wire [3:0]Data6;
  wire [3:0]Data5;
  wire [3:0]Data4;
  wire [3:0]Data3;
  wire [3:0]Data2;
  wire [3:0]Data1;
  wire [3:0]Data0;
//------------------------------------------------------------ 
  output         lcd_rs     ;
  output         lcd_rw   ;
  output         lcd_en   ;
  output  [7:0]  lcd_data ;


 wire lcd_rs;
  wire lcd_rw;
  wire lcd_en;
 wire [7:0]lcd_data;
  lcd1602_module U5
   
  (
  .CLK(CLK ),
  .RSTn(RSTn ),
  .lcd_rs(lcd_rs),
  .lcd_rw (lcd_rw),
  .lcd_en(lcd_en),
  .lcd_data(lcd_data),
  .Data7 ( Data7 ),
   .Data6 ( Data6 ),
   .Data5 ( Data5 ),
   .Data4 ( Data4 ),
   .Data3 ( Data3 ),
   .Data2 ( Data2 ),
   .Data1 ( Data1 ),
   .Data0 ( Data0 )
   );
endmodule

LCD1602模块
module lcd1602_module(CLK    ,
      RSTn   ,
      lcd_rs     ,
      lcd_rw     ,
      lcd_en     ,
      lcd_data,
      Data7,Data6,Data5,Data4,Data3,Data2,Data1,Data0
      );
//输入输出信号定义
input          CLK    ;//系统时钟输入
input          RSTn   ;//系统复位信号,低电平有效
output         lcd_rs     ;//lcd的寄存器选择输出信号
output         lcd_rw     ;//lcd的读、写操作选择输出信号
output         lcd_en     ;//lcd使能信号
output  [7:0]  lcd_data   ;//lcd的数据总线(不进行读操作,故为输出)
input [3:0] Data7;
input [3:0] Data6;
input [3:0] Data5;
input [3:0] Data4;
input [3:0] Data3;
input [3:0] Data2;
input [3:0] Data1;
input [3:0] Data0;

//寄存器定义
reg            lcd_rs     ;
reg            clk_div    ;
reg     [17:0] delay_cnt  ;
reg     [7:0]  lcd_data   ;
reg     [4:0]  char_cnt   ;  
reg     [7:0]  data_disp  ;
reg     [9:0]  state      ;  
parameter    idle   = 10'b000000000,
      clear  = 10'b000000001,  
      set_function = 10'b000000010,  
      switch_mode = 10'b000000100,  
      set_mode     = 10'b000001000,  
      shift    = 10'b000010000,  
      set_ddram1   = 10'b000100000,  
      set_ddram2   = 10'b001000000,  
      write_ram1   = 10'b010000000, 
      write_ram2   = 10'b100000000; 
assign lcd_rw = 1'b0;     
assign lcd_en = clk_div; 
always@(posedge CLK or negedge RSTn)
begin
 if(!RSTn)
  begin
   delay_cnt<=18'd0;
   clk_div<=1'b0;
  end
 else if(delay_cnt==18'd249999)
  begin
   delay_cnt<=18'd0;
   clk_div<=~clk_div;
  end
 else
  begin
   delay_cnt<=delay_cnt+1'b1;
   clk_div<=clk_div;
  end
end
always@(posedge clk_div or negedge RSTn) //State Machine
begin
 if(!RSTn)
  begin
   state   <= idle;
   lcd_data <= 8'bzzzzzzzz;
   char_cnt <= 5'd0;   
  end
 else
  begin
  case(state)
  idle: begin         state <= clear;
     lcd_data <= 8'bzzzzzzzz;
    end
  clear: begin        state <= set_function;
     lcd_rs<=1'b0;
     lcd_data <= 8'b00000001;   
    end  
  set_function:         begin
     state <= switch_mode;
     lcd_rs<=1'b0;
     lcd_data <= 8'b00111000;    
    end
  switch_mode:          begin
     state <= set_mode;
     lcd_rs<=1'b0;
     lcd_data <= 8'b00001100;
    end 
  set_mode:begin          state <= shift; 
     lcd_rs<=1'b0;
     lcd_data <= 8'b00000110;
    end
  shift: begin        state <= set_ddram1;
     lcd_rs<=1'b0;
     lcd_data <= 8'b0001_0000;   
    end  
  set_ddram1:   
    begin
     state <= write_ram1;
     lcd_rs<=1'b0;
     lcd_data <= 8'b1000_0000;//Line1
    end
  set_ddram2:          begin
     state <= write_ram2;
     lcd_rs<=1'b0;
     lcd_data <= 8'b1100_0000;//Line2  
    end
  write_ram1:    
    begin         
     if(char_cnt <=5'd15)       
//5'd15这个坐标我做了修改
      begin
       char_cnt <= char_cnt + 1'b1;
       lcd_rs<=1'b1;
       lcd_data <= data_disp;
       state <= write_ram1;
      end
     else
      begin
       state <= set_ddram2; 
      end    
    end
  write_ram2:    
    begin         
     if(char_cnt <=5'd30)   
//5'd30这个坐标我做了修改

      begin
       char_cnt <= char_cnt + 1'b1;
       lcd_rs<=1'b1;
       lcd_data <= data_disp;
       state <= write_ram2;
      end
     else
      begin
       char_cnt <=5'd0;
       state <= shift; 
      end    
    end
  default:  state <= idle;
  endcase
  end
end

always @(char_cnt)  
begin
 case (char_cnt)
 5'd2: data_disp  = "D"; 
 5'd3: data_disp  = "S"; 
 5'd4: data_disp  = "1"; 
 5'd5: data_disp  = "3"; 
 5'd6: data_disp  = "0"; 
 5'd7: data_disp  = "2"; 
 5'd9: data_disp  = "C"; 
 5'd10: data_disp  = "L"; 
 5'd11: data_disp = "O"; 
 5'd12: data_disp  = "C"; 
 5'd13: data_disp  = "K"; 
  5'd20: data_disp = Data7+48; 
 5'd21: data_disp = Data6+48;
 5'd22: data_disp = ":"; 
 5'd23: data_disp = Data4+48;
 5'd24: data_disp = Data3+48; 
 5'd25: data_disp = ":"; 
 5'd26: data_disp = Data1+48; 
 5'd27: data_disp = Data0+48; 
 default :   data_disp =" "; 
 endcase
end
endmodule

其余代码省略,参考进程10


           运行结果,可以发现LCD内容要比LED数码管内容显示时间要慢大约0.5秒,可能是因为LCD的是慢扫描器件所致。


                    LCD1602 I/O分配图

点击下载DS1302.rar


工程师
2013-01-08 15:14:38     打赏
29楼

进程18、I2C

   实验中设置接口板的DIP开关作为I2C“写”数据输入口,按键1执行“读”操作,按键8执行“写”操作。数码LED的高2位显示“读”的十六进制值,最低2位显示“写”的数据十六进制值。运行时拨动DIP开关到欲写入的值,按一下按键8写入,然后按一下按键1读出。

input CLK,RSTn;
output scl;
inout  sda;
input[7:0] data_in;//DIP开关
input wr_input;
input rd_input;
reg scl;
reg sda_buf;
reg link;
reg phase0,phase1,phase2,phase3;
//EEPROM操作部分代码
parameter
start=4'b0000, //开始
step1=4'b0001, //第1位
step2=4'b0010,//第2位
step3=4'b0011, //第3位
step4=4'b0100, //第4位
step5=4'b0101, //第5位
step6=4'b0110, //第6位
step7=4'b0111, //第7位
step8=4'b1000, //第8位
ack=4'b1001,   //确认位
stop=4'b1010; //结束位
inout  sda;//I2C数据线
assign sda=(link)? sda_buf:1'bz;
//读EEPROM
begin 
if(phase0)
scl<=1;
else if(phase2)
scl<=0;
case(i2c_state)
ini: begin
case(inner_state)
start: begin
if(phase1) begin
link<=1;
sda_buf<=0;
 end
if(phase3&&link) begin
inner_state<=step1;
sda_buf<=1;
link<=1;
end
 end
step1:
if(phase3) begin
sda_buf<=0;
link<=1;
inner_state<=step2;
end
step2:
if(phase3) begin
sda_buf<=1;
link<=1;
inner_state<=step3;
end
step3:
if(phase3) begin
sda_buf<=0;
link<=1;
inner_state<=step4;
end
step4:
if(phase3) begin
sda_buf<=0;
link<=1;
inner_state<=step5;
end
step5:
if(phase3) begin
sda_buf<=0;
link<=1;
inner_state<=step6;
end
step6:
if(phase3) begin
sda_buf<=0;
link<=1;
inner_state<=step7;
end
step7:
if(phase3) begin
sda_buf<=0;
link<=1;
inner_state<=step8;
end
step8:
if(phase3) begin
link<=0;
inner_state<=ack;
end
ack: begin
if(phase0)
sda_buf<=sda;
if(phase1) begin
if(sda_buf==1)
main_state<=2'b00;
end
if(phase3) begin
link<=1;
sda_buf<=addr[7];
inner_state<=step1;
i2c_state<=sendaddr;
end
end
endcase
end

//数码LED部分代码
output[7:0] DIG;//数码管使能
output[7:0] SEG;//数码管段数据
reg[7:0] SEG;
reg[7:0] DIG;
reg[15:0] cnt_scan;
reg[5:0] SEG_buf;

always @(cnt_scan)
begin
      case(cnt_scan[15:13])
       3'b000 : DIG = 8'b1111_1110;
       3'b001 : DIG = 8'b1111_1101;
       3'b010 : DIG = 8'b1111_1011;
       3'b011 : DIG = 8'b1111_0111;
       3'b100 : DIG = 8'b1110_1111;
       3'b101 : DIG = 8'b1101_1111;
       3'b110 : DIG = 8'b1011_1111;
       3'b111 : DIG = 8'b0111_1111;
       default :DIG = 8'b1111_1110;
    endcase
end
always@(DIG)
begin
 case(DIG)
  8'b11111101:   SEG_buf=writeData_reg[7:4];
  8'b11111110:   SEG_buf=writeData_reg[3:0];   
  8'b10111111:   SEG_buf=readData_reg[3:0];
  8'b01111111:   SEG_buf=readData_reg[7:4]; 
  default:             SEG_buf=9'h10;
  endcase
end

always@(SEG_buf)
begin 
 case(SEG_buf)
  4'b0000:SEG=8'b1100_0000;
  4'b0001:SEG=8'b1111_1001;
  4'b0010:SEG=8'b1010_0100;
  4'b0011:SEG= 8'b1011_0000;
  4'b0100:SEG=8'b1001_1001;
  4'b0101:SEG=8'b1001_0010;
  4'b0110:SEG=8'b1000_0010;
  4'b0111:SEG=8'b 1111_1000;
  4'b1000:SEG=8'b1000_0000;
  4'b1001:SEG=8'b1001_0000;
  4'b1010:SEG=8'b1000_1000;
  4'b1011:SEG=8'b1000_0011;
  4'b1100:SEG=8'b1100_0110;
  4'b1101:SEG=8'b1001_0001;
  4'b1110:SEG= 8'b1000_0110;
  4'b1111:SEG=8'b1000_1110;
  default:SEG=8'hff;
  endcase
end


    
                            写入5AH


 
                             读出写入的数据


 
                            I/O分配表

点击下载i2c.rar


工程师
2013-01-17 14:38:47     打赏
30楼

进程19、数字频率计

  门控信号发生器从50M时钟分频出门控信号gate_out,在gate_out的时间间隔内对信号频率的变化次数FQ_in进行计数,则信号频率f=FQ_in/gate_out.这里设定门控信号时间为1秒,在gate_out的上升沿开始对FQ_in计数,在gate_out的下降沿将7位的计数值锁存,然后送LED数码管显示。LED数码显示已经考虑到高位无用零消隐的功能。接口板上LCD1602的RS引脚用来作为外部待测信号输入端。要求输入的信号是TTL电平方波。黄色LED用来监视gate_out状态。
//部分代码
module frequ(
 CLK,
 RESET,
 FQ_in,
 sm_seg,
 sm_bit,
 YELLOW
 );
 
input CLK;
input RESET;
input FQ_in;
output YELLOW;
//门控信号
reg gate_out;
reg gate;
always @(posedge gate or negedge RESET)
begin
if(!RESET )
gate_out <=0;
else
gate_out<=~gate_out;
end
//---------------------------------
always @(posedge clk_1khz or negedge RESET)
begin
if(!RESET)
gate<=0;
   else
gate<=clk_1hz;
end
assign YELLOW=gate_out;
//----------------------------------------
//频率计数
reg [3:0]FqCount0,FqCount1,FqCount2,FqCount3,FqCount4,FqCount5,FqCount6;
reg [3:0] Fqout0,Fqout1,Fqout2,Fqout3,Fqout4,Fqout5,Fqout6;
reg[2:0]counter6;
always @(posedge FQ_in or negedge RESET)
begin
if(!RESET)
begin
FqCount0<=4'b0000;FqCount1<=4'b0000;FqCount2<=4'b0000;FqCount3<=4'b0000;
FqCount4<=4'b0000;FqCount5<=4'b0000;FqCount6<=4'b0000;
Fqout0<=4'b0000;Fqout1<=4'b0000;Fqout2<=4'b0000;Fqout3<=4'b0000;
Fqout4<=4'b0000;Fqout5<=4'b0000;Fqout6<=3'b000;
end else begin if(gate_out==1) begin
counter6<=0;
if((FqCount5==4'b1001)&&(FqCount4==4'b1001)&&(FqCount3==4'b1001)
&&(FqCount2==4'b1001)&&(FqCount1==4'b1001)&&(FqCount0==4'b1001)) begin
FqCount0<=4'b0000;FqCount1<=4'b0000;FqCount2<=4'b0000;FqCount3<=4'b0000;
FqCount4<=4'b0000;FqCount5<=4'b0000;FqCount6<=FqCount6+4'b0001; end else begin
if((FqCount4==4'b1001)&&(FqCount3==4'b1001)&&(FqCount2==4'b1001)
&&(FqCount1==4'b1001)&&(FqCount0==4'b1001)) begin
FqCount0<=4'b0000;FqCount1<=4'b0000;FqCount2<=4'b0000;FqCount3<=4'b0000;
FqCount4<=4'b0000;FqCount5<=4'b0001+FqCount5;FqCount6<=FqCount6;
end else begin if((FqCount3==4'b1001)&&(FqCount2==4'b1001)&&(FqCount1==4'b1001)
&&(FqCount0==4'b1001)) begin
FqCount0<=4'b0000;FqCount1<=4'b0000;FqCount2<=4'b0000;FqCount3<=4'b0000;
FqCount4<=4'b0001+FqCount4;FqCount5<=FqCount5;FqCount6<=FqCount6;
end else begin
if((FqCount2==4'b1001)&&(FqCount1==4'b1001)&&(FqCount0==4'b1001))begin
FqCount0<=4'b0000;FqCount1<=4'b0000;FqCount2<=4'b0000;FqCount3<=4'b0001+FqCount3;
FqCount4<=FqCount4;FqCount5<=FqCount5;FqCount6<=FqCount6;
end else begin if((FqCount1==4'b1001)&&(FqCount0==4'b1001))begin
FqCount0<=4'b0000;FqCount1<=4'b0000;FqCount2<=4'b0001+FqCount2;FqCount3<=FqCount3;
FqCount4<=FqCount4;FqCount5<=FqCount5;FqCount6<=FqCount6;
end else begin if(FqCount0==4'b1001) begin
FqCount0<=4'b0000;FqCount1<=4'b0001+FqCount1;FqCount2<=FqCount2;FqCount3<=FqCount3;
FqCount4<=FqCount4;FqCount5<=FqCount5;FqCount6<=FqCount6;
end else begin
FqCount0<=4'b0001+FqCount0;FqCount1<=FqCount1;FqCount2<=FqCount2;FqCount3<=FqCount3;
FqCount4<=FqCount4;FqCount5<=FqCount5;FqCount6<=FqCount6;
end end end end end end end else begin
if(counter6==2'b01) begin
FqCount0<=4'b0000;FqCount1<=4'b0000;FqCount2<=4'b0000;FqCount3<=4'b0000;
FqCount4<=4'b0000;FqCount5<=4'b0000;FqCount6<=4'b0000;
end else begin
counter6<=counter6+1;Fqout0<=FqCount0;Fqout1<=FqCount1;Fqout2<=FqCount2;Fqout3<=FqCount3;
Fqout4<=FqCount4;Fqout5<=FqCount5;Fqout6<=FqCount6;
end end end end
//---------------------------------------------------
//显示
output  [7:0] sm_seg;
output  [7:0] sm_bit ;
reg  [7:0] sm_seg;
reg [7:0] sm_bit ;
reg[7:0] dataout_buf;
always @(counter4)
begin
case(counter4[12:10])
3'b000 :  sm_bit = 8'b1111_1110;
3'b001 :  sm_bit = 8'b1111_1101;
3'b010 :  sm_bit = 8'b1111_1011;
3'b011 :  sm_bit = 8'b1111_0111;
3'b100 :  sm_bit = 8'b1110_1111;
3'b101 :  sm_bit = 8'b1101_1111;
3'b110 :  sm_bit = 8'b1011_1111;
3'b111 :   sm_bit = 8'b1111_1111;
default :  sm_bit = 8'b1111_1110;
endcase
end
//-----------------------------
always@(sm_bit)
begin
case(sm_bit)
8'b1111_1110: dataout_buf=Fq_data0;
8'b1111_1101: begin
if(Fq_data6==0 && Fq_data5==0 && Fq_data4==0 && Fq_data3==0 && Fq_data2==0 && Fq_data1==0)
dataout_buf=10;
else
dataout_buf=Fq_data1;
end
8'b1111_1011: begin
if(Fq_data6==0 && Fq_data5==0 && Fq_data4==0 && Fq_data3==0 && Fq_data2==0 )
dataout_buf=10;
else
dataout_buf=Fq_data2;
end
8'b1111_0111: begin
if(Fq_data6==0 && Fq_data5==0 && Fq_data4==0 &&Fq_data3==0)
dataout_buf=10;
else
dataout_buf=Fq_data3; 
end
8'b1110_1111: begin
if(Fq_data6==0 && Fq_data5==0 && Fq_data4==0)
dataout_buf=10;
else
dataout_buf=Fq_data4;
end
8'b1101_1111: begin
if(Fq_data6==0 &&Fq_data5==0)
dataout_buf=10;
else
dataout_buf=Fq_data5;
end
8'b1011_1111: begin
if(Fq_data6==0)
dataout_buf = 10;
else
dataout_buf=Fq_data6;
end
default:
dataout_buf=10;
endcase
end
//-------------------
always@(dataout_buf)
begin
case(dataout_buf)
4'h0 : sm_seg = 8'hc0;
4'h1 : sm_seg = 8'hf9;
4'h2 : sm_seg = 8'ha4;
4'h3 : sm_seg = 8'hb0;
4'h4 : sm_seg = 8'h99;
4'h5 : sm_seg = 8'h92;
4'h6 : sm_seg = 8'h82;
4'h7 : sm_seg = 8'hf8;
4'h8 : sm_seg = 8'h80;
4'h9 : sm_seg = 8'h90;
4'ha : sm_seg = 8'hff;
endcase
end

             从示波器标准信号输入信号频率为1000HZ的方波



   I/O分配图

点击下载frequ.rar


共30条 3/3 1 2 3 跳转至

回复

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