查看: 6665|回复: 2

基于状态机的IIC协议实现

[复制链接]
  • TA的每日心情
    开心
    2015-10-15 14:19
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2015-12-24 12:24:21 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 jwl 于 2015-12-24 12:29 编辑

    拿到了小脚丫的板子,写了一个IIC作为简单测试程序。给小伙伴们参考参考
    好像ultraedit和帖子的代码不太兼容,有些地方比较夸张的裂开了,请忽视这些细节

    发送端部分:
    1. /*
    2.         数据发送端----------------------> IIC总线
    3.                                            ------------------
    4.                                           |                       |
    5.                                  sclk->|                       |->scl
    6.                                   rst->|                        |
    7.                       data[3:0]=>|                        |->sda
    8.                                          |                         |
    9.                                 ack<-|                         |
    10.                                             ------------------
    11. */

    12. module IICsender(
    13.         input wire sclk,
    14.         input wire rst,
    15.         input wire [3:0] data,
    16.         output reg ack,                //主机中断
    17.         output reg scl,
    18.         output reg sda
    19. );
    20.         
    21.         reg [6:0] state;
    22. /*        reg clk, clk_inv;*/
    23.         
    24.         parameter
    25.                 Idle = 7'b0000001,
    26.                 Start= 7'b0000010,
    27.                 Bit4 = 7'b0000100,
    28.                 Bit3 = 7'b0001000,
    29.                 Bit2 = 7'b0010000,
    30.                 Bit1 = 7'b0100000,
    31.                 Stop = 7'b1000000;               
    32.                
    33. //scl信号的产生,为sclk二分频               
    34.         always @(posedge sclk)
    35.                 begin
    36.                         if (rst)
    37.                                 scl <= 0;
    38.                         else
    39.                                 scl <= ~scl;
    40.                 end
    41.         
    42. //状态机及输出逻辑
    43.         always @(negedge sclk) begin
    44.                 if (rst)
    45.                         begin
    46.                                 sda <= 1;
    47.                                 ack <= 0;
    48.                                 state <= Idle;
    49.                         end
    50.                 else
    51.                         case (state)
    52.                                 Idle:
    53.                                         if (ack && scl) begin state<=Start; ack<=1; sda<=0;end
    54.                                         else begin state<=Idle; ack<=1; sda<=1;end
    55.                                 Start:
    56.                                         if (ack && !scl) begin state<=Bit4; ack<=0; sda<=data[3];end
    57.                                         else begin state<=Start;ack<=1;end
    58.                                 Bit4:
    59.                                         if (!scl) begin state<=Bit3; sda<=data[2];end
    60.                                         else state<=Bit4;
    61.                                 Bit3:
    62.                                         if (!scl) begin state<=Bit2; sda<=data[1];end
    63.                                         else state<=Bit3;
    64.                                 Bit2:
    65.                                         if (!scl) begin state<=Bit1; sda<=data[0];end
    66.                                         else state<=Bit2;
    67.                                 Bit1:
    68.                                         if (!scl) begin state<=Stop; sda<=0;end
    69.                                         else state<=Bit1;
    70.                                 Stop:
    71.                                         if (scl) begin state<=Idle; sda<=1;end
    72.                                         else state<=Stop;
    73.                         endcase
    74.         end        

    75. endmodule
    复制代码
    接收端部分:
    1. /*
    2.         IIC总线        --------------------->数据接收端                                                                        
    3.                                         ------------------
    4.                                        |                      |
    5.                                scl->|                       |<-rst
    6.                                        |                      |
    7.                                        |                       |->ack
    8.                              sda->|                        |->finish
    9.                                       |                        |=>data[3:0]         
    10.                                         ------------------
    11. */

    12. module IICreceiver(
    13.         input wire scl,
    14.         input wire sda,
    15.         input wire rst,
    16.         output wire [3:0] data,
    17.         output reg ack,                                        //开始接收中断
    18.         output reg finish                                //接收完成中断
    19.         );
    20.         
    21.         parameter
    22.                 Idle  = 6'b000001,
    23.                 Bit4  = 6'b000010,
    24.                 Bit3  = 6'b000100,
    25.                 Bit2  = 6'b001000,
    26.                 Bit1  = 6'b010000,
    27.                 Stop  = 6'b100000;

    28.         reg [5:0] state=Idle;
    29.         reg StartFlag, StopFlag;
    30.         reg [3:0] data_tmp;

    31. //开始检测电路        
    32.         always @(negedge sda)        
    33.                 if (scl)
    34.                         StartFlag <= 1;
    35.                 else
    36.                         StartFlag <= 0;

    37. //结束检测电路               
    38.         always @(posedge sda)
    39.                 if (scl)
    40.                         StopFlag <= 1;
    41.                 else
    42.                         StopFlag <= 0;                        

    43. //状态机迁移        
    44.         always @(posedge scl)
    45.                 if (rst)
    46.                         begin
    47.                                  ack <= 0;
    48.                                  finish <= 0;
    49.                                  state<= Idle;
    50.                                  data_tmp <= 4'bzzzz;
    51.                         end
    52.                 else
    53.                         case (state)
    54.                                 Idle:
    55.                                         if (StartFlag) begin state<=Bit4;data_tmp[3]<=sda;ack<=1;end
    56.                                         else state<=Idle;
    57.                                 Bit4:
    58.                                         if (ack) begin state<=Bit3;data_tmp[2]<=sda;ack<=0;end
    59.                                         else state<=Bit4;
    60.                                 Bit3:
    61.                                         begin state<=Bit2;data_tmp[1]<=sda;end
    62.                                 Bit2:
    63.                                         begin state<=Bit1;data_tmp[0]<=sda;finish<=1;end
    64.                                 Bit1:
    65.                                         if (StopFlag) begin state<=        Idle;finish<=0;end
    66.                                         else state<=Bit1;                        
    67.                         endcase
    68.                         
    69.                 assign data = finish? data_tmp:4'bzzzz;

    70. endmodule
    复制代码
    顶层测试模块

    1. module IIC_top(
    2.         input wire clk,
    3.         input wire rst,
    4.         input wire [3:0] send,
    5.         output wire [3:0] receive,
    6.         output wire receiveInt,                                        //开始接收中断
    7.         output wire finish                                //接收完成中断
    8. );
    9.         wire sendInt,scl,sda;
    10.         IICsender U1( .sclk(clk), .rst(rst),.data(send),.ack(sendInt),.scl(scl),.sda(sda));
    11.         IICreceiver U2(.scl(scl), .sda(sda),.rst(rst),.data(receive),.ack(receiveInt),.finish(finish));
    12. endmodule
    复制代码
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2017-6-14 11:22
  • 签到天数: 44 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2015-12-25 14:03:46 | 显示全部楼层
    楼主好分享!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2021-2-27 22:16
  • 签到天数: 1568 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2019-4-9 12:30:38 | 显示全部楼层
    谢谢分享 522.jpg
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-4-19 06:26 , Processed in 0.136796 second(s), 19 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.