I2C实在搞不定了

wuwdb_82   2008-12-23 12:19 楼主
各位大大的程序,官方的,民间的,都试过了,开发板上的,有时复位后可以,大部分时间不行.俺投降了.
接的是FM24C16 .用I2C1
最常见的现象: SCL常高,无信号. SDA常低,亦无信号.导致BUSY位始终为1
PB6 PB7设置为Open-drain.
两个脚都加了上拉电阻4.7K
香版主是不是可以帮忙调板?你在广州吗?给个地址,我快递给你.搞好请你吃饭

回复评论 (10)

再研究

断电重启,让EEPROM一起断电.就可以
单独复位STM32,一般就不行了.
点赞  2008-12-23 12:59

请教

我对I2C协议不是很熟,请教大家:
主机与分机通讯过程中,如果主机发生了复位,刚好分机是把SDA线下拉,这个时候主机的时钟由于复位而消失了,那是不是SDA就一直保持下拉?因此主机再上电后,也无法重新启动通讯
点赞  2008-12-23 15:38

板子断电,保证上电后两根线都是高电平

否则,即使PE@CR1=0,即I2C这个外设还没有使能,监测到总线不是在高电平的idle状态,都会将busy位置1。这样再怎么发start位,都发不出。

所以软件上,在主机复位之前,要先发个stop位。否则就~~~
点赞  2008-12-23 16:02

谢谢lut1lut

我是用手按轻触开关复位啊.没法确保复位前发个STOP位.
这么说,只要板上用了I2C,就只能用断电复位了?
假如我在线JTAG编程调试,那I2C也有可能工作不正常?如果真是这样,实在太晕了.
能不能把PB6,7先设置成IO口.统统拉高,然后再转成I2C模式. 我试一下
点赞  2008-12-23 16:21

基本搞定了

这种"异常复位"确实会造成I2C死锁.是硬件I2C无法避免的.一旦发生,应先转到IO口方式,用IO口方式发出SCK脉冲.每发一次,检测SDA是否变高.高了就说明解锁了.退出,再转回硬件I2C方式.
简单的代码如下:
void CheckDeadLock(void)
{
    DWORD tem=     GPIOB->CRL;
    int i =0;
    I2C_Cmd(I2C1, DISABLE);
    RCC->APB1ENR &= ~RCC_APB1Periph_I2C1;
    tem = (tem&(~(0x0f<<24)))|(3<<24); // SCK ==> output
    tem = (tem&(~(0x0f<<28)))|(4<<28); // SDA ==> input
    GPIOB->CRL = tem;
    while(1){
        GPIOB->BSRR =  (0x1UL<<(6+16));
        Delay(0x2000);
        GPIOB->BSRR =  (0x1UL<<6);
        Delay(0x2000);
        i++;
        if(GPIOB->IDR& (0x1UL<<7))
        {
            printf("释放了%d ", i);
            break;
        }    
                else if(i>=9){ // 这里或许应该是8,待研究
                }
    }
}    
我编写的一个程序,不停地读EEPROM,之前一旦复位,基本就死了.现在多次测试,基本OK.之所以说基本,因为几十次还是有一两次,解锁后还是无法跑下去.在这里感谢香版 netjob lut1lut. 以及几位提供了自己代码的网友

如果哪位同学觉得有所帮助,请一起和我奚落一下ST公司的驱动开发能力.  初接触STM32,为它划时代的能力而震撼,深深感觉到这才是21世纪的单片机.再深入,在它提供的驱动包上开始栽跟斗.首先是不同版本的驱动包,同一个结构体,里面的成员变量居然是不同的(名字不同).再后来,发觉很多地方都充满了while(1)这种类型的死循环,一旦硬件出错,软件就死掉了.没有考虑错误的情况.退一步说,即使难以完美处理各种错误,起码也应该在旁边加相应的注释,例如来个fixme提示.让后来者少走弯路.
两个字评论: 业余 三个字:不专业  四个字:有待改进   五个字:望做得更好
点赞  2008-12-23 17:50

谢谢楼主的批评

两个字评论: 业余 三个字:不专业  四个字:有待改进   五个字:望做得更好

这个评论总结的有道理,俺已经把那帮写这个library的姑娘小伙儿骂了无数遍了,可惜俺不是他们的老板,否则......;嗨,现在找份工作不易,我们还是好好培养他们吧,“望做得更好”。

点赞  2008-12-23 18:20

以前就上过这个当,没有复位,左调右调I2C读取还是错误...

                                 不过这应该是极端情况.I2C若调好了,我测试一次读几k,连续几百次都没问题.
点赞  2008-12-25 00:03

做的还好

                                  
点赞  2008-12-26 14:32

mark....

                                  
点赞  2009-1-14 11:05

这种情况极少会被注意到

                                 太危险了
点赞  2009-1-14 14:34
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复