24c256读写失败

[复制链接]
 楼主| chunhuaqioushi 发表于 2009-3-25 09:58 | 显示全部楼层 |阅读模式
24C256读写失败
24C256读写失败
程序停止在了while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
测试i2c引脚都为低电平

//------------------------EEPROM 24C256 API---------------------------
void        GPIO_I2c_Init(void){
        GPIO_InitTypeDef        GPIO_InitStruct;
//CLOCK
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE);
//-----------------------------------------------------------
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStruct.GPIO_Speed        = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,&GPIO_InitStruct);

}

void I2C_24c256Init(void)
{
        I2C_InitTypeDef I2C_InitStruct;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
        GPIO_I2c_Init();
       
        I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStruct.I2C_ClockSpeed = I2C_Speed;
        I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
        I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
       //
        I2C_InitStruct.I2C_OwnAddress1 = I2C_Slave_Adress7;
       
        I2C_Init(I2C1,&I2C_InitStruct);
        I2C_AcknowledgeConfig (I2C1,ENABLE);
        I2C_Cmd(I2C1,ENABLE);
}

void I2C_24c256ByteWrite(u16 WriteAddr,unsigned char Byte )
{
        NVIC_SETPRIMASK();            
    // Start the I2C
        I2C_GenerateSTART(I2C1,ENABLE);

      //not recommanded, stupid way
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

        I2C_Send7bitAddress(I2C1,EE24C256_ADDW,I2C_Direction_Transmitter);

        // when get ACK, means Set Success
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
//------------------------------地址高位
        I2C_SendData(I2C1, (WriteAddr>>8));

        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
//------------------------------地址低位
        I2C_SendData(I2C1, WriteAddr);

        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

        I2C_SendData(I2C1, Byte);

        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
       
        I2C_GenerateSTOP(I2C1, ENABLE);
        NVIC_RESETPRIMASK();//开中断asm("CPSIE I");
}

void    I2C_24c256ByteRead(u16 WriteAddr,unsigned char  *Byte )
{
        NVIC_SETPRIMASK();   
        // Start the I2C
        I2C_GenerateSTART(I2C1,ENABLE);
      //not recommanded, stupid way
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

        I2C_Send7bitAddress(I2C1,EE24C256_ADDW,I2C_Direction_Transmitter);

        // when get ACK, means Set Success
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
//------------------------------地址高位
        I2C_SendData(I2C1, (WriteAddr>>8));

        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
//------------------------------地址低位
        I2C_SendData(I2C1, WriteAddr);

        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
       
        I2C_Send7bitAddress(I2C1,EE24C256_ADDR,I2C_Direction_Transmitter);

        // when get ACK, means Set Success
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
        *Byte = I2C_ReceiveData(I2C1);

        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
       
        I2C_GenerateSTOP(I2C1, ENABLE);
        NVIC_RESETPRIMASK();
}
硬件没有问题,我使用模拟i2c的方法可以正常的读写
查看寄存器 busy 一直为 1
lut1lut 发表于 2009-3-25 10:08 | 显示全部楼层

busy状态位当然为1咯

因为总线电平都是低,只要一使能I2C模块的时钟,BUSY@SR2马上被硬件置位。这样的话,再想进行I2C通信,当然不能成功。

请用置顶帖子中2楼的那个。
 楼主| chunhuaqioushi 发表于 2009-3-25 10:17 | 显示全部楼层

谢谢

谢谢
我主要是想知道我怎么错了,错在哪了??
呵呵
也许大家没有时间帮我看
lut1lut 发表于 2009-3-25 10:28 | 显示全部楼层

通信之前要保证

1。总线电平都处于idle状态,高电平
2。I2C的两个状态寄存器的状态值正确,一般应该都为0
 楼主| chunhuaqioushi 发表于 2009-3-25 10:56 | 显示全部楼层

回 通信之前要保证

我的状态是
I2C的两个状态寄存器的状态值正确,都为0

总线电平都处于低电平,有上拉,不知为何故?
把24c256焊掉状态为高

