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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 5092|回复: 3

[讨论] I2C信号毛刺怎么滤波?

[复制链接]
发表于 2019-9-26 14:36:02 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 lingking 于 2019-9-26 14:41 编辑

最近看一个I2C的IP核的源码,为了滤波和去除亚稳态,代码里面用好多级触发器来保存I2C信号,还做了滤波处理。但是对于下面红色代码部分是如何滤波,还是不太清楚:以下是代码:
always@(posedge clk or negedge nReset)        begin
                if(!nReset)
                        begin
                                cSCL         <= 2'b00;                                // 复位,全部清0
                                cSDA        <= 2'b00;                                // 复位,全部清0               
                        end                        
                else if(rst)                       
                        begin                       
                                cSCL         <= 2'b00;                                // 复位,全部清0                               
                                cSDA        <= 2'b00;                                // 复位,全部清0       
                        end        
                else
                        begin
                                cSCL         <=         {cSCL[0],scl_i};       
                            cSDA        <=         {cSDA[0],sda_i};   
                        end  
        end                                                                                                                                
                                                                                                                                                                                                                                                       
                                                               
                                                               
//         SCL和SDA滤波器的计数器                                                                                                                                                                                                                                               
always@(posedge clk or negedge nReset)
        begin
                if(!nReset)
                        filter_cnt <= 14'd0;
                else if(rst || (!ena))                       
                        filter_cnt <= 14'd0;                       
                else if(~|filter_cnt)                                //
                        filter_cnt <= clk_cnt >> 2;               
                else
                        filter_cnt <= filter_cnt - 1;       
        end                                                                                                                                                                                                                                                        
                                                                                                                               
                               

                               

always@(posedge clk or negedge nReset)                                                                                                                                        
        begin
                if(!nReset)
                        begin
                                fSCL         <= 3'b111;
                                fSDA        <= 3'b111;
                        end
                else if(rst)
                        begin
                                fSCL         <= 3'b111;
                                fSDA        <= 3'b111;                                       
                        end  
                else if(~|filter_cnt)               
                        begin
                                fSCL         <= {fSCL[1:0],cSCL[1]};                                                                               
                                fSDA        <= {fSDA[1:0],cSDA[1]};               
                                                                                       
                        end
        end                                                                                                                                
                                                                                                                               
                                                                                                                               
                                                                                                                               


always@(posedge clk or negedge nReset)
        begin
                if(~nReset)
                        begin
                                sSCL <= 1'b1;                                                                                                               
                                sSDA <= 1'b1;                                                                                                               
                                dSCL <= 1'b1;
                                dSDA <= 1'b1;                               
                        end
                else if(rst)
                        begin
                                sSCL <= 1'b1;                                                                                                               
                                sSDA <= 1'b1;                                                                                                               
                                dSCL <= 1'b1;
                                dSDA <= 1'b1;       
                        end
                else
                        begin
                                sSCL <= &fSCL[2:1] | &fSCL[1:0]|(fSCL[2] & fSCL[0]);                                                                                                                                       

                                sSDA <= &fSDA[2:1] | &fSDA[1:0]|(fSDA[2] & fSDA[0]);                                                                                                                               
                               
                                dSCL <= sSCL;
                                dSDA <= sSDA;                                                                                                                                       
                        end  
       
        end

 楼主| 发表于 2019-9-26 14:43:16 | 显示全部楼层
为什么存进3bit寄存器里面的3个值,有2个位为1就能实现滤波?
发表于 2019-9-27 05:52:39 | 显示全部楼层
你想错了吧:
sSCL <= &fSCL[2:1] | &fSCL[1:0]|(fSCL[2] & fSCL[0]);

fSCL[2:1]必须有一个为0,才能为0
fSCL[1:0]必须有一个为0,才能为0
fSCL[2]和fSCL[0]必须有一个为0,才能为0
也就是说当上面3个同时满足时, sSCL才能为0.
所以也就是说bit2和bit1同时为0, bit1和bit0同时0或者bit2和bit0同时为0,sSCL就是0了。这样确实是相当于滤波了。相当于3次filter_cnt为0的情况下,采了cSCL3次,只要保证2次是0,sSCL就是0了。
 楼主| 发表于 2019-9-27 09:54:58 | 显示全部楼层


kk2009 发表于 2019-9-27 05:52
你想错了吧:
sSCL


多谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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


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

GMT+8, 2024-12-22 09:23 , Processed in 0.015070 second(s), 6 queries , Gzip On, Redis On.

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