用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