24c256和硬件电路是正常的我用模拟i2c的方法可以正常的读写
香水城 发表于 2009-3-25 11:00 | 显示全部楼层

总线电平都处于低电平是不对的,这时I2C不能工作

好像你的24C256有问题。
 楼主| chunhuaqioushi 发表于 2009-3-25 11:25 | 显示全部楼层

回好像你的24C256有问题。

我用模拟i2c的方法可以正常的读写,24c256就没有问题了吧
 楼主| chunhuaqioushi 发表于 2009-3-25 11:34 | 显示全部楼层

自己再顶一下

自己再顶一下啊
路过的高手指点一下
lut1lut 发表于 2009-3-25 11:39 | 显示全部楼层

通信之前的总线电平问题

我很奇怪,I2C通信之前,跟后来用GPIO模拟还是用软件库没有关系,问什么一个情况下是总线正常电平,一个情况下总线电平不正常呢? 
 楼主| chunhuaqioushi 发表于 2009-3-25 12:09 | 显示全部楼层

问题没解决


顶顶顶
顶到问题解决为止
lut1lut 发表于 2009-3-25 12:14 | 显示全部楼层

我问你

I2C通信之前,跟后来用GPIO模拟还是用软件库没有关系,问什么一个情况下是总线正常电平,一个情况下总线电平不正常呢? 
香水城 发表于 2009-3-25 12:16 | 显示全部楼层

I2C通信之前总线就变低,为什么会与I2C程序有关呢?

程序还没有运行,怎么能怪程序呢?
lut1lut 发表于 2009-3-25 13:26 | 显示全部楼层

还要确定两件事

第一,是一上电,还是I2C通信了一段时间后,总线电平不正常;

第二,到底是STM32还是24C256拉低了总线电平。
lut1lut 发表于 2009-3-25 13:54 | 显示全部楼层

呼唤lz

你把问题说清楚了,我们才好帮你解决啊。
 楼主| chunhuaqioushi 发表于 2009-3-25 14:09 | 显示全部楼层

回楼上几位

I2C_24c256Init()
之后电平就变低了,电平是被24c256拉低了
改变I2C_Speed后有时会影响,使电平变高,再改变又会死掉
偶尔可以执行到I2C_24c256ByteWrite(u16 WriteAddr,unsigned char Byte )中的while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

有时可以执行到I2C_24c256ByteRead(u16 WriteAddr,unsigned char  *Byte )中的 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
lut1lut 发表于 2009-3-25 14:22 | 显示全部楼层

通信之前的电平问题

就是说,板子一上电,电平还是正常的;执行了I2C_24c256Init()电平被外部的24C256拉低?

那么,
1。进入I2C_24c256Init()函数,看看哪句话使得电平变低的;
2。使用置顶帖子里的2楼方法,也会这样么;
 楼主| chunhuaqioushi 发表于 2009-3-25 14:29 | 显示全部楼层

回楼上

我在看看
 楼主| chunhuaqioushi 发表于 2009-3-25 14:36 | 显示全部楼层

通信之前的电平问题

我这上电之后就被拉低了
偶尔是高的,没有初始化的时候就已经是低了,初始化之后还是低,外部有上拉
是开漏的引脚
我想一定是被24c256拉低了
汉之云 发表于 2009-3-25 14:42 | 显示全部楼层

出错时复位一下MCU

出错时复位MCU,别松手直接量该点电平,就知道MCU是否在拉低这根线
香水城 发表于 2009-3-25 14:46 | 显示全部楼层

上电之后在STM32还没有操作之前,总线就被拉低

你最好用示波器看看,上电时I2C线上是否有干扰信号。

可以尝试先把I2C管脚初始化为GPIO模式,然后在SCK脚上输出一个时钟脉冲,看看I2C总线是否变高,如果没有变高,再输出一个时钟脉冲试试看,如果连续输出8~9个时钟脉冲还不能让I2C总线变高,则表示这个I2C设备有问题;如果发现I2C总线变高,则停止这样的尝试,可以调用I2C的初始化程序了。

如果上电后SCK就是低电平,而且又不是STM32拉低的,那么很可能你的24C256坏了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

24

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部