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  
原文地址:https://www.cnblogs.com/sepeng/p/3258705.html