打印

STM32 的I2C2并接ADXL345和MPU3050时无法工作

[复制链接]
5319|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
EWB5|  楼主 | 2012-3-6 20:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 EWB5 于 2012-3-6 20:40 编辑

下面是主程序main和一个自己编改的程序i2c__ee.c(包括.h文件):
#include "stm32f10x_lib.h"
#include "i2c_ee.h"

u8 set1_buffer[7]={0x0B,0x0B,0x08,0x80,0x00,0x00,0x00};  ////adxl345设置参数
u8 reg1_buffer[7]={0x31,0x2c,0x2d,0x2e,0x1e,0x1f,0x20};
u8 set2_buffer[5]={0x80,0x07,0x1E,0x00,0x00};  ////mpu3050设置参数
u8 reg2_buffer[5]={0x3E,0x15,0x16,0x17,0x3E};
u8 rx1_buffer[6];  //adxl345接受的数据
u8 rx2_buffer[8];  //mpu3050接受的数据
u8 devid[1];           //描述硬件ID代码

ErrorStatus HSEStartUpStatus;
void RCC_Configuration(void);
void NVIC_Configuration(void);
void GPIO_Configuration(void);
void delay(u32 count);
/*******************************************************************************
*******************************************************************************/
void main(void)
{
  delay(0xFFFFF);  //上电延时
  #ifdef DEBUG
    debug();
  #endif   
  RCC_Configuration();  
  NVIC_Configuration();
  GPIO_Configuration();
  My_IIC_Init();
/******** ADXL345设备的配置启动************/
  I2C2_ByteWrite(adxl345_id,set1_buffer+0, reg1_buffer[0]);//数据格式控制,禁用自测力,中断高电平有效,全分辨率模式(正负16g,13 bit),右对齐并带符号扩展
  I2C2_ByteWrite(adxl345_id,set1_buffer+1, reg1_buffer[1]);//非低功耗模式,器件带宽为12.5Hz,输出数据速率为25Hz;(默认带宽50,速率100 )
  I2C2_ByteWrite(adxl345_id,set1_buffer+2, reg1_buffer[2]);//静止功能和活动功能同时打开,禁止自动切换至休眠模式,测量模式,不休眠
  I2C2_ByteWrite(adxl345_id,set1_buffer+3, reg1_buffer[3]);//只使能DATA_READY中断
  I2C2_ByteWrite(adxl345_id,set1_buffer+4, reg1_buffer[4]);//X 偏移量
  I2C2_ByteWrite(adxl345_id,set1_buffer+5, reg1_buffer[5]);//Y 偏移量
  I2C2_ByteWrite(adxl345_id,set1_buffer+6, reg1_buffer[6]);//Z 偏移量      
/******** MPU3050设备的配置启动************/
  I2C2_ByteWrite(mpu3050_id,set2_buffer+0, reg2_buffer[0] );     
  I2C2_ByteWrite(mpu3050_id,set2_buffer+1, reg2_buffer[1] );   
  I2C2_ByteWrite(mpu3050_id,set2_buffer+2, reg2_buffer[2] );  
  I2C2_ByteWrite(mpu3050_id,set2_buffer+3, reg2_buffer[3] );  
  I2C2_ByteWrite(mpu3050_id,set2_buffer+4, reg2_buffer[4] );
/******** ADXL345读出的数据为0xE5,表示正确 ************/
  I2C2_BufferRead(adxl345_id,0x00,1,devid);
  if( *devid==0xE5 )
  { GPIO_SetBits(GPIOC, GPIO_Pin_6); }  
/***************** 数据存储************************/
  I2C2_BufferRead(adxl345_id,0x32,6,rx1_buffer);  GPIO_SetBits(GPIOC, GPIO_Pin_7);  delay(0xfffff);// ADXL345读出的数据保存  
  I2C2_BufferRead(mpu3050_id,0x1B,8,rx2_buffer);  GPIO_SetBits(GPIOC, GPIO_Pin_8);  delay(0xfffff);// MPU3050读出的数据保存   
  while (1)
  {
    GPIO_SetBits(GPIOC, GPIO_Pin_9);
  }
}
/*******************************************************************************
* Function Name  : RCC_Configuration
* Description    : Configures the different system clocks.
*******************************************************************************/
void RCC_Configuration(void)
{
  RCC_DeInit();  /* RCC system reset(for debug purpose) */
  RCC_HSEConfig(RCC_HSE_ON);  /* Enable HSE */
  HSEStartUpStatus = RCC_WaitForHSEStartUp(); /* Wait till HSE is ready */
  if(HSEStartUpStatus == SUCCESS)
  {   
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* Enable Prefetch Buffer */
    FLASH_SetLatency(FLASH_Latency_2);/* Flash 2 wait state */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);  /* HCLK = SYSCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);  /* PCLK2 = HCLK */
    RCC_PCLK1Config(RCC_HCLK_Div2); /* PCLK1 = HCLK/2 */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); /* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLCmd(ENABLE); /* Enable PLL */   
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)/* Wait till PLL is ready */
     {   }  
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* Select PLL as system clock source */   
    while(RCC_GetSYSCLKSource() != 0x08)/* Wait till PLL is used as system clock source */
     {   }
  }
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);/* GPIOB and GPIOC Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2 , ENABLE);  
}
/*******************************************************************************
* Function Name  : NVIC_Configuration
*******************************************************************************/
void NVIC_Configuration(void)
{
    #ifdef  VECT_TAB_RAM   
       NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); /* Set the Vector Table base location at 0x20000000 */
  #else
       NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);    /* VECT_TAB_FLASH  Set the Vector Table base location at 0x08000000 */
  #endif
}
/*******************************************************************************
* Function Name  : GPIO_Configuration
*******************************************************************************/
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;   
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure PB.10, PC.11 as  SCL & SDA */  
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);  /* Configure PC.06, PC.07, PC.08 and PC.09 as Output push-pull */  
}
/***************************************************/
void delay(u32 count)
{
for(; count != 0; count--);
}
/*******************************************************************************
* Function Name  : assert_failed
* Description    : Reports the name of the source file and the source line number
*                  where the assert_param error has occurred.
* Input          : - file: pointer to the source file name
*                  - line: assert_param error line source number
*******************************************************************************/
#ifdef  DEBUG
void assert_failed(u8* file, u32 line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/*********** (C) COPYRIGHT 2007 STMicroelectronics *****END OFF LILE****/
接下来是i2c_ee.c的内容:
#include "i2c_ee.h"
extern void delay(u32 count);
extern u8 rx1_buffer[6];  //adxl345接受的数据
extern u8 rx2_buffer[6];  //mpu3050接受的数据
/*******************************************************************************
* Function Name  : My_IIC_Init
* Description    : Initializes peripherals used by the I2C EEPROM driver.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void My_IIC_Init()
{
  I2C_InitTypeDef  I2C_InitStructure;      
  I2C_SoftwareResetCmd(I2C2,ENABLE);
  I2C_SoftwareResetCmd(I2C2,DISABLE);
  
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = 0x30 ; //////////// I2C地址为 0x30
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = 10000;
  I2C_Cmd(I2C2, ENABLE);
  I2C_AcknowledgeConfig(I2C2, ENABLE);
  I2C_Init(I2C2, &I2C_InitStructure);

}
/*******************************************************************************
* Function Name  : I2C2_ByteWrite
*******************************************************************************/
void I2C2_ByteWrite(u8 slave_id,u8* pBuffer, u8 WriteAddr) //原数据地址指针,slave器件内部地址,slave器件ID
{     
   I2C_GenerateSTART(I2C2, ENABLE);   //delay(0x1ff); //// Send STRAT condition ////
   while( !I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) );  /* Test on EV5 and clear it 起始位已经发送 */
   
  I2C_Send7bitAddress(I2C2, slave_id, I2C_Direction_Transmitter); // delay(0x1ff); ////Send 0xA6 for connect ////
  while( !I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) );  /* Test on EV6 and clear it 地址已发送 */
  
  I2C_SendData(I2C2, WriteAddr);  //delay(0x1ff); //// Send the reg_buffer to write to ////
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  /* Test on EV8 and clear it 发送缓冲区空 */
  
  I2C_SendData(I2C2, *pBuffer);// delay(0x1ff);  //// Send the set_buffer to be written ////
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  /* Test on EV8 and clear it 发送缓冲区空 (即发完了)*/
  
  I2C_GenerateSTOP(I2C2, ENABLE); //// Send STOP condition ////
}
/*******************************************************************************
* Function Name  : I2C2_BufferRead
* Input          : - pBuffer : pointer to the buffer that receives the data read from the reg.
*                  - ReadAddr : EEPROM's internal address to read from.
*                  - NumByteToRead : number of bytes to read from the EEPROM.
*******************************************************************************/
void I2C2_BufferRead(u8 slave_id,u8 ReadAddr, u16 NumByteToRead,u8* pBuffer)
{  
  I2C_GenerateSTART(I2C2, ENABLE); ////Send START condition ////
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));              /* Test on EV5 and clear it 起始位已经发送 */
  
  if( NumByteToRead==1 )                                         /*In the case of a single data transfer disable ACK before reading the data */
  {  I2C_AcknowledgeConfig(I2C2, DISABLE);  }
  else
  {  I2C_AcknowledgeConfig(I2C2, ENABLE);  }
  
  I2C_Send7bitAddress(I2C2,slave_id,I2C_Direction_Transmitter);   //// Send 0xA6 for connect ////
  // I2C2->DR = 0xA7;
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  /* Test on EV6 and clear it 地址已发送或地址匹配 */
  
