阿松松 发表于 2015-1-5 14:38:39

关于STM32硬件I2C问题

前面和大家分享了模拟I2C代码,也来谈谈我的硬件I2C。
传感器地址为0x1a,这是实际的SCL与SDA波形图

下面这个图纯属测试,测试是否发出的数据正确,发送的数据为0xaa

代码如下,配置文件也检查了好几遍,并没有发现什么问题,可代码在发送了device地址后,就停了。

请牛牛们帮忙分析



/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_i2c.h"
#include "user_i2c.h"

/**
* @briefInitializes peripherals used by the I2C Periph driver.
* @paramNone
* @retval None
*/
void I2C_HighLevel_Init(void)
{

GPIO_InitTypeDefGPIO_InitStructure;

/*!< I2C Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

/*!< I2C_SCL_GPIO_CLK and I2C_SDA_GPIO_CLK Periph clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

/*!< GPIO configuration */
/*!< Configure I2C pins: SCL */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);//高电平到低电平跳变

/*!< Configure I2C pins: SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);//高电平到低电平跳变?
/*!< GPIO configuration */
/* Connect PXx to I2C_SCL*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);//低电平到高电平跳变?
/* Connect PXx to I2C_SDA*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);//低电平到高电平跳变?

/*!< I2C configuration */
I2C_InitTypeDefI2C_InitStructure;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 200000;

/* I2C Peripheral Enable */
I2C_Cmd(I2C1, ENABLE);

/* Apply I2C configuration after enabling it */
I2C_Init(I2C1, &I2C_InitStructure);
}



/**
* @brief Transmit start/adress/stop, receive sensors DATA from I2C Periph.
* @paramNone
* @retval None
*/
UV_Ambient_Sensor I2C_Read(uint8_t Device_Addr, uint8_t Reg_Addr,uint8_t NumByteToRead)
{
UV_Ambient_Sensor UV_value;

//UV_Ambient_Sensor uv_amb_sensor;//store sensor value
//while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));//check if i2c is busy

I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//wait ack
//I2C_GenerateSTART(I2C1, DISABLE);

I2C_Send7bitAddress(I2C1, Device_Addr, I2C_Direction_Transmitter);// write slave address
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//
//slave ack

/* Clear EV6 by setting again the PE bit */
I2C_Cmd(I2C1, ENABLE);

I2C_SendData(I2C1, Reg_Addr);// write slave register address
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//
//slave ack

/*!< Test on EV8 and clear it */
//while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF));//-------debug1

//I2C_GenerateSTOP(I2C1, ENABLE);//uv datasheet need,stand i2c?
//I2C_GenerateSTOP(I2C1, DISABLE);//stop transmit stop signal

I2C_GenerateSTART(I2C1, ENABLE);
//I2C_GenerateSTART(I2C1, DISABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//

I2C_Send7bitAddress(I2C1, Device_Addr, I2C_Direction_Receiver);// Read
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//
//slave ack

/* One Byte Master Reception procedure (POLLING) -----------------------------*/
/* While there is data to be read */
/*
while(NumByteToRead)
{
    if(NumByteToRead == 1)//Generate Stop before receive the last byte
    {*/
//      while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR));//-------debug2
      /* Disable Acknowledgement */
      I2C_AcknowledgeConfig(I2C1, DISABLE);
      
      /* Send STOP Condition */
      I2C_GenerateSTOP(I2C1, ENABLE);
//    }

    /* Test on EV7 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))//
    {      
      /* Read a byte from the sensor */
      UV_value.Ambient_value = I2C_ReceiveData(I2C1);

      /* Point to the next location where the byte read will be saved */
//      pBuffer++;
      
      /* Decrement the read bytes counter */
//      NumByteToRead--;      
    }
//}

/* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);
return UV_value;
}

void I2C_Write(uint8_t Device_Addr, uint8_t Reg_Addr, uint8_t Ctrl_Cmd)
{
//while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));//check if i2c is busy
I2C_GenerateSTART(I2C1, ENABLE);// SCL与SDA均产生下降沿信号
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//wait ack


I2C_Send7bitAddress(I2C1, Device_Addr, I2C_Direction_Transmitter);// write slave address,
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//
//slave ack

I2C_SendData(I2C1, Reg_Addr);// write slave register address
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//
//slave ack

I2C_SendData(I2C1, Ctrl_Cmd);// data to be written
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//
//slave ack

/* Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
}

/**
* @briefWait for EEPROM Standby state.
*
* @noteThis function allows to wait and check that EEPROM has finished the
*      last operation. It is mostly used after Write operation: after receiving
*      the buffer to be written, the EEPROM may need additional time to actually
*      perform the write operation. During this time, it doesn't answer to
*      I2C packets addressed to it. Once the write operation is complete
*      the EEPROM responds to its address.
*
* @paramNone
* @retval sEE_OK (0) if operation is correctly performed, else return value
*         different from sEE_OK (0) or the timeout user callback.
*/
void I2C_WaitEepromStandbyState(void)      
{
__IO uint16_t SR1_Tmp = 0;

/* Keep looping till the slave acknowledge his address or maximum number
   of trials is reached (this number is defined by sEE_MAX_TRIALS_NUMBER define
   in STM324x7I_eval_i2c_ee.h file) */
do
{
    /* Send START condition */
    I2C_GenerateSTART(I2C1, ENABLE);
    /* Read I2C1 SR1 register */
    SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);
    /* Send sensor address for write */
    I2C_Send7bitAddress(I2C1, 0x1A, I2C_Direction_Transmitter);
}while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));

/* Clear AF flag */
I2C_ClearFlag(I2C1, I2C_FLAG_AF);
/* STOP condition */   
I2C_GenerateSTOP(I2C1, ENABLE);
}




zhang7309 发表于 2015-1-5 15:00:01

楼主IIC用的那种模式呢?从器件是否应该有响应?

hlt512 发表于 2015-1-5 15:02:15

速度慢点,时序

阿松松 发表于 2015-1-5 15:10:10

zhang7309 发表于 2015-1-5 15:00
楼主IIC用的那种模式呢?从器件是否应该有响应?

从器件不响应似乎,很奇怪。
标准I2C,STM32主

阿松松 发表于 2015-1-5 15:11:15

hlt512 发表于 2015-1-5 15:02
速度慢点,时序

嗯,要标准速率吗,记得我试过100K的,还是不行。
我这个是200K的,一般来说,官方的要多快比较合适呢

linshifaa 发表于 2015-1-5 15:37:47

这是什么软件啊~

阿松松 发表于 2015-1-5 15:39:14

linshifaa 发表于 2015-1-5 15:37
这是什么软件啊~

软件????

linshifaa 发表于 2015-1-5 15:42:08

这个软件啊

晓枫VS枯叶 发表于 2015-1-5 15:42:19

4GSa/s这采样率,这示波器多少钱啊,测量信号的带宽能达到多少!

阿松松 发表于 2015-1-5 15:44:01

linshifaa 发表于 2015-1-5 15:42
这个软件啊

额,这个是示波器,图像可以直接抓取保存到U盘上
页: [1] 2 3
查看完整版本: 关于STM32硬件I2C问题