I2C 串口通訊協議

            

  1. //傳輸頻率為400k Hz
  2.  
  3. module I2C(
  4.   clk,
  5.   rst,
  6.   w_ctrl,       //control byte
  7.   w_h_addr, //address high byte
  8.   w_l_addr,  //address low byte
  9.   w_data,     //write data
  10.   r_ctrl,        //control byte
  11.   r_h_addr,  //address high byte
  12.   r_l_addr,   //address low byte
  13.   r_data,      //read data
  14.   scl,
  15.   sda
  16. );
  17.  
  18. input  clk,rst;
  19. input  [6:0] w_ctrl;
  20. input  [7:0] w_h_addr;
  21. input  [7:0] w_l_addr;
  22. input  [7:0] w_data;
  23. input  [6:0] r_ctrl;
  24. input  [7:0] r_h_addr;
  25. input  [7:0] r_l_addr;
  26. output [7:0] r_data;
  27. output scl;
  28. inout  sda;
  29.  
  30. reg [6:0] div_cnt;
  31. reg [3:0] bps_cnt;
  32. reg [7:0] reg_d;
  33. reg [7:0] in_d;
  34. reg [7:0] r_data;
  35. reg reg_sda;
  36. reg div_en;                 
  37. reg bps_en;                 
  38. reg sda_en;
  39. reg buf_sda;
  40. reg scl;
  41.  
  42. //=====================================================
  43. // 狀態機
  44. //=====================================================
  45.  
  46. parameter  [4:0]  W_START          = 5'd0,
  47.                              W_CTRL_B       = 5'd1,
  48.                              W_ACK0            = 5'd2,
  49.                              W_ADDR_H_B  = 5'd3,
  50.                              W_ACK1            = 5'd4,
  51.                              W_ADDR_L_B   = 5'd5,
  52.                              W_ACK2            = 5'd6,
  53.                              W_DATA            = 5'd7,
  54.                              W_ACK3            = 5'd8,
  55.                              W_STOP            = 5'd9,
  56.                              W_IDLE             = 5'd10,
  57.                              R_START0        = 5'd11,
  58.                              R_CTRL_B0     = 5'd12,
  59.                              R_ACK0           = 5'd13,
  60.                              R_ADDR_H_B  = 5'd14,
  61.                              R_ACK1           = 5'd15,
  62.                              R_ADDR_L_B  = 5'd16,
  63.                              R_ACK2            = 5'd17,
  64.                              R_START1        = 5'd18,
  65.                              R_CTRL_B1      = 5'd19,
  66.                              R_ACK3            = 5'd20,
  67.                              R_DATA             = 5'd21,
  68.                              R_NO_ACK       = 5'd22,
  69.                              R_STOP            = 5'd23,
  70.                              R_IDLE             = 5'd24;
  71.  
  72. reg [4:0] present_state, next_state;
  73.  
  74. always@(posedge clk or negedge rst)
  75. begin
  76.      if(!rst)  present_state <= W_START;
  77.      else      present_state <= next_state;
  78. end
  79.  
  80. always@(div_cnt or bps_cnt or present_state)
  81. begin
  82.     case(present_state)
  83.     W_START : if(div_cnt == 7'd124 && bps_cnt == 4'd0
  84.                            next_state = W_CTRL_B;
  85.                         else   
  86.                             next_state = W_START;
  87.     W_CTRL_B : if(div_cnt == 7'd124 && bps_cnt == 4'd8
  88.                               next_state = W_ACK0;
  89.                            else   
  90.                               next_state = W_CTRL_B;
  91.     W_ACK0 : if(div_cnt == 7'd124 && bps_cnt == 4'd0
  92.                           next_state = W_ADDR_H_B;
  93.                        else   
  94.                           next_state = W_ACK0;
  95.     W_ADDR_H_B : if(div_cnt == 7'd124 && bps_cnt == 4'd8
  96.                                     next_state = W_ACK1;
  97.                                  else   
  98.                                     next_state = W_ADDR_H_B;
  99.     W_ACK1 : if(div_cnt == 7'd124 && bps_cnt == 4'd0
  100.                           next_state = W_ADDR_L_B;
  101.                        else   
  102.                           next_state = W_ACK1;
  103.     W_ADDR_L_B : if(div_cnt == 7'd124 && bps_cnt == 4'd8
  104.                                     next_state = W_ACK2;
  105.                                  else   
  106.                                     next_state = W_ADDR_L_B;
  107.     W_ACK2 : if(div_cnt == 7'd124 && bps_cnt == 4'd0
  108.                           next_state = W_DATA;
  109.                        else   
  110.                           next_state = W_ACK2;
  111.     W_DATA : if(div_cnt == 7'd124 && bps_cnt == 4'd8
  112.                           next_state = W_ACK3;
  113.                        else   
  114.                           next_state = W_DATA;
  115.     W_ACK3 : if(div_cnt == 7'd124 && bps_cnt == 4'd0) 
  116.                           next_state = W_STOP;
  117.                        else   
  118.                           next_state = W_ACK3;
  119.     W_STOP : if(div_cnt == 7'd124 && bps_cnt == 4'd1
  120.                           next_state = W_IDLE;
  121.                        else   
  122.                           next_state = W_STOP;
  123.     W_IDLE : if(div_cnt == 7'd124 && bps_cnt == 4'd8
  124.                          next_state = R_START0;
  125.                      else   
  126.                          next_state = W_IDLE;
  127.     R_START0 : if(div_cnt == 7'd124 && bps_cnt == 4'd0
  128.                              next_state = R_CTRL_B0;
  129.                           else   
  130.                               next_state = R_START0;
  131.     R_CTRL_B0 : if(div_cnt == 7'd124 && bps_cnt == 4'd8
  132.                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值