// I2C_Cmd(I2C1, ENABLE);                                                     /* Clear EV6 by setting again the PE bit */   
  I2C_SendData(I2C2,ReadAddr);   //// Send the ADXL reg_address to write to ////
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));           /* Test on EV8 and clear it 发送缓冲区空*/
  
  I2C_GenerateSTART(I2C2, ENABLE);    //// Send STRAT condition again////  
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));         /* Test on EV5 and clear it 起始位已经发送*/
  
  I2C_Send7bitAddress(I2C2, slave_id, I2C_Direction_Receiver); //// Send 0xA7 for connect ////
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));      /* Test on EV6 and clear it 地址已发送 */
  
  while(NumByteToRead)   
  {
    if(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED))    /* Test on EV7 and clear it接受缓冲区非空(即有接受数据) */
    {
      *pBuffer = I2C_ReceiveData(I2C2);  
      if( NumByteToRead == 2 )      ////这是倒数二个数据
       { I2C_AcknowledgeConfig(I2C2, DISABLE); }    /* Disable Acknowledgement */
      if( NumByteToRead == 1 )      ////这是最后一个数据
       { I2C_GenerateSTOP(I2C2, ENABLE); }      /* Send STOP Condition */  
       pBuffer++;        
       NumByteToRead--;      
     }   //// end if
  }

}

