• Verilog实现IIC通讯第二版


    HMC5883三轴磁力传感器IIC通讯模块的VerilogHDL的实现

    上一版并没有实现我想要的功能

    0.0.1版   正在修订中   2013/9/2

      1 //date :2013/7/7
      2    //designer :pengxiaoen
      3    //synthesizer:QuartusII 12.1
      4    //function : IIC实现HMC5883的通讯  50M /(400k × 4)= 32
      5    
      6    
      7  `define WriteAddress  8'h3c
      8  `define ReadAddress   8'h3d
      9    
     10 `define RegAAddress   8'h00  //配置寄存器A
     11 `define RegBAddress   8'h01  //配置寄存器B
     12 `define ModelAddress  8'h02  //模式寄存器
     13 `define X_MSBAddress  8'h03  //X MSB寄存器
     14 `define X_LSBAddress  8'h04
     15 `define Z_MSBAddress  8'h05
     16 `define Z_LSBAddress  8'h06
     17 `define Y_MSBAddress  8'h07
     18 `define Y_LSBAddress  8'h08
     19 `define STATEAddress  8'h09  //状态寄存器
     20 `define IdentifyAAddress  8'h10  //识别寄存器A 
     21 `define IdentifyBAddress  8'h10
     22 `define IdentifyCAddress  8'h10
     23   
     24 `define INITIAL  0
     25 `define DELAY    1
     26 `define MEASURE  2
     27   
     28 `define START  3
     29 `define Re     4
     30 `define Se     5
     31 `define STOP   6
     32   
     33   //`default_nettype none
     34   
     35   module HMC5883_2 (
     36                       clock,reset,
     37                             sda,scl,
     38                             out_seg,
     39                            
     40                             sel_seg,
     41                                      IIC_result
     42                             );
     43                             
     44   input clock,reset;
     45   inout sda,scl;
     46   output reg [7:0]out_seg;
     47   output reg IIC_result;
     48   
     49   output reg [5:0]sel_seg;
     50   
     51   reg [7:0] SEND_buffer;
     52   reg [7:0] Re_buffer ;
     53   reg sda_reg;
     54   reg scl_reg;
     55   reg ack_reg; 
     56   reg sda_enable;
     57   reg scl_enable;
     58   
     59   reg IC_state;
     60   reg n_IC_state;
     61   reg [2:0]state;           //当前状态寄存器
     62   reg state_finish_flag ;   //
     63   
     64   reg [5:0] scl_4;
     65   reg [3:0] step_counter;
     66   reg [3:0] clk_temp ;
     67   
     68 //==============================================================================================  
     69 //-------------时钟控制模块------------------start---------------
     70   always @ (posedge clock or negedge reset)
     71   if (!reset)
     72       begin 
     73            clk_temp <= 4'd0;
     74             scl_4 <= 6'd0;
     75        end 
     76   else if (clk_temp==4'd15)
     77            begin
     78                clk_temp <= 4'd0;
     79                if (state_finish_flag) scl_4 <= 6'd0;
     80                else if (scl_4 == 6'b111_111)   //这里是一个保护机制,可以设置一个flag
     81                       scl_4 <= 6'b111_111;
     82                     else  scl_4 <= scl_4 + 1;
     83           end 
     84        else clk_temp <= clk_temp + 1;
     85 //----------时钟控制模块----------end-----------
     86 
     87 //--------一个检测的pin---------start-----------
     88 always @(posedge clock or negedge reset)
     89 if(!reset)
     90    IIC_result <= 1'd0;
     91 else if(scl_4 == 6'b111_111)
     92        IIC_result <= 1'd1;
     93         else ; 
     94 //-----------一个检测的pin-------end----------        
     95         
     96 //-------延时模块----5us------start--------
     97  reg [7:0] delay_counter;
     98  reg delay_enable;
     99  always @(posedge clock )
    100   if(!delay_enable) 
    101       begin 
    102            delay_counter <= 8'd0;
    103            state_finish_flag <= 1'd0;
    104       end 
    105   else  if(delay_counter == 8'd250)
    106            begin 
    107                state_finish_flag <= 1'd1;
    108                delay_counter <= 8'd0;
    109            end 
    110         else  begin 
    111                     delay_counter <= delay_counter + 1;
    112                         state_finish_flag <= 1'd0;
    113                   end 
    114  //--------------延时模块-------end---------------
    115  
    116  //----------状态机控制模块---------start-------
    117  always @ (posedge clock or negedge reset)
    118  if(!reset) 
    119    IC_state <= `INITIAL;
    120   else IC_state <= n_IC_state;             
    121   
    122  //------------------------------------------ 
    123   always @ (posedge state_finish_flag or negedge reset)
    124   if (!reset)
    125       begin 
    126            SEND_buffer  <= 8'd0;
    127            n_IC_state   <= 1'd0;
    128        end 
    129    else if(IC_state == `INITIAL)
    130       case (step_counter)
    131              0: begin  state <= `START;end 
    132              1: begin  state <= `Se;  SEND_buffer <= `WriteAddress;   end 
    133              2: begin  state <= `Se;  SEND_buffer <= `ModelAddress;   end
    134              3: begin  state <= `Se;  SEND_buffer <= `RegAAddress;   end     
    135              4: begin  state <= `STOP;   end
    136                  
    137                  5: begin  n_IC_state <= `MEASURE;   end
    138              default state <= `START;
    139        endcase 
    140   else if (IC_state == `MEASURE)
    141       case (step_counter)
    142               0: begin  state <= `START; end 
    143               1: begin  state <= `Se;   SEND_buffer <= `WriteAddress; end 
    144               2: begin  state <= `Se;   SEND_buffer <= `X_MSBAddress; end
    145               3: begin  state <= `START; end     
    146               4: begin  state <= `Se;   SEND_buffer <= `ReadAddress;end            
    147               5: begin  state <= `Re;   end
    148               6: begin  state <= `Re;   end
    149               7: begin  state <= `Re;   end
    150               8: begin  state <= `Re;   end
    151               9: begin  state <= `Re;   end
    152              10: begin  state <= `Re;   end
    153              11: begin  state <= `STOP; end
    154                  
    155                  12:begin  n_IC_state <= `INITIAL;  end
    156              default state <= `START;
    157        endcase       
    158        else ;
    159  //----------状态机控制模块----------end--- ---
    160 
    161 //----------执行步骤计数--------start------------ 
    162 always @ (posedge clock  or negedge reset)
    163 if (!reset) begin 
    164     step_counter <= 4'd0;  end 
    165 else  if((IC_state == `INITIAL)&& (state_finish_flag))   begin 
    166              if(step_counter == 4'd5)  step_counter <= 4'd0;  
    167                 else step_counter <= step_counter + 1; end 
    168        else if((IC_state == `MEASURE) && (state_finish_flag))   begin  
    169                  if(step_counter == 4'd12 ) step_counter <= 4'd0;
    170                   else step_counter <= step_counter + 1;     end 
    171                  else ; 
    172 //----------执行步骤计数--------end------------ 
    173                 
    174  //-----------外部数据线 控制模块----start------
    175  always @ (posedge clock or negedge reset)
    176 if(!reset)
    177   begin
    178        Re_buffer <= 8'd0;
    179          sda_enable <= 1'd0; 
    180          scl_enable <= 1'd0;
    181          delay_enable <= 1'd0;
    182   end 
    183  else case (state)
    184      `START : case (scl_4)
    185                  0: begin sda_enable <= 1'd1; scl_enable <= 1'd1; delay_enable <= 1'd0;
    186                                   sda_reg <= 1'd1;  scl_reg <= 1'd0;  end                      
    187                  1: begin sda_reg <= 1'd1;  scl_reg <= 1'd0;  end
    188                  2: begin sda_reg <= 1'd1;  scl_reg <= 1'd1;  end
    189                  3: begin sda_reg <= 1'd0;  scl_reg <= 1'd1;  end 
    190                       4: delay_enable <= 1'd1;
    191                   default  begin sda_reg <= 1'dz;  scl_reg <= 1'dz;  end     
    192               endcase  
    193      `STOP  : case (scl_4)
    194                  0: begin sda_enable <= 1'd1; scl_enable <= 1'd1; delay_enable <= 1'd0;
    195                                sda_reg <= 1'd0;  scl_reg <= 1'd0; end
    196                  1: begin sda_reg <= 1'd0;  scl_reg <= 1'd0; end     
    197                  2: begin sda_reg <= 1'd0;  scl_reg <= 1'd1; end 
    198                  3: begin sda_reg <= 1'd1;  scl_reg <= 1'd1; end
    199                       4: delay_enable <= 1'd1;
    200                   default  begin sda_reg <= 1'dz;  scl_reg <= 1'dz; end
    201                endcase                  
    202       `Se    : case (scl_4)
    203                  0: begin sda_enable <= 1'd1; scl_enable <= 1'd1; delay_enable <= 1'd0;
    204                                sda_reg <= 1'd0;            scl_reg <= 1'd0;  end
    205                  1: begin sda_reg <= SEND_buffer[7];  scl_reg <= 1'd0;  end
    206                  2: begin sda_reg <= SEND_buffer[7];  scl_reg <= 1'd1;  end
    207                  3: begin sda_reg <= SEND_buffer[7];  scl_reg <= 1'd1;  end
    208                  4: begin                             scl_reg <= 1'd0;  end
    209                  5: begin sda_reg <= SEND_buffer[6];  scl_reg <= 1'd0;  end
    210                  6: begin sda_reg <= SEND_buffer[6];  scl_reg <= 1'd1;  end
    211                  7: begin sda_reg <= SEND_buffer[6];  scl_reg <= 1'd1;  end
    212                  8: begin                             scl_reg <= 1'd0;  end
    213                  9: begin sda_reg <= SEND_buffer[5];  scl_reg <= 1'd0;  end
    214                 10: begin sda_reg <= SEND_buffer[5];  scl_reg <= 1'd1;  end
    215                 11: begin sda_reg <= SEND_buffer[5];  scl_reg <= 1'd1;  end
    216                 12: begin                             scl_reg <= 1'd0;  end
    217                 13: begin sda_reg <= SEND_buffer[4];  scl_reg <= 1'd0;  end
    218                 14: begin sda_reg <= SEND_buffer[4];  scl_reg <= 1'd1;  end
    219                 15: begin sda_reg <= SEND_buffer[4];  scl_reg <= 1'd1;  end
    220                 16: begin                             scl_reg <= 1'd0;  end
    221                 17: begin sda_reg <= SEND_buffer[3];  scl_reg <= 1'd0;  end
    222                 18: begin sda_reg <= SEND_buffer[3];  scl_reg <= 1'd1;  end
    223                 19: begin sda_reg <= SEND_buffer[3];  scl_reg <= 1'd1;  end
    224                 20: begin                             scl_reg <= 1'd0;  end
    225                 21: begin sda_reg <= SEND_buffer[2];  scl_reg <= 1'd0;  end
    226                 22: begin sda_reg <= SEND_buffer[2];  scl_reg <= 1'd1;  end
    227                 23: begin sda_reg <= SEND_buffer[2];  scl_reg <= 1'd1;  end
    228                 24: begin                             scl_reg <= 1'd0;  end
    229                 25: begin sda_reg <= SEND_buffer[1];  scl_reg <= 1'd0;  end
    230                 26: begin sda_reg <= SEND_buffer[1];  scl_reg <= 1'd1;  end
    231                 27: begin sda_reg <= SEND_buffer[1];  scl_reg <= 1'd1;  end
    232                 28: begin                             scl_reg <= 1'd0;  end
    233                 29: begin sda_reg <= SEND_buffer[0];  scl_reg <= 1'd0;  end
    234                 30: begin sda_reg <= SEND_buffer[0];  scl_reg <= 1'd1;  end
    235                 31: begin sda_reg <= SEND_buffer[0];  scl_reg <= 1'd1;  end
    236                 //此时序之后必须释放掉sda控制权  等待响应
    237                 32: begin  sda_enable <= 1'd0; scl_enable <= 1'd0; delay_enable <= 1'd1;
    238                                 ack_reg <= 1'd0;           scl_reg <= 1'd0;  end //这里出现了一个警告,因为ack_reg没有利用到
    239                 33: begin  ack_reg <= sda;            scl_reg <= 1'd0;  end
    240                      34: begin  ack_reg <= sda;            scl_reg <= 1'd1;  end
    241                 35: begin  ack_reg <= sda;            scl_reg <= 1'd1;  end
    242                //此时IC有可能在一个时钟下来不及响应,从而导致主机没有接收到响应信号
    243                 default  begin                        scl_reg <= 1'dz;      end                  
    244              endcase  
    245                   
    246       `Re  : case (scl_4)
    247                      0: begin  sda_enable <= 1'd0; scl_enable <= 1'd1; delay_enable <= 1'd0;
    248                                                        scl_reg <= 1'd0;  end
    249                      1: begin                        scl_reg <= 1'd0;  end
    250                      2: begin                        scl_reg <= 1'd1;  end 
    251                      3: begin Re_buffer[7] <= sda;   scl_reg <= 1'd1;  end
    252                      4: begin                        scl_reg <= 1'd0;  end
    253                      5: begin                        scl_reg <= 1'd0;  end
    254                      6: begin                        scl_reg <= 1'd1;  end
    255                      7: begin Re_buffer[6] <= sda;   scl_reg <= 1'd1;  end
    256                      8: begin                        scl_reg <= 1'd0;  end
    257                      9: begin                        scl_reg <= 1'd0;  end
    258                     10: begin                        scl_reg <= 1'd1;  end
    259                     11: begin Re_buffer[5] <= sda;   scl_reg <= 1'd1;  end
    260                     12: begin                        scl_reg <= 1'd0;  end
    261                     13: begin                        scl_reg <= 1'd0;  end
    262                     14: begin                        scl_reg <= 1'd1;  end
    263                     15: begin Re_buffer[4] <= sda;   scl_reg <= 1'd1;  end
    264                     16: begin                        scl_reg <= 1'd0;  end
    265                     17: begin                        scl_reg <= 1'd0;  end
    266                     18: begin                        scl_reg <= 1'd1;  end
    267                     19: begin Re_buffer[3] <= sda;   scl_reg <= 1'd1;  end
    268                     20: begin                        scl_reg <= 1'd0;  end
    269                     21: begin                        scl_reg <= 1'd0;  end
    270                     22: begin                        scl_reg <= 1'd1;  end
    271                     23: begin Re_buffer[2] <= sda;   scl_reg <= 1'd1;  end
    272                     24: begin                        scl_reg <= 1'd0;  end
    273                     25: begin                        scl_reg <= 1'd0;  end
    274                     26: begin                        scl_reg <= 1'd1;  end
    275                     27: begin Re_buffer[1] <= sda;   scl_reg <= 1'd1;  end
    276                     28: begin                        scl_reg <= 1'd0;  end
    277                     29: begin                        scl_reg <= 1'd0;  end
    278                     30: begin                        scl_reg <= 1'd1;  end
    279                     31: begin Re_buffer[0] <= sda;   scl_reg <= 1'd1;  end
    280                //此时序之后主机夺回sda控制权,延时开始
    281                     32: begin sda_enable <= 1'd1; delay_enable <= 1'd1;
    282                                sda_reg <= 0; scl_reg <= 1'd0;  end
    283                     33: begin  sda_reg <= 0; scl_reg <= 1'd0;  end
    284                     34: begin  sda_reg <= 0; scl_reg <= 1'd1;  end
    285                     35: begin  sda_reg <= 0; scl_reg <= 1'd1;  end
    286                     default  begin sda_reg <= 1'dz;    scl_reg <= 1'dz;end
    287                endcase
    288       endcase
    289  //-------外部数据线 控制模块----------end---------------
    290  
    291  assign sda = sda_enable ? sda_reg : 1'dz ;
    292  assign scl = scl_enable ? scl_reg : 1'dz ;
    293 //==================================================================================== 
    294  
    295  
    296  //--------------数码管显示部分=======只显示了一部分,有待优化============================
    297  always @ ( posedge clock or negedge reset)
    298  if (!reset)
    299    begin 
    300      sel_seg <= 6'b111110;
    301    end 
    302  else if(state_finish_flag)
    303         begin
    304           sel_seg <= {sel_seg[4:0],sel_seg[5]};
    305         end
    306  //------------------------------------------------
    307  always @(posedge clock or negedge reset)
    308  if (!reset) out_seg <= 8'd0;
    309  else 
    310    begin
    311      case (Re_buffer[3:0])  //刚开始这里没有[3:0] 居然没有报错,连个警告都没有,这是为什么呢
    312          4'b0000  :  out_seg<=8'b1100_0000;//0000_0011
    313          4'b0001  :  out_seg<=8'b1111_1001;//1001_1111 
    314          4'b0010  :  out_seg<=8'b1010_0100;//0010_0101 
    315          4'b0011  :  out_seg<=8'b1011_0000;//0000_1101 
    316          4'b0100  :  out_seg<=8'b1001_1001;//1001_1001 
    317          4'b0101  :  out_seg<=8'b1001_0010;//0100_1001 
    318          4'b0110  :  out_seg<=8'b1000_0010;//0100_0001 
    319          4'b0111  :  out_seg<=8'b1111_1000;//0001_1111 
    320          4'b1000  :  out_seg<=8'b1000_0000;//0000_0001 
    321          4'b1001  :  out_seg<=8'b1001_1000;//0001_1001 
    322          4'b1010  :  out_seg<=8'b1000_1000;//0001_0001 
    323          4'b1011  :  out_seg<=8'b1000_0011;//1100_0001 
    324          4'b1100  :  out_seg<=8'b1100_0110;//0110_0011 
    325          4'b1101  :  out_seg<=8'b1010_0001;//1000_0101 
    326          4'b1110  :  out_seg<=8'b1000_0110;//0110_0001 
    327          4'b1111  :  out_seg<=8'b1000_1110;//0111_0001 
    328       endcase 
    329    end 
    330 //-------------------------------================================= 
    331 
    332  endmodule  
    333  
  • 相关阅读:
    尚硅谷韩顺平Linux教程学习笔记
    第15章 自动编码器
    问题总结
    日常问题记录
    SQLServer日常bug记录
    .NetCore使用NLog写入数据库总结
    C#操作XML文档
    C#中的 ?/?:/?? 三者的区别及用法
    git 命令从入门到放弃
    通过反射技术获得类中的所有属性
  • 原文地址:https://www.cnblogs.com/sepeng/p/3258705.html
Copyright © 2020-2023  润新知