在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4044|回复: 7

[求助] xilinx verilog 编写IIC程序,从机TCA6416APW,求高手指导

[复制链接]
发表于 2013-9-12 22:14:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
最近编写了一个IIC程序,从机是TCA6416APW芯片,sda,scl 均通过10k上拉电阻接到3.3v电源上。如图1

                               
登录/注册后可看大图
[size=0.83em]2013-9-12 20:39 上传
下载附件 [size=0.83em](67.12 KB)





                               
登录/注册后可看大图

tca6416的口线通过反相器驱动LED,(只截图两个管脚,其他相同)。sda,scl,reset接到fpga(spartan 3se500)的管脚上。先编写程序驱动led,程序源码如下




  1. module iic_com(clk,rst_n,reset_led, scl,sda);

  2. input clk;                // 30MHz
  3. input rst_n;        //复位信号,低有效
  4. output reset_led;
  5. output scl;                // 时钟端口
  6. inout sda;                // 数据端口

  7. assign reset_led=1;//tca6416复位信号置高

  8. //--------------------------------------------
  9. reg[20:0] cnt_20ms;        //20ms计数寄存器
  10. always [url=home.php?mod=space&uid=72445]@[/url] (posedge clk or negedge rst_n)
  11.         if(!rst_n) cnt_20ms <= 20'd0;
  12.         else if(cnt_20ms == 20'd600000)  cnt_20ms <= 20'd0;
  13.         else cnt_20ms <= cnt_20ms+1'b1;        //不断计数

  14. //---------------------------------------------
  15. //分频部分
  16. reg[2:0] cnt;        // cnt=0:scl上升沿?cnt=1:scl高电平中间 cnt=2:scl下降沿 cnt=3:scl低电平中间
  17. reg[9:0] cnt_delay;        //600循环计数,产生iic所需要的时钟 20us
  18. reg scl_r;                //时钟脉冲寄存器
  19. reg ack_rise;
  20. reg scl_dir;

  21. always @ (posedge clk or negedge rst_n)
  22.         if(!rst_n) cnt_delay <= 10'd0;
  23.         else if(cnt_delay == 10'd599) cnt_delay <=10'd0;        //计数到20us为scl的周期
  24.         else cnt_delay <= cnt_delay+1'b1;        //延时
  25.         
  26. always @ (posedge clk or negedge rst_n) begin
  27.         if(!rst_n) cnt <= 3'd5;
  28.         else begin
  29.                 case (cnt_delay)
  30.                         10'd49:        cnt <= 3'd1;        //cnt=1:scl高电平中间,用于数据采样
  31.                         10'd299:        cnt <= 3'd2;        //cnt=2:scl下降沿               
  32.                         10'd314:        cnt <= 3'd3;        //cnt=3:scl低电平中间,
  33.                         10'd599:        cnt <= 3'd0;        //cnt=0:scl上升沿
  34.                         default: cnt <= 3'd5;
  35.                         endcase
  36.                 end
  37. end

  38. `define SCL_POS                (cnt==3'd0)                //cnt=0:scl上升沿
  39. `define SCL_HIG                (cnt==3'd1)                //cnt=1:scl高电平中间,用于数据采样
  40. `define SCL_NEG                (cnt==3'd2)                //cnt=2:scl下降沿
  41. `define SCL_LOW                (cnt==3'd3)                //cnt=3:scl低电平中间

  42. always @ (posedge clk or negedge rst_n)begin
  43.         if(!rst_n) begin
  44.                 scl_r <= 1'b1;
  45.                 end
  46.         else if(cnt==3'd0)
  47.                 begin        
  48.                 scl_r <= 1'b1;        //scl信号上升沿
  49.                 end
  50.         else if(cnt==3'd2) begin         
  51.                 scl_r <= 1'b0;        //scl信号下降
  52.                 end
  53. end
  54. assign scl = scl_dir ? scl_r : 1'bz;        //?iic所需要的时钟信号

  55. //--------------------------------------------

  56. //配置TCA6416A               
  57. `define DEVICE_ADDR           8'b01000010          //TCA6416地址
  58. `define CONFIG_COMMAND  8'b00000110   //P0口配置地址
  59. `define CONFIG_DATA     8'b00000000   //P0/P1口配置数据,配置为输出口
  60. `define OUT_COMMAND     8'b00000010   //P0口输出地址
  61. `define POLARITY_COMMAND  8'b00000100   //p0极性
  62. `define POLARITY_data   8'b00000000   //p0极性

  63. wire[7:0] dis_data0;        //故障信息的数据
  64. wire[7:0] dis_data1;
  65. assign dis_data0=8'b00001111;
  66. assign dis_data1=8'b00001111;
  67. reg[7:0] db_r;                //在IIC上传送的数据寄存器

  68. //读、写时序
  69. parameter         IDLE         = 5'd0;
  70. parameter         START        = 5'd1;
  71. parameter         ADDR_DEVICE = 5'd2;
  72. parameter         ADDR_DEVICE_ACK = 5'd3;
  73. parameter         CONFIG_ADDR = 5'd4;
  74. parameter         CONFIG_ADDR_ACK = 5'd5;
  75. parameter         CONFIG_DATA0 = 5'd6;
  76. parameter         CONFIG_DATA0_ACK = 5'd7;
  77. parameter         CONFIG_DATA1 = 5'd8;
  78. parameter         CONFIG_DATA1_ACK         = 5'd9;
  79. parameter         OUT_ADDR        = 5'd10;
  80. parameter         OUT_ADDR_ACK = 5'd11;
  81. parameter         OUT_DATA0 = 5'd12;
  82. parameter         OUT_DATA0_ACK = 5'd13;
  83. parameter         OUT_DATA1 = 5'd14;
  84. parameter         OUT_DATA1_ACK        = 5'd15;
  85. parameter   POLARITY=5'd16;
  86. parameter   POLARITY_ACK=5'd17;
  87. parameter   POLARITY_DATA0=5'd18;
  88. parameter   POLARITY_DATA0_ACK=5'd19;
  89. parameter   POLARITY_DATA1=5'd20;
  90. parameter   POLARITY_DATA1_ACK=5'd21;
  91. parameter         STOP1        = 5'd22;
  92. parameter         STOP2        = 5'd23;
  93. parameter         WAIT        = 5'd24;

  94. reg[4:0] cstate;        //状态寄存器
  95. reg[3:0] num;
  96. reg sda_r;                //输出数据寄存器
  97. reg sda_link;        //输出sda信号inout方向  1为输出,0为输入
  98. assign sda = sda_link ? sda_r:1'bZ;//三态口

  99. always @ (posedge clk or negedge rst_n) begin
  100.         if(!rst_n) begin//复位
  101.               ack_rise<=1'b0;
  102.                         cstate <= IDLE;
  103.                         sda_link <= 1'b0;
  104.                         scl_dir<=1'b0;
  105.                         num <= 4'd0;
  106.                         db_r <= 8'b00000000;        //送器件地址
  107.                 end
  108.         else           
  109.                 case (cstate)
  110.                         IDLE:        begin
  111.                                         scl_dir<=1'b1;
  112.                                         sda_link <= 1'b1;                        //数据线sda为output
  113.                                         sda_r <= 1'b1;                        
  114.                                         db_r <= `DEVICE_ADDR;        //送器件地址                        
  115.                                         cstate <= START;               
  116.                                 end
  117.                                 
  118.                         START: begin
  119.                                         if(cnt_delay==10'd150)begin   //scl为高电平期间                                       
  120.                                                 sda_link <= 1'b1;        //数据线sda output
  121.                                                 sda_r <= 1'b0;                //拉低数据sda,产生下降沿                                                
  122.                                                 cstate <= ADDR_DEVICE;
  123.                                                 num <= 4'd0;                //num计数清零                                       
  124.                                                 end
  125.                                         else cstate <= START; //等待scl高电平中间位置到来
  126.                                 end
  127.                                 
  128.                         ADDR_DEVICE:begin               //发送器件地址
  129.                                         if(`SCL_LOW) begin
  130.                                                 case (num)
  131.                                                         4'd0: sda_r <= db_r[7];
  132.                                                         4'd1: sda_r <= db_r[6];
  133.                                                         4'd2: sda_r <= db_r[5];
  134.                                                         4'd3: sda_r <= db_r[4];
  135.                                                         4'd4: sda_r <= db_r[3];
  136.                                                         4'd5: sda_r <= db_r[2];
  137.                                                         4'd6: sda_r <= db_r[1];
  138.                                                         4'd7: sda_r <= db_r[0];
  139.                                                         default: ;
  140.                                                 endcase
  141.                                                 sda_link <= 1'b1;
  142.                                                 num <= num+1'b1;//并行执行
  143.                                                 if(num == 4'd8) begin
  144.                                                         num <= 4'd0;                        //num计数清零
  145.                                                         sda_link <= 1'b0;    //释放总线
  146.                                                         cstate <=ADDR_DEVICE_ACK;
  147.                                                 end
  148.                                         end
  149.                                         else cstate <= ADDR_DEVICE;//等待                                       
  150.                                 end
  151.                                 
  152.                 ADDR_DEVICE_ACK:begin
  153.                                 if(scl) begin
  154.                                         sda_link <= 1'b0;
  155.                                                 if(!sda)begin
  156.                                                         cstate <= CONFIG_ADDR;        //从机响应                                                
  157.                                                         db_r <= `CONFIG_COMMAND;// P0配置地址                        
  158.                                                 end
  159.                                         end
  160.                                 else cstate <= ADDR_DEVICE_ACK;                //等待下降沿                        
  161.                                 end
  162.                                 
  163.                 CONFIG_ADDR:begin
  164.                                 if(`SCL_LOW) begin
  165.                                                 case (num)
  166.                                                         4'd0: sda_r <= db_r[7];
  167.                                                         4'd1: sda_r <= db_r[6];
  168.                                                         4'd2: sda_r <= db_r[5];
  169.                                                         4'd3: sda_r <= db_r[4];
  170.                                                         4'd4: sda_r <= db_r[3];
  171.                                                         4'd5: sda_r <= db_r[2];
  172.                                                         4'd6: sda_r <= db_r[1];
  173.                                                         4'd7: sda_r <= db_r[0];
  174.                                                         default: ;
  175.                                                 endcase
  176.                                                 sda_link <= 1'b1;
  177.                                                 num <= num+1'b1;//并行执行
  178.                                                 if(num == 4'd8) begin        
  179.                                                         num <= 4'd0;                                                                        
  180.                                                         //sda_r <= 1'b1;  
  181.                                                         sda_link <= 1'b0;//释放总线                                                         
  182.                                                         cstate <=CONFIG_ADDR_ACK;
  183.                                                 end
  184.                                         end
  185.                                         else cstate <= CONFIG_ADDR;//等待                                       
  186.                                 end
  187.                                 
  188.                 CONFIG_ADDR_ACK:        begin
  189.                                         if(scl) begin
  190.                                                 sda_link <= 1'b0;                                                
  191.                                                 if(!sda) begin                //从机响应        
  192.                                                                         cstate <=CONFIG_DATA0;         //写P0配置操作
  193.                                                                         db_r <= `CONFIG_DATA;        //P0口配置数据        
  194.                                                         end
  195.                                                 end
  196.                                         else cstate <= CONFIG_ADDR_ACK;        //等待从机响应                                
  197.                                         end
  198.                                 
  199.                 CONFIG_DATA0: begin
  200.                                 if(`SCL_LOW) begin
  201.                                                 case (num)
  202.                                                         4'd0: sda_r <= db_r[7];
  203.                                                         4'd1: sda_r <= db_r[6];
  204.                                                         4'd2: sda_r <= db_r[5];
  205.                                                         4'd3: sda_r <= db_r[4];
  206.                                                         4'd4: sda_r <= db_r[3];
  207.                                                         4'd5: sda_r <= db_r[2];
  208.                                                         4'd6: sda_r <= db_r[1];
  209.                                                         4'd7: sda_r <= db_r[0];
  210.                                                         default: ;
  211.                                                 endcase
  212.                                                 sda_link <= 1'b1;
  213.                                                 num <= num+1'b1;//并行执行
  214.                                                 if(num == 4'd8) begin        
  215.                                                         num <= 4'd0;                                                                        
  216.                                                         //sda_r <= 1'b1;  
  217.                                                         sda_link <= 1'b0;//释放总线                                                        
  218.                                                         cstate <=CONFIG_DATA0_ACK;
  219.                                                 end
  220.                                         end
  221.                                         else cstate <= CONFIG_DATA0;//等待                                       
  222.                                 end               
  223.                         
  224.                 CONFIG_DATA0_ACK:        begin
  225.                                 if(scl) begin
  226.                                         sda_link <= 1'b0;
  227.                                         if(!sda) begin                //从机响π藕
  228.                                                                 cstate <= CONFIG_DATA1;         //写P1                                       
  229.                                                                 db_r <= `CONFIG_DATA;        //P1口配置数据               
  230.                                                 end
  231.                                         end
  232.                                         else cstate <= CONFIG_DATA0_ACK;        //等待从机响应
  233.                                 end
  234.                                 
  235.                 CONFIG_DATA1: begin
  236.                                 if(`SCL_LOW) begin
  237.                                                 case (num)
  238.                                                         4'd0: sda_r <= db_r[7];
  239.                                                         4'd1: sda_r <= db_r[6];
  240.                                                         4'd2: sda_r <= db_r[5];
  241.                                                         4'd3: sda_r <= db_r[4];
  242.                                                         4'd4: sda_r <= db_r[3];
  243.                                                         4'd5: sda_r <= db_r[2];
  244.                                                         4'd6: sda_r <= db_r[1];
  245.                                                         4'd7: sda_r <= db_r[0];
  246.                                                         default: ;
  247.                                                 endcase
  248.                                                 sda_link <= 1'b1;
  249.                                                 num <= num+1'b1;//并行执行
  250.                                                 if(num == 4'd8) begin        
  251.                                                         num <= 4'd0;                        //num计数清零
  252.                                                         //sda_r <= 1'b1;  
  253.                                                         sda_link <= 1'b0;//释放总线
  254.                                                         cstate <=CONFIG_DATA1_ACK;
  255.                                                 end
  256.                                         end
  257.                                         else cstate <= CONFIG_DATA1;//等待                                       
  258.                                 end               
  259.                                                                
  260.                 CONFIG_DATA1_ACK:        begin
  261.                                                 if(scl) begin
  262.                                                         sda_link <= 1'b0;
  263.                                                         if(!sda) begin                //从机响应                                                               
  264.                                                                                 cstate <= OUT_ADDR;         //写P0输出地址
  265.                                                                                 db_r <= `OUT_COMMAND;        //P0口配置数据        
  266.                                                                 end
  267.                                                 end
  268.                                         else cstate <= CONFIG_DATA1_ACK;               
  269.                                         end
  270.                                        
  271.                 OUT_ADDR: begin
  272.                                 if(`SCL_LOW) begin
  273.                                                 case (num)
  274.                                                         4'd0: sda_r <= db_r[7];
  275.                                                         4'd1: sda_r <= db_r[6];
  276.                                                         4'd2: sda_r <= db_r[5];
  277.                                                         4'd3: sda_r <= db_r[4];
  278.                                                         4'd4: sda_r <= db_r[3];
  279.                                                         4'd5: sda_r <= db_r[2];
  280.                                                         4'd6: sda_r <= db_r[1];
  281.                                                         4'd7: sda_r <= db_r[0];
  282.                                                         default: ;
  283.                                                 endcase
  284.                                                 num <= num+1'b1;//并行执行
  285.                                                 if(num == 4'd8) begin
  286.                                                         ack_rise<=1'b1;                                                
  287.                                                         num <= 4'd0;                        //num计数清零
  288.                                                         //sda_r <= 1'b1;  
  289.                                                         sda_link <= 1'b0;
  290.                                                         cstate <=OUT_ADDR_ACK;
  291.                                                 end
  292.                                         end
  293.                                         else cstate <= OUT_ADDR;//等待                                       
  294.                                 end                                       

  295.                 OUT_ADDR_ACK:        begin
  296.                                                 if(scl) begin
  297.                                                         sda_link <= 1'b0;
  298.                                                         if(!sda) begin                //从机响应
  299.                                                                                 cstate <= OUT_DATA0; //写P0输出数据
  300.                                                                                 db_r <= dis_data0;
  301.                                                                 end
  302.                                                 end
  303.                                         else cstate <= OUT_ADDR_ACK;        //等待从机响应                        
  304.                                         end        
  305.                                        
  306.                 OUT_DATA0: begin
  307.                                                 if(`SCL_LOW) begin
  308.                                                 case (num)
  309.                                                         4'd0: sda_r <= db_r[7];
  310.                                                         4'd1: sda_r <= db_r[6];
  311.                                                         4'd2: sda_r <= db_r[5];
  312.                                                         4'd3: sda_r <= db_r[4];
  313.                                                         4'd4: sda_r <= db_r[3];
  314.                                                         4'd5: sda_r <= db_r[2];
  315.                                                         4'd6: sda_r <= db_r[1];
  316.                                                         4'd7: sda_r <= db_r[0];
  317.                                                         default: ;
  318.                                                 endcase
  319.                                                 sda_link <= 1'b1;
  320.                                                 num <= num+1'b1;//并行执行
  321.                                                 if(num == 4'd8) begin        
  322.                                                         num <= 4'd0;                        //num计数清零
  323.                                                         //sda_r <= 1'b1;
  324.                                                         sda_link <= 1'b0;                                                        
  325.                                                         cstate <=OUT_DATA0_ACK;        
  326.                                                 end
  327.                                         end
  328.                                         else cstate <= OUT_DATA0;//等待                                       
  329.                                 end        
  330.         
  331.                 OUT_DATA0_ACK:        begin
  332.                                                 if(scl) begin
  333.                                                         sda_link <= 1'b0;
  334.                                                         if(!sda ) begin                //从机响应信号                                                               
  335.                                                                                 cstate <= OUT_DATA1; //写P1输出数据
  336.                                                                                 db_r <= dis_data1;        //P1口数据                                                                                
  337.                                                                 end
  338.                                                 end
  339.                                         else cstate <= OUT_DATA0_ACK;        //等待从机响应
  340.                                 end
  341.                                 
  342.                 OUT_DATA1: begin
  343.                                                 if(`SCL_LOW) begin
  344.                                                 case (num)
  345.                                                         4'd0: sda_r <= db_r[7];
  346.                                                         4'd1: sda_r <= db_r[6];
  347.                                                         4'd2: sda_r <= db_r[5];
  348.                                                         4'd3: sda_r <= db_r[4];
  349.                                                         4'd4: sda_r <= db_r[3];
  350.                                                         4'd5: sda_r <= db_r[2];
  351.                                                         4'd6: sda_r <= db_r[1];
  352.                                                         4'd7: sda_r <= db_r[0];
  353.                                                         default: ;
  354.                                                 endcase
  355.                                                 sda_link <= 1'b1;
  356.                                                 num <= num+1'b1;//并行执行
  357.                                                 if(num == 4'd8) begin        
  358.                                                         num <= 4'd0;                        //num计数清零
  359.                                                         //sda_r <= 1'b1;
  360.                                                         sda_link <= 1'b0;                                                         
  361.                                                         cstate <=OUT_DATA1_ACK;
  362.                                                 end
  363.                                         end
  364.                                         else cstate <= OUT_DATA1;//等待                                       
  365.                                 end        
  366.                                 
  367.                 OUT_DATA1_ACK:        begin
  368.                                                 if(scl) begin
  369.                                                         sda_link <= 1'b0;
  370.                                                         if(!sda) begin                //从机响应信号
  371.                                                                                 db_r <= `POLARITY_COMMAND;        
  372.                                                                                 cstate <= POLARITY;                                                                 
  373.                                                                 end
  374.                                                 end
  375.                                         else cstate <= OUT_DATA1_ACK;        //等待从机响应
  376.                                 end
  377.                                 
  378.                         POLARITY: begin
  379.                                 if(`SCL_LOW) begin
  380.                                                 case (num)
  381.                                                         4'd0: sda_r <= db_r[7];
  382.                                                         4'd1: sda_r <= db_r[6];
  383.                                                         4'd2: sda_r <= db_r[5];
  384.                                                         4'd3: sda_r <= db_r[4];
  385.                                                         4'd4: sda_r <= db_r[3];
  386.                                                         4'd5: sda_r <= db_r[2];
  387.                                                         4'd6: sda_r <= db_r[1];
  388.                                                         4'd7: sda_r <= db_r[0];
  389.                                                         default: ;
  390.                                                 endcase
  391.                                                 sda_link <= 1'b1;
  392.                                                 num <= num+1'b1;//并行执行
  393.                                                 if(num == 4'd8) begin                                                
  394.                                                         num <= 4'd0;                        //num计数清零
  395.                                                         //sda_r <= 1'b1;  
  396.                                                         sda_link <= 1'b0;
  397.                                                         cstate <=POLARITY_ACK;
  398.                                                 end
  399.                                         end
  400.                                         else cstate <= POLARITY;//等待                                       
  401.                                 end                                       

  402.                 POLARITY_ACK:        begin
  403.                                                 if(scl) begin
  404.                                                         sda_link <= 1'b0;
  405.                                                         ack_rise<=1'b0;                                                        
  406.                                                         if(!sda) begin                //从机响应
  407.                                                                                 cstate <= POLARITY_DATA0; //写P0输出数据
  408.                                                                                 db_r <= `POLARITY_data;
  409.                                                                 end
  410.                                                 end
  411.                                         else cstate <= POLARITY_ACK;        //等待从机响应                        
  412.                                         end        
  413.                                        
  414.                 POLARITY_DATA0: begin
  415.                                                 if(`SCL_LOW) begin
  416.                                                 case (num)
  417.                                                         4'd0: sda_r <= db_r[7];
  418.                                                         4'd1: sda_r <= db_r[6];
  419.                                                         4'd2: sda_r <= db_r[5];
  420.                                                         4'd3: sda_r <= db_r[4];
  421.                                                         4'd4: sda_r <= db_r[3];
  422.                                                         4'd5: sda_r <= db_r[2];
  423.                                                         4'd6: sda_r <= db_r[1];
  424.                                                         4'd7: sda_r <= db_r[0];
  425.                                                         default: ;
  426.                                                 endcase
  427.                                                 sda_link <= 1'b1;
  428.                                                 num <= num+1'b1;//并行执行
  429.                                                 if(num == 4'd8) begin        
  430.                                                         num <= 4'd0;                        //num计数清零
  431.                                                         //sda_r <= 1'b1;
  432.                                                         sda_link <= 1'b0;                                                        
  433.                                                         cstate <=POLARITY_DATA0_ACK;        
  434.                                                 end
  435.                                         end
  436.                                         else cstate <= POLARITY_DATA0;//等待                                       
  437.                                 end        
  438.         
  439.                 POLARITY_DATA0_ACK:        begin
  440.                                                 if(scl) begin
  441.                                                         sda_link <= 1'b0;
  442.                                                         if(!sda ) begin                //从机响应信号                                                               
  443.                                                                                 cstate <= POLARITY_DATA1; //写P1输出数据
  444.                                                                                 db_r <= `POLARITY_data;        //P1口数据                                                                        
  445.                                                                 end
  446.                                                 end
  447.                                         else cstate <= POLARITY_DATA0_ACK;        //等待从机响应
  448.                                 end
  449.                                 
  450.                 POLARITY_DATA1: begin
  451.                                                 if(`SCL_LOW) begin
  452.                                                 case (num)
  453.                                                         4'd0: sda_r <= db_r[7];
  454.                                                         4'd1: sda_r <= db_r[6];
  455.                                                         4'd2: sda_r <= db_r[5];
  456.                                                         4'd3: sda_r <= db_r[4];
  457.                                                         4'd4: sda_r <= db_r[3];
  458.                                                         4'd5: sda_r <= db_r[2];
  459.                                                         4'd6: sda_r <= db_r[1];
  460.                                                         4'd7: sda_r <= db_r[0];
  461.                                                         default: ;
  462.                                                 endcase
  463.                                                 sda_link <= 1'b1;
  464.                                                 num <= num+1'b1;//并行执行
  465.                                                 if(num == 4'd8) begin        
  466.                                                         num <= 4'd0;                        //num计数清零
  467.                                                         //sda_r <= 1'b1;
  468.                                                         sda_link <= 1'b0;                                                         
  469.                                                         cstate <=POLARITY_DATA1_ACK;
  470.                                                 end
  471.                                         end
  472.                                         else cstate <= POLARITY_DATA1;//等待                                       
  473.                                 end        
  474.                                 
  475.                 POLARITY_DATA1_ACK:        begin
  476.                                                 if(scl) begin
  477.                                                         sda_link <= 1'b0
  478.                                                         if(!sda) begin                //从机响应信号
  479.                                                                                 cstate <= STOP1;                                                                 
  480.                                                                 end
  481.                                                 end
  482.                                         else cstate <= POLARITY_DATA1_ACK;        //等待从机响应
  483.                                 end                        
  484.                                        
  485.                 STOP1:begin
  486.                                         if(`SCL_LOW) begin
  487.                                                         sda_link <= 1'b1;
  488.                                                         sda_r <= 1'b0;
  489.                                                         cstate <= STOP2;
  490.                                                 end
  491.                                         else cstate <= STOP1;
  492.             end
  493.             
  494.                 STOP2:begin
  495.                                         if(cnt_delay==10'd150)begin
  496.                                                         //sda_r <= 1'b1;        //scl为高时,sda产生上升沿(结束信号)
  497.                                                         sda_link<=1'b0;
  498.                                                         scl_dir<=1'b0;
  499.                                                         cstate <= WAIT;
  500.                                                 end
  501.                                         else cstate <= STOP2;
  502.                       end
  503.                
  504.                 WAIT:begin
  505.                                         if(cnt_20ms==20'd600000) begin
  506.                                                 cstate <= IDLE;
  507.                                                 end                                                
  508.                                         else cstate <= WAIT;
  509.                                         end
  510.                                 
  511.                 default: cstate <= IDLE;
  512.                 endcase
  513. end

  514. endmodule


复制代码




调试运行后,所有led灯均发光,且没有变换,用示波器观测sda.scl的电平,观测波形如图2。


                               
登录/注册后可看大图



图2(从start到stop)图2放大部分见图3

                               
登录/注册后可看大图


图3(起始,发送器件地址后应答,发送配置字,应答)
现在问题是,第9个时钟周期未见sda先变高电平后被拉低的过程,且第十个周期的低电平时(即发送 下一字节的第1个周期)均有边沿毛刺。
求各位老师帮我看看,程序哪里有问题,为何会出现毛刺?谢谢。
PS第一次发帖,求关注
发表于 2013-9-13 10:57:04 | 显示全部楼层
189
194
都对sda_link赋值了,我不知道你想干啥,还有仅仅给出这么多信息,想人人定位问题还是有难度的。
发表于 2013-9-13 11:06:02 | 显示全部楼层
nice job
 楼主| 发表于 2013-9-14 10:34:49 | 显示全部楼层
回复 2# chen851112

line   189 是设置sda为输出口,输出一个字节的8bit;line   194 是设置sda 为输入口,当发送8个数据完成时,第九个时钟低电平时释放总线,以获得相应信号;
189 和194并不是同时执行的
发表于 2013-9-14 14:51:41 | 显示全部楼层
回复 4# wangliang724
你看看你自己的问题,我都已经说得这么明白了,你的问题是第九个时钟时出问题了,我给提出的代码问题也是在这。你在考虑一下。
发表于 2013-9-17 09:37:50 | 显示全部楼层
回复 4# wangliang724
问题,解决了吗?
 楼主| 发表于 2013-9-18 11:08:44 | 显示全部楼层
改过了,还是不行。



  1. if(`SCL_LOW) begin
  2. case (num)
  3. 4'd0: sda_r <= db_r[7];
  4. 4'd1: sda_r <= db_r[6];
  5. 4'd2: sda_r <= db_r[5];
  6. 4'd3: sda_r <= db_r[4];
  7. 4'd4: sda_r <= db_r[3];
  8. 4'd5: sda_r <= db_r[2];
  9. 4'd6: sda_r <= db_r[1];
  10. 4'd7: sda_r <= db_r[0];
  11. default: ;
  12. endcase
  13. if(num != 4'd8)begin
  14. sda_link <= 1'b1;
  15. num <= num+1'b1;//并行执行
  16. end
  17. else begin //(num == 4'd8)
  18. num <= 4'd0;         //num计数清零
  19. sda_link <= 1'b0; //释放总线
  20. cstate <=ADDR_DEVICE_ACK;
  21. end
  22. end
  23. else cstate <= ADDR_DEVICE;//等待       
  24. end



复制代码
代码改成如上形式,结果未发生变化。TCA6416应该是应答了,因为如果将sda分配该FPGA的一个悬空管脚,第九个时钟电平时sda将一直被拉高,而分配给与TCA6416的sda相连的管脚时,第九个时钟电平时sda被拉低。问题是,在第九个时钟的低电平时释放了总线,sda应该先被拉高,然后才被TCA6416响应拉低,在第九个时钟的高电平时产生一个响应位,可现在用示波器查看,第9个时钟时,sda一直是低,而且led灯全亮。不知问题所在。请老师您帮我看看好吗?调了好长时间了,想用这个芯片做故障指示用的,比较重要。如果需要我可以把源程序发给老师,帖子里面的源程序格式有点乱。谢谢。
发表于 2014-7-22 09:46:23 | 显示全部楼层
为什么我的iic读出来的全是高电平?求解答。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

X

小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-6-23 13:55 , Processed in 0.026335 second(s), 12 queries , Gzip On, MemCached On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表