野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11506|回复: 5

STM32F103的I2C问题

[复制链接]
发表于 2018-1-19 20:22:02 | 显示全部楼层 |阅读模式
uint8_t I2C_ByteWrite(uint8_t WriteDatas,uint8_t WriteAddr){
  I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);

  I2CTimeout = I2CT_FLAG_TIMEOUT;  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))  
  {
    if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(0);
  }

  I2CTimeout = I2CT_FLAG_TIMEOUT;
  /* Send EEPROM address for write */
  I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);

  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(1);
  }  
  /* Send the EEPROM's internal address to write to */
  I2C_SendData(EEPROM_I2Cx, WriteAddr);

  I2CTimeout = I2CT_FLAG_TIMEOUT;
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(2);
  }

  /* Send the byte to be written */
  I2C_SendData(EEPROM_I2Cx,WriteAddr);

  I2CTimeout = I2CT_FLAG_TIMEOUT;  
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);
  }

  /* Send STOP condition */
  I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);

        return 1;
}

uint8_t Current_Address_Read(uint8_t ReadDatas,uint8_t ReadAddr)
{
  I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);

  I2CTimeout = I2CT_FLAG_TIMEOUT;  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))  
  {
    if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(4);
  }

  I2CTimeout = I2CT_FLAG_TIMEOUT;
  /* Send EEPROM address for write */
  I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Receiver);

  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))               ||程序停在这里
  {
    if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(5);
  }  
        while(I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)==0)  
                {
                        if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(6);
                }
  ReadDatas=I2C_ReceiveData(EEPROM_I2Cx);
               
        /* Disable Acknowledgement */
  I2C_AcknowledgeConfig(EEPROM_I2Cx, DISABLE);

  /* Send STOP Condition */
  I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);
                return 1;
}

int main(void)
{
        uint8_t read;
  USART_Config();
        LED_GPIO_Config();
        I2C_EE_Init();
  I2C_ByteWrite(10,EEP_Firstpage);
        Current_Address_Read(read,EEP_Firstpage);
        if(read==10)
        {
          LED_G(on);
        }else
        {
          LED_R(on);
        }
  while (1)
  {      
  }
}


   程序总是停在读EEPROM的过程传递I2C设备地址,不能继续往下执行,求解,把例程也看几遍,也想不出问题在哪。

回复

使用道具 举报

发表于 2018-1-20 09:01:40 | 显示全部楼层
检查初始化和硬件连接
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-1-21 22:39:09 | 显示全部楼层
uint16_t EEPROM_ADDRESS;

static  uint32_t  I2CTimeout = I2CT_LONG_TIMEOUT;   

static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode);

static void I2C_GPIO_Config(void)
{
  GPIO_InitTypeDef  GPIO_InitStruct;

        /* 使能与 I2C 有关的时钟 */
        RCC_APB1PeriphClockCmd( EEPROM_I2C_CLK, ENABLE );
        RCC_APB2PeriphClockCmd( EEPROM_I2C_GPIO_CLK, ENABLE );
       
   
  /* I2C_SCL、I2C_SDA*/
  GPIO_InitStruct.GPIO_Pin = EEPROM_I2C_SCL_PIN;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;               // 开漏输出
  GPIO_Init(EEPROM_I2C_SCL_PORT, &GPIO_InitStruct);
       
  GPIO_InitStruct.GPIO_Pin = EEPROM_I2C_SDA_PIN;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;               // 开漏输出
  GPIO_Init(EEPROM_I2C_SDA_PORT, &GPIO_InitStruct);       
       
}

static void I2C_Mode_Config(void)
{
  I2C_InitTypeDef  I2C_InitStruct;

  /* I2C 配置 */
  I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
       
        /* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */
  I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
       
  I2C_InitStruct.I2C_OwnAddress1 =I2Cx_OWN_ADDRESS7;
  I2C_InitStruct.I2C_Ack = I2C_Ack_Enable ;
         
        /* I2C的寻址模式 */
  I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
       
        /* 通信速率 */
  I2C_InitStruct.I2C_ClockSpeed = I2C_Speed;
  
        /* I2C 初始化 */
  I2C_Init(EEPROM_I2Cx, &I2C_InitStruct);
  
        /* 使能 I2C */
  I2C_Cmd(EEPROM_I2Cx, ENABLE);   
}
void I2C_EE_Init(void)
{

  I2C_GPIO_Config();

  I2C_Mode_Config();
  EEPROM_ADDRESS=0xA0;
}
这个是初始化程序,对照了例程,没看出有问题,现在是程序第一次向EEPROM写入数据正常,当读取数据时,程序停在输入地址这一步,也就是第二操作EEPROM时,通讯失败。基本程序附上,求解决。,
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-1-21 22:52:17 | 显示全部楼层
当我注释读取程序,继续写入第二个数时,程序同样停在发送地址后,程序不再响应,但是前一步的写入正常,为什么再执行写入就不可以了?求解
回复 支持 反对

使用道具 举报

发表于 2018-1-25 08:33:35 | 显示全部楼层
模拟I2C可以吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-1-25 16:25:42 | 显示全部楼层
    解决了,I2C初始没问题,主要是第一次写入后, 再进行第二操作时,中间没添加等待程序,导致二次应答失败。
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2025-1-17 21:37 , Processed in 0.034802 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表