用Verilog实现IIC通讯

注意,此代码是错误代码,并不能实现想要的结果。

 之所以留着,因为里面的enable 是独立开来的思想值得借鉴。就是控制单元和运算单元分开(我也是借鉴别人的实现思想)。具体用verilogHDL实现IIC通讯在http://www.cnblogs.com/sepeng/p/3258705.html 里会做到。

  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 MEASURE  1
 26 
 27 `define START  2
 28 `define Re     3
 29 `define Se     4
 30 `define STOP   5
 31 
 32 //`default_nettype none
 33 
 34 module HMC5883_IIC (
 35                     clock,reset,
 36                           sda,scl,
 37                           out_seg,
 38                           
 39                           sel_seg
 40                           );
 41                           
 42 input clock,reset;
 43 inout sda,scl;
 44 output reg [7:0]out_seg;
 45 
 46 output reg [5:0]sel_seg;
 47 
 48 reg [7:0] SEND_buffer;
 49 reg [7:0] Re_buffer ;
 50 reg sda_reg;
 51 reg scl_reg;
 52 reg sda_enable;
 53 reg scl_enable;
 54 
 55 reg IC_state;
 56 reg [2:0]state;           //当前状态寄存器
 57 reg state_finish_flag ;   //
 58 
 59 reg [5:0] clk_counter;
 60 reg [3:0] step_counter;
 61 reg [5:0] clk_temp ;
 62 
 63 
 64 //-------------------------时钟控制模块-------------------------------start------------------
 65 always @ (posedge clock or negedge reset)
 66 if (!reset)
 67     begin 
 68          clk_temp <= 6'd0;
 69           clk_counter <= 6'd0;
 70      end 
 71 else if (clk_temp[5])
 72          begin
 73                  clk_temp <= 6'd0;
 74                  if (state_finish_flag) clk_counter <= 6'd0;
 75                  else if (clk_counter == 6'b111_111)   //这里是一个保护机制,可以设置一个flag
 76                      begin 
 77                          clk_counter <= 6'b111_111;
 78                      end 
 79                  else    clk_counter <= clk_counter + 1;
 80             end 
 81       else clk_temp <= clk_temp + 1;
 82 //-------------------------时钟控制模块-----------------------------------end------------------
 83 
 84 
 85 
 86 //-----------------状态机控制模块------------------------------------------start-------------------
 87 always @ (posedge clock or negedge reset)
 88 if(!reset) 
 89   IC_state <= `INITIAL;
 90  else IC_state <= `MEASURE;
 91  
 92  always @ (posedge clock or negedge reset)
 93  if (!reset)
 94      begin 
 95           step_counter <= 4'd0;
 96             SEND_buffer  <= 8'd0;
 97       end 
 98   else if(IC_state == `INITIAL)
 99      case (step_counter)
100           0: begin  state <= `START; step_counter <= step_counter + 1;end 
101             1: begin  SEND_buffer <= 8'h3c;state <= `Se;  step_counter <= step_counter + 1; end 
102             2: begin  SEND_buffer <= 8'h02;state <= `Se;  step_counter <= step_counter + 1; end
103            3: begin  SEND_buffer <= 8'h00;state <= `Se;  step_counter <= step_counter + 1; end     
104             4: begin  SEND_buffer <= 8'h00;state <= `Se;  step_counter <= step_counter + 1; end
105             default step_counter <= 4'd0;
106       endcase 
107 else if (IC_state == `MEASURE)
108      case (step_counter)
109            0: begin  state <= `START; step_counter <= step_counter + 1;end 
110              1: begin  SEND_buffer <= 8'h3c;state <= `Se;  step_counter <= step_counter + 1; end 
111              2: begin  SEND_buffer <= 8'h03;state <= `Se;  step_counter <= step_counter + 1; end
112             3: begin  state <= `START;  step_counter <= step_counter + 1;end     
113              4: begin  SEND_buffer <= 8'h3d;state <= `Se;  step_counter <= step_counter + 1; end
114             
115              5: begin  state <= `Re;  step_counter <= step_counter + 1; end
116              6: begin  state <= `Re;  step_counter <= step_counter + 1; end
117              7: begin  state <= `Re;  step_counter <= step_counter + 1; end
118              8: begin  state <= `Re;  step_counter <= step_counter + 1; end
119              9: begin  state <= `Re;  step_counter <= step_counter + 1; end
120             10: begin  state <= `Re;  step_counter <= step_counter + 1; end
121             11: begin  state <= `Re;  step_counter <= step_counter + 1; end
122             12: begin  state <= `Re;  step_counter <= step_counter + 1; end
123             
124             13: begin  state <= `STOP;  step_counter <= 4'd0; end
125             default step_counter <= 4'd0;
126       endcase       
127  
128 //-----------------状态机控制模块-------------------------------------------end---------------------
129      
130 
131      
132 //------------------------------------------使能控制模块--------------------------start---------------
133 always @ (posedge clk_counter or negedge reset)
134 if (!reset)
135     begin 
136          sda_enable <= 1'd0;
137           scl_enable <= 1'd0;
138      end  
139 else case (state)
140     `START : begin
141                  if(clk_counter >= 6'd4) 
142                           begin 
143                                 sda_enable <= 1'd0;
144                                  scl_enable <= 1'd0;
145                             end 
146                       else 
147                           begin
148                                sda_enable <= 1'd1;
149                                  scl_enable <= 1'd1; 
150                             end   
151               end 
152                  
153     `STOP  : begin
154                  if(clk_counter >= 6'd4) 
155                           begin 
156                                 sda_enable <= 1'd0;
157                                  scl_enable <= 1'd0;
158                             end 
159                       else 
160                           begin
161                                sda_enable <= 1'd1;
162                                  scl_enable <= 1'd1; 
163                             end   
164               end 
165                  
166      `Se    : begin
167                  if(clk_counter >= 6'd36)   //send 完成之后释放掉使能
168                           begin 
169                                 sda_enable <= 1'd0;
170                                  scl_enable <= 1'd0;
171                             end 
172                       else 
173                           begin
174                                sda_enable <= 1'd1;
175                                  scl_enable <= 1'd1; 
176                             end   
177               end
178                  
179      `Re    : begin 
180                  if(clk_counter >= 6'd32)    //receive 完成之后释放掉使能
181                           begin 
182                                 sda_enable <= 1'd0;
183                                  scl_enable <= 1'd0;
184                             end 
185                       else 
186                           begin
187                                sda_enable <= 1'd1;
188                                  scl_enable <= 1'd1; 
189                             end 
190               end 
191 endcase
192 //------------------------------------------使能控制模块--------------------------end---------------   
193      
194      
195      
196 //------------------------------------------------外部数据线 控制模块-----------------start---------------
197 always @ (posedge clk_counter or negedge reset)
198 if(!reset)
199     begin 
200          sda_reg <= 1'd0;
201           scl_reg <= 1'd0;
202           state_finish_flag <= 1'd0;
203           Re_buffer <= 8'd0;
204      end 
205 else case (state)
206     `START : begin
207                   case (clk_counter)
208                           0: begin sda_reg <= 1'd1;    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end 
209                             1: begin sda_reg <= 1'd1;    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
210                            2: begin sda_reg <= 1'd1;    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
211                            3: begin sda_reg <= 1'd0;    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end 
212                            default     begin sda_reg <= 1'dz;    scl_reg <= 1'dz;    state_finish_flag <= 1'd1; end 
213                       endcase 
214               end 
215                  
216     `STOP  : begin
217                   case (clk_counter)
218                           0: begin sda_reg <= 1'd0;    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
219                            1: begin sda_reg <= 1'd0;    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end     
220                             2: begin sda_reg <= 1'd0;    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end 
221                             3: begin sda_reg <= 1'd1;    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
222                             default  begin sda_reg <= 1'dz;    scl_reg <= 1'dz;    state_finish_flag <= 1'd1; end
223                      endcase 
224               end 
225                  
226      `Se    : begin
227                   case (clk_counter)
228                            0: begin sda_reg <= 1'd0;    scl_reg <= 1'd0; end
229                              1: begin sda_reg <= SEND_buffer[7];    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
230                              2: begin sda_reg <= SEND_buffer[7];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
231                              3: begin sda_reg <= SEND_buffer[7];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
232                              4: begin                               scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
233                              5: begin sda_reg <= SEND_buffer[6];    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
234                              6: begin sda_reg <= SEND_buffer[6];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
235                              7: begin sda_reg <= SEND_buffer[6];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
236                              8: begin                               scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
237                              9: begin sda_reg <= SEND_buffer[5];    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
238                             10: begin sda_reg <= SEND_buffer[5];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
239                             11: begin sda_reg <= SEND_buffer[5];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
240                             12: begin                               scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
241                             13: begin sda_reg <= SEND_buffer[4];    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
242                             14: begin sda_reg <= SEND_buffer[4];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
243                             15: begin sda_reg <= SEND_buffer[4];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
244                             16: begin                               scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
245                             17: begin sda_reg <= SEND_buffer[3];    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
246                             18: begin sda_reg <= SEND_buffer[3];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
247                             19: begin sda_reg <= SEND_buffer[3];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
248                             20: begin                               scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
249                             21: begin sda_reg <= SEND_buffer[2];    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
250                             22: begin sda_reg <= SEND_buffer[2];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
251                             23: begin sda_reg <= SEND_buffer[2];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
252                             24: begin                               scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
253                             25: begin sda_reg <= SEND_buffer[1];    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
254                             26: begin sda_reg <= SEND_buffer[1];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
255                             27: begin sda_reg <= SEND_buffer[1];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
256                             28: begin                               scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
257                             29: begin sda_reg <= SEND_buffer[0];    scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
258                             30: begin sda_reg <= SEND_buffer[0];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
259                             31: begin sda_reg <= SEND_buffer[0];    scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
260                             
261                             32: begin /*state_finish_flag <= sda;*/    scl_reg <= 1'd0;     /*state_finish_flag <= 1'd0; */ end
262                             33: begin /*state_finish_flag <= sda;*/    scl_reg <= 1'd0;     /*state_finish_flag <= 1'd0; */ end
263                             34: begin /*state_finish_flag <= sda;*/    scl_reg <= 1'd1;     /*state_finish_flag <= 1'd0; */ end
264                             35: begin state_finish_flag <= sda;    scl_reg <= 1'd1;     /*state_finish_flag <= 1'd0; */ end
265 
266                             default  begin       scl_reg <= 1'dz;    state_finish_flag <= sda; end      //等待响应
267                       endcase  
268               end
269                  
270      `Re   : begin 
271                   case (clk_counter)
272                            0: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
273                              1: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
274                              2: begin                        scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end 
275                              3: begin Re_buffer[7] <= sda;   scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
276                              4: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
277                              5: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
278                              6: begin                        scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
279                              7: begin Re_buffer[6] <= sda;   scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end

280                              8: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
281                              9: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
282                            10: begin                        scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
283                            11: begin Re_buffer[5] <= sda;   scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
284                             12: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
285                             13: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
286                             14: begin                        scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
287                             15: begin Re_buffer[4] <= sda;   scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
288                             16: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
289                             17: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
290                             18: begin                        scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
291                             19: begin Re_buffer[3] <= sda;   scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
292                             20: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
293                             21: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
294                             22: begin                        scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
295                             23: begin Re_buffer[3] <= sda;   scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
296                             24: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
297                             25: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
298                             26: begin                        scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
299                             27: begin Re_buffer[3] <= sda;   scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
300                             28: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
301                             29: begin                        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
302                             30: begin                        scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
303                             31: begin Re_buffer[3] <= sda;   scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
304                             
305 //                            32:begin sda_reg <= 1'd0;        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end   //NA
306 //                            33:begin sda_reg <= 1'd0;        scl_reg <= 1'd0;     state_finish_flag <= 1'd0; end
307 //                            34:begin sda_reg <= 1'd0;        scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
308 //                            35:begin sda_reg <= 1'd0;        scl_reg <= 1'd1;     state_finish_flag <= 1'd0; end
309                             
310                             default  begin sda_reg <= 1'dz;    scl_reg <= 1'dz;    state_finish_flag <= 1'd1; end
311                       endcase
312               end 
313 endcase
314 //------------------------------------------------外部数据线 控制模块-----------------end---------------
315 
316 
317 
318 assign sda = sda_enable ? sda_reg : 1'dz ;
319 assign scl = scl_enable ? scl_reg : 1'dz ;
320 
321 
322 
323 
324 
325 
326 always @ (posedge clk_counter or negedge reset)
327 if (!reset)
328   begin 

329     sel_seg <= 6'b111110;
330   end 
331 else if(state_finish_flag)
332        begin
333          sel_seg <= {sel_seg[4:0],sel_seg[5]};
334        end
335 
336 always @(posedge clock or negedge reset)
337 if (!reset) out_seg <= 8'd0;
338 else 
339   begin
340     case (Re_buffer)
341        4'b0000  :  out_seg<=8'b1100_0000;//0000_0011
342         4'b0001  :  out_seg<=8'b1111_1001;//1001_1111 
343         4'b0010  :  out_seg<=8'b1010_0100;//0010_0101 
344         4'b0011  :  out_seg<=8'b1011_0000;//0000_1101 
345         4'b0100  :  out_seg<=8'b1001_1001;//1001_1001 
346         4'b0101  :  out_seg<=8'b1001_0010;//0100_1001 
347         4'b0110  :  out_seg<=8'b1000_0010;//0100_0001 
348         4'b0111  :  out_seg<=8'b1111_1000;//0001_1111 
349         4'b1000  :  out_seg<=8'b1000_0000;//0000_0001 
350         4'b1001  :  out_seg<=8'b1001_1000;//0001_1001 
351         4'b1010  :  out_seg<=8'b1000_1000;//0001_0001 
352         4'b1011  :  out_seg<=8'b1000_0011;//1100_0001 
353         4'b1100  :  out_seg<=8'b1100_0110;//0110_0011 
354         4'b1101  :  out_seg<=8'b1010_0001;//1000_0101 
355         4'b1110  :  out_seg<=8'b1000_0110;//0110_0001 
356         4'b1111  :  out_seg<=8'b1000_1110;//0111_0001 
357      endcase 
358   end 
359 
360 
361 
362 endmodule  
原文地址:https://www.cnblogs.com/sepeng/p/3181071.html