• 用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  
  • 相关阅读:
    设计模式之设计原则
    把二叉树打印成多行
    快速排序的递归遍历和非递归遍历
    二叉树的非递归遍历
    约瑟夫环问题
    strcpy strcat strcmp memcpy函数的自己实现
    【解题模板】一些很基础的板子
    【笔记】取模运算的用法
    【OJ技巧】DSACPP pa-book中的一些提示
    【编程语言】Java基础进阶——面向对象部分
  • 原文地址:https://www.cnblogs.com/sepeng/p/3181071.html
Copyright © 2020-2023  润新知