打印

关于IIC通讯的问题,恳请大家帮忙!

[复制链接]
3888|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
syyy81|  楼主 | 2011-1-6 11:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用一个IIC读取EEPROM的实验例程改了下,用做与LIS3LV02DQ的芯片进行通信,结果怎么调也弄不来,恳请大家帮看看程序。

i2c_ee.h文件
#include "stm32f10x.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Use the defines below the choose the EEPROM type */
//#define EE_M24C08  /* Support the device: M24C08. */
/* note: Could support: M24C01, M24C02, M24C04 and M24C16 if the blocks and
   HW address are correctly defined*/
//#define EE_M24C64_32  /* Support the devices: M24C32 and M24C64 */
#define EE_24LC02 /* STM32F103ZE-EK开发板缺省配置的芯片是24LC02 */
/* Defines for the GPIO pins used for the I2C communication */
#define I2C_EE             I2C1
#define I2C_EE_CLK         RCC_APB1Periph_I2C1
#define I2C_EE_GPIO        GPIOB
#define I2C_EE_GPIO_CLK    RCC_APB2Periph_GPIOB
#define I2C_EE_SCL         GPIO_Pin_6
#define I2C_EE_SDA         GPIO_Pin_7
#ifdef EE_M24C64_32
/* For M24C32 and M24C64 devices, E0,E1 and E2 pins are all used for device
  address selection (ne need for additional address lines). According to the
  Harware connection on the board (on STM3210C-EVAL board E0 = E1 = E2 = 0) */
#define EEPROM_HW_ADDRESS     0x1D   /* E0 = E1 = E2 = 0 */
#define I2C_Speed             200000
#define I2C_SLAVE_ADDRESS7    0x1D
#define I2C_FLASH_PAGESIZE    32
#elif defined (EE_M24C08)
/* The M24C08W contains 4 blocks (128byte each) with the adresses below: E2 = 0
   EEPROM Addresses defines */
#define EEPROM_Block0_ADDRESS 0x1D   /* E2 = 0 */
#define I2C_Speed             200000
#define I2C_SLAVE_ADDRESS7    0x1D
#define I2C_FLASH_PAGESIZE    16
#elif defined (EE_24LC02)
/* The M24C08W contains 4 blocks (128byte each) with the adresses below: E2 = 0
   EEPROM Addresses defines */
#define EEPROM_Block0_ADDRESS 0x1D   /* E2 = 0 */
#define I2C_Speed             200000
#define I2C_SLAVE_ADDRESS7    0x1D
#define I2C_FLASH_PAGESIZE    8
#endif /* EE_M24C64_32 */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void I2C_EE_Init(void);
void I2C_EE_ByteWrite(uint8_t i2c_data, uint8_t WriteAddr);
void I2C_EE_PageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite);
void I2C_EE_BufferWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite);
uint8_t I2C_EE_BufferRead(uint8_t ReadAddr,uint8_t NumByteToRead);
void I2C_EE_WaitEepromStandbyState(void);
#endif /* __I2C_EE_H */

i2c_ee.c文件
#include "i2c_ee.h"
/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */
/** @addtogroup I2C_EEPROM
  * @{
  */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t EEPROM_ADDRESS = 0x1D;
/* Private function prototypes -----------------------------------------------*/
void GPIO_Configuration(void);
void I2C_Configuration(void);
/* Private functions ---------------------------------------------------------*/
/**
  * @brief  Configure the used I/O ports pin
  * @param  None
  * @retval None
  */
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  
  /* Configure I2C_EE pins: SCL and SDA */
  GPIO_InitStructure.GPIO_Pin =  I2C_EE_SCL | I2C_EE_SDA;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  GPIO_Init(I2C_EE_GPIO, &GPIO_InitStructure);
}
/**
  * @brief  I2C Configuration
  * @param  None
  * @retval None
  */
void I2C_Configuration(void)
{
  I2C_InitTypeDef  I2C_InitStructure;
  
  /* I2C configuration */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
   I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
  
  /* I2C Peripheral Enable */
  I2C_Cmd(I2C_EE, ENABLE);
  /* Apply I2C configuration after enabling it */
  I2C_Init(I2C_EE, &I2C_InitStructure);
}
/**
  * @brief  Initializes peripherals used by the I2C EEPROM driver.
  * @param  None
  * @retval None
  */
void I2C_EE_Init()
{
  /* I2C Periph clock enable */
  RCC_APB1PeriphClockCmd(I2C_EE_CLK, ENABLE);   
  
  /* GPIO Periph clock enable */
  RCC_APB2PeriphClockCmd(I2C_EE_GPIO_CLK, ENABLE);   
  
  /* GPIO configuration */
  GPIO_Configuration();
  /* I2C configuration */
  I2C_Configuration();
  
}
/**
  * @brief  Writes one byte to the I2C EEPROM.
  * @param  pBuffer : pointer to the buffer  containing the data to be
  *   written to the EEPROM.
  * @param  WriteAddr : EEPROM's internal address to write to.
zhgmdh2009
  * @retval None
  */
