历史上的今天
返回首页

历史上的今天

今天是:2025年06月03日(星期二)

正在发生

2018年06月03日 | STM32L系列+ADXL345的I2C调试

2018-06-03 来源:eefocus

STM32的硬件I2C调试确实要比模拟麻烦很多啊,一大堆的配置,调通F系列的,本以为直接移植到L系列会很轻松,没想到问题依然很多,现直接附上STM32L系列的I2C初始化及读写函数:

1.GPIO的初始化:

static void ADXL_LowLevel_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

/* 使能与 I2C1 有关的时钟 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE); 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);  


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure); 


  /*!< Configure sEE_I2C pins: SDA */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect PXx to I2C_SCL*/
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);


/* Connect PXx to I2C_SDA*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
  
}

2.I2C的初始化:

void I2C_ADXL_Init(void)
{  
I2C_InitTypeDef I2C_InitStructure;
ADXL_LowLevel_Init(); 
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = ADXL_ADRESS;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
  
  /* ADXL_I2C Peripheral Enable */
  I2C_Cmd(I2C1, ENABLE);
  /* Apply MEMS_I2C configuration after enabling it */
  I2C_Init(I2C1, &I2C_InitStructure); 
}

3.读

u8 I2C_ADXL_ByteRead(u8 ReadAddr)
{
u8 RxData;
/*wait until I2C bus is not busy*/
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* Send START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  /* Send ADXL address for write */
  I2C_Send7bitAddress(I2C1, ADXL_ADRESS, I2C_Direction_Transmitter);
    /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    /* Send the ADXL's Register address to write to */
  I2C_SendData(I2C1, ReadAddr);  
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF) == RESET);
  /* Send STRAT condition a second time */  
  I2C_GenerateSTART(I2C1, ENABLE);
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  /* Send ADXL address for read */
  I2C_Send7bitAddress(I2C1, ADXL_ADRESS, I2C_Direction_Receiver);
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == RESET);
  /* Disable Acknowledgement */
    I2C_AcknowledgeConfig(I2C1, DISABLE);
(void)I2C1->SR2;
  
  /*!< Send STOP Condition */
  I2C_GenerateSTOP(I2C1, ENABLE);
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET);
  
/* Read a byte from the ADXL Register */
RxData = I2C_ReceiveData(I2C1);
while(I2C1->CR1 & I2C_CR1_STOP);
    I2C_AcknowledgeConfig(I2C1, ENABLE);


return RxData;
}

4. 写

void I2C_ADXL_ByteWrite(u8 pBuffer, u8 WriteAddr)
{
  /*wait until I2C bus is not busy*/
  while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
    
/* Send START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
    /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); 
  
   /* Send MMA address for write */
  I2C_Send7bitAddress(I2C1, ADXL_ADRESS, I2C_Direction_Transmitter);
    
/* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
   
    /* Send the MMA's Register address to write to */    
  I2C_SendData(I2C1, WriteAddr); 
  
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
   
    /* Send the byte to be written */
  I2C_SendData(I2C1, pBuffer);
  
   /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  
   
   /* Send STOP condition */
  I2C_GenerateSTOP(I2C1, ENABLE);


}


推荐阅读

史海拾趣

问答坊 | AI 解惑

菜鸟请教!多开关控制多个发光二极管C程序

  要求:按下开关灯亮,断开开关灯灭。 我用switch语句,按下开关灯亮了,可断开开关灯就是不灭,我改了n次了它还是不灭,我已经拿它没办法了,求哥哥们给个C语言的程序,谢谢!   比如:按k1,led1亮;按k2,led2与led3亮;按 ...…

查看全部问答>

74HC165应用

各位高手,谁用过74HC165 芯片,想用它结合51单片机,LED数码管做个计数器。 可不会应用此芯片。哪位高手,分享下经验。谢谢…

查看全部问答>

OK2440 DNW下载内核文件(nk.bin)

    有没有哪位高人用过OK2440开发板?小弟我刚开始学习,遇到很奇怪的问题,就是使用DNW的USB下载内核文件nk.bin或者nk.nb0时,一直提示checksum error!MEM:1502 DN:200 Invalid BIN file signature!24,d0,24,6c,af,d0,24   &nbs ...…

查看全部问答>

CE5下怎么基于现有BSP复制出一个新的BSP(名称不同),并且能够在新BSP上建立新的CE工程,要些改什么地方?

CE5下怎么基于现有BSP复制出一个新的BSP(名称不同),并且能够在新BSP上建立新的CE工程,要些改什么地方?…

查看全部问答>

页表问题

每个进程都有一个页表吗? 不是每个进程的系统空间【0x80000000-0xffffffff】都是同一物理地址吗? 页表在0xc00000000,每个进程页表不一样这里就不一样了,怎么回事啊? 头晕…

查看全部问答>

sqlite3如何建库,如何读?

从网上找了个sqlite3.exe,就这一个文件, 直接双击,就是sqlite> 在网上查了一下,建库有好多的方法,什么$,sqlite3 xxx.db等, 执行就报sql error。 直接create table .....OK。 insert .......OK。 .exit以后再打开sqlite3.exe时,刚才建 ...…

查看全部问答>

侃侃我的成果

本人长期从事单片机开发应用,积累了一定的经验。本人将毕生研究心得集成了文字,放在我的博客里,希望大家光临指导,并给点意见。我的博客地址;http://blog.mcuol.com/user/Article/500.html…

查看全部问答>

我的应急灯经验

我做的比较晚,现在才发表一下自己的见解。真的很感谢EEWORLD能提供这样的机会,让我们获得好多的知识。 在做应急灯的过程中,我主要能获得的就是在设计电路中自己的一点小小经验吧。 在到设计电路中,我都是拿一个集成模块,根据标准电路来设计 ...…

查看全部问答>

modelsim 6.5仿真遇到的问题

用modelsim 6.5仿真为什么会报下面的错误?请高手指教 vsim work.vtf_test# vsim work.vtf_test # Loading work.vtf_test(fast)# Loading work.modelsim_test(fast)# Loading work.maxii_io(fast)# Loading work.maxii_lcell(fast)# Loading work. ...…

查看全部问答>

IARSTM8-ServicePack1.10.4发布了

                                 IAR STM8 - Service Pack 1.10.4 发布了…

查看全部问答>