/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
之所以没有分别用I2C1和I2C2分别驱动两个传感器是因为开发板上的I2C1的PB6、PB7接了温度传感器,而且单独驱动其中一个时也是只能用I2C2,我怀疑是温度传感器影响了我买的两个传感器模块的工作,但是现在两个并接在I2C2上不正常是不是也是这个问题呢,他们之间相互干扰????
最下面是.h文件:
#ifndef __I2C_EE_H
#define __I2C_EE_H

#include "stm32f10x_lib.h"

#define adxl345_id 0xA6   
#define mpu3050_id 0x00

void My_IIC_Init(void);
void I2C2_ByteWrite(u8 slave_id,u8* pBuffer, u8 WriteAddr);
void I2C2_BufferRead(u8 slave_id,u8 ReadAddr, u16 NumByteToRead,u8* pBuffer);

#endif

myself.rar

384.16 KB

源文件

沙发
香水城| | 2012-3-7 22:51 | 只看该作者
分别单独接可以正常工作吗?

如果可以,请降低时钟速率试试看。

使用特权

评论回复
板凳
ljxpro| | 2016-1-23 17:54 | 只看该作者
我的神州1号开发板上I2C1接有AT24C02,单独没问题;接上ADXL345经常出现初始化后总线锁死。好多帖子说STM32的I2C有Bug。没有设置中断优先级,不知是否与此有关。楼主单独接ADXL345能调通吗?

使用特权

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

本版积分规则

个人签名:小鸟一个有待提高

0

主题

14

帖子

0

粉丝