void I2C_EE_ByteWrite(uint8_t i2c_data, uint8_t WriteAddr)
{
  /* Send STRAT condition */
  I2C_GenerateSTART(I2C_EE, ENABLE);
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT));  
  /* Send EEPROM address for write */
  I2C_Send7bitAddress(I2C_EE, EEPROM_ADDRESS, I2C_Direction_Transmitter);
  
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  I2C_SendData(I2C_EE, WriteAddr);  
  
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  /* Send the byte to be written */
  I2C_SendData(I2C_EE, i2c_data);
   
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  
  /* Send STOP condition */
  I2C_GenerateSTOP(I2C_EE, ENABLE);
}
/**
  * @brief  Reads a block of data from the EEPROM.
  * @param  pBuffer : pointer to the buffer that receives the data read
  *   from the EEPROM.
  * @param  ReadAddr : EEPROM's internal address to read from.
  * @param  NumByteToRead : number of bytes to read from the EEPROM.
  * @retval None
  */
uint8_t I2C_EE_BufferRead(uint8_t ReadAddr,uint8_t NumByteToRead)
{  
  uint8_t I2CData;
/* While the bus is busy */
  while(I2C_GetFlagStatus(I2C_EE, I2C_FLAG_BUSY));
  
  /* Send START condition */
  I2C_GenerateSTART(I2C_EE, ENABLE);
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT));
   
  /* Send EEPROM address for write */
  I2C_Send7bitAddress(I2C_EE, EEPROM_ADDRESS, I2C_Direction_Transmitter);
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  
  /* Clear EV6 by setting again the PE bit */
  I2C_Cmd(I2C_EE, ENABLE);
  /* Send the EEPROM's internal address to read from: Only one byte address */
  I2C_SendData(I2C_EE, ReadAddr);   
  
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  
  /* Send STRAT condition a second time */  
  I2C_GenerateSTART(I2C_EE, ENABLE);
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT));
  
  /* Send EEPROM address for read */
  I2C_Send7bitAddress(I2C_EE, EEPROM_ADDRESS, I2C_Direction_Receiver);
  
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  
  /* While there is data to be read */
  while(NumByteToRead)  
  {
    if(NumByteToRead == 1)
    {
      /* Disable Acknowledgement */
      I2C_AcknowledgeConfig(I2C_EE, DISABLE);
      
      /* Send STOP Condition */
      I2C_GenerateSTOP(I2C_EE, ENABLE);
    }
    /* Test on EV7 and clear it */
    if(I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_RECEIVED))  
    {      
      /* Read a byte from the EEPROM */
      I2CData = I2C_ReceiveData(I2C_EE);
      /* Point to the next location where the byte read will be saved */
      
      /* Decrement the read bytes counter */
      NumByteToRead--;        
    }   
  }
  /* Enable Acknowledgement to be ready for another reception */
  I2C_AcknowledgeConfig(I2C_EE, ENABLE);
  return I2CData;
}

}}
沙发
bili| | 2011-1-6 11:22 | 只看该作者
楼主你用示波器看了对应引脚的时序是否输出?若有输出,根据I2C协议检查是否输出正确?没有输出就应该查看你的程序配置是否正确。

使用特权

评论回复
板凳
syyy81|  楼主 | 2011-1-6 11:22 | 只看该作者
自己先顶下吧,郁闷啊

使用特权

评论回复
地板
syyy81|  楼主 | 2011-1-6 11:26 | 只看该作者
这个程序是从一一个实验例程里改的,应该没问题,协议我是参考模块给的例程,也应该没问题。

使用特权

评论回复
5
ST_ARM| | 2011-1-6 11:58 | 只看该作者
问题出在这个函数:
I2C_CheckEvent(***);
用户在使用ST的软件库时,最好不要用这个函数。I2C其实没有什么问题,关键的问题是大家看到ST库里有一个例程,想也不想就拿来用,ST的软件库的那个I2C读写EEPROM例程的没有经过测试,关键是开发ST的评估板的部门没有在板子上使用EEPROM的芯片,编写工程师也就没有电路板去测试,他们只是按照流程写了一个,评估板的工程师也没有去测试。
所以大家使用ST的I2C时参考本论坛里lutlut1编写的例程,或自己编写。

我支持客户从来就没有在使用I2C出过问题。

使用特权

评论回复
6
sy126c| | 2011-1-6 19:08 | 只看该作者
我的密码丢了又注册了个账号,不知道楼上说的“本论坛里lutlut1编写的例程”我怎么搜不到?

使用特权

评论回复
7
sy126c| | 2011-1-6 19:09 | 只看该作者
我的密码丢了又注册了个账号,不知道楼上说的“本论坛里lutlut1编写的例程”我怎么

使用特权

评论回复
8
ST_ARM| | 2011-1-7 11:43 | 只看该作者
lut1lut发的,在精华区有。

使用特权

评论回复
9
mcu520| | 2011-1-9 19:22 | 只看该作者
I2C MARK

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

16

帖子

0

粉丝