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