打印

stm32 iic驱动ADXL345

[复制链接]
6366|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
EWB5|  楼主 | 2012-3-11 17:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
stm32 iic驱动ADXL345用库函数写得,以前可以的 不知道怎么就突然不行了
#include "stm32f10x_lib.h"
#include "i2c_ee.h"

u8 set_buffer[7]={0x0B,0x0B,0x08,0x80,0x00,0x00,0x00};  ////adxl345设置参数
u8 reg_buffer[7]={0x31,0x2c,0x2d,0x2e,0x1e,0x1f,0x20};
u8 ry_buffer[6];  //adxl345接受的数据
u8 NUM_ADXL =6;
u8 adxl_n=0;
u8 devid[1];           //描述硬件ID代码

ErrorStatus HSEStartUpStatus;
void RCC_Configuration(void);
void NVIC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void delay(u32 count);
/*******************************************************************************
*******************************************************************************/
int main(void)
{  
  #ifdef DEBUG
    debug();
  #endif   
  RCC_Configuration();  
  NVIC_Configuration();
  GPIO_Configuration();
  USART_Configuration();
  My_IIC_Init();
  delay(0xFFFFF);  //上电延时
/******** ADXL345设备的配置启动************/  
  I2C_ByteWrite(adxl345_id,set_buffer+0, reg_buffer[0]);//数据格式控制,禁用自测力,中断高电平有效,全分辨率模式(正负16g,13 bit),右对齐并带符号扩展
  I2C_ByteWrite(adxl345_id,set_buffer+1, reg_buffer[1]);//非低功耗模式,器件带宽为12.5Hz,输出数据速率为25Hz;(默认带宽50,速率100 )
  I2C_ByteWrite(adxl345_id,set_buffer+2, reg_buffer[2]);//静止功能和活动功能同时打开,禁止自动切换至休眠模式,测量模式,不休眠
  I2C_ByteWrite(adxl345_id,set_buffer+3, reg_buffer[3]);//只使能DATA_READY中断
  I2C_ByteWrite(adxl345_id,set_buffer+4, reg_buffer[4]);//X 偏移量
  I2C_ByteWrite(adxl345_id,set_buffer+5, reg_buffer[5]);//Y 偏移量
  I2C_ByteWrite(adxl345_id,set_buffer+6, reg_buffer[6]);//Z 偏移量
  I2C_BufferRead(adxl345_id,0x00,1,devid);
  while (1)
  {  
     I2C_BufferRead(adxl345_id,0x32,6,ry_buffer);  // ADXL345读出的数据保存
     while(NUM_ADXL--)   //ADXL
     {
        USART_SendData( USART1,ry_buffer[adxl_n++] );
       while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  
     }
     NUM_ADXL=6; adxl_n=0;
  }
}

/*******************************************************************************
* 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 | RCC_APB2Periph_GPIOC, ENABLE);/* GPIOB and GPIOC Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2 , ENABLE); /*   I2C1 Periph clock enable */
  /* Enable GPIOD and AFIO clocks */
  //RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  /* Enable USART2 clocks */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  
}
/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description    : Configures Vector Table base location.
*******************************************************************************/
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
* Description    : Configures the different system clocks.
*******************************************************************************/
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_PinRemapConfig(GPIO_Remap_USART2, DISABLE);/* Enable the USART2 Pins Software Remapping */
      /* Configure USART2 RTS (PD.04) and USART2 Tx (PD.05) as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //| GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
       /* Configure USART2 CTS (PD.03) and USART2 Rx (PD.06) as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //| GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}  

/*******************************************************************************
* Function Name  : USART_Configuration
*******************************************************************************/
void USART_Configuration(void)
{
  USART_InitTypeDef USART_InitStructure;
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No ;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //USART_HardwareFlowControl_RTS_CTS;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_InitStructure.USART_Clock = USART_Clock_Disable;
  USART_InitStructure.USART_CPOL = USART_CPOL_Low;
  USART_InitStructure.USART_CPHA = USART_CPHA_2Edge;
  USART_InitStructure.USART_LastBit = USART_LastBit_Disable;
  USART_Init(USART1, &USART_InitStructure);
  USART_Cmd(USART1, ENABLE); /* Enable the USART2 */
}
/***************************************************/
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
* Output         : None
* Return         : None
*******************************************************************************/
#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 OF

下面是.C文件
#include "i2c_ee.h"

/*******************************************************************************
* 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 I2C_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 I2C_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
  }

}

这不行可能是I2C内部硬件不行,但是后来用IO口写得也突然不行了额:
穿了一下附件,请大家指教一下啊~~都弄快20天了

1-ADXL_IO_ok.rar

252.48 KB

1-ADXL_I2C2_flag.rar

257.71 KB

沙发
李富贵| | 2012-3-11 18:17 | 只看该作者
I2C中断要最高优先级,否则会卡死,这是一个陷阱,因为单独调I2C是没有问题的,加上其他部件就完蛋了。

使用特权

评论回复
板凳
ljxpro| | 2016-1-23 17:43 | 只看该作者
1、我也是用STM32F10x_StdPeriph_Lib_V3.5.0库函数一直调不通。找到的例子多是模拟的,不想用模拟,想学习I2C硬件。
2、现在尝试wgsxsm的方法(https://bbs.21ic.com/forum.php?mo ... p;highlight=ADXL345),使用STM32Cube建立工程,看ST是如何配置的。但使用的不是库函数了,是HAL库函数。
3、感觉似乎是轮询模式中需要加延时,也在考虑使用STM32F10x_StdPeriph_Lib_V3.5.0库函数的中断模式。在8051F340上使用中断可以调通。

使用特权

评论回复
地板
hugo0chen| | 2016-4-4 17:34 | 只看该作者
最近也在高stm32l151的硬件IIC 还没高搞定,死在ev5

使用特权

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

本版积分规则

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

0

主题

14

帖子

0

粉丝