Skip to main content
ASING.91
Associate III
January 24, 2019
Question

I2C program for STM32L053R8T6 not working.

  • January 24, 2019
  • 2 replies
  • 663 views

My code to write directly to registers for I2C communication between Lis3dh accelerometer and STM32L053R8T6 is not working. Only CMSIS drivers are used. Could you give some suggestions. [I am looking to learn the basics of STM32 and have tried HAL drivers already]

#include "stm32l0xx.h"

#include "stdio.h"

/* accelerometer definitions*/

#define lis3dh_address 0x19       //0x18 if sd0 connected to ground   //0x19 if sd0 connected to power supply

#define who_am_i 0x0F

/*STM32 definitions*/

#define buffersize 1

uint32_t I2C2_RX_Data[buffersize];

uint8_t I2C_Read_Reg(uint8_t Device,uint8_t Register);

int main(void)

{

 

 //LSI clock

 RCC->CSR = RCC_CSR_LSION;

 while((RCC->CSR & RCC_CSR_LSIRDY)!=RCC_CSR_LSIRDY);  //check the stablity of the low speed oscillator

 

 RCC->IOPENR |= RCC_IOPENR_GPIOBEN;              //IO port B clock enable bit This bit is set and cleared by software.

 

 /* (1) PU for I2C signals */

 /* (2) open drain for I2C signals */

 /* (3) AF5 for I2C signals */

 /* (4) Select AF mode (10) on PB13 and PB14 */

 GPIOB->PUPDR |= (GPIOB->PUPDR & ~(GPIO_PUPDR_PUPD13 | GPIO_PUPDR_PUPD14)) \

                | (GPIO_PUPDR_PUPD13_0 | GPIO_PUPDR_PUPD14_0); /* (1) */

 GPIOB->OTYPER |= GPIO_OTYPER_OT_13 | GPIO_OTYPER_OT_14; /* (2) */

 GPIOB->OSPEEDR |= 2<<26 | 2<<28;

 GPIOB->AFR[1] |= 5<<20 | 5<<24;

 

 GPIOB->MODER |= (GPIOB->MODER & ~(GPIO_MODER_MODE13 | GPIO_MODER_MODE14)) | (GPIO_MODER_MODE13_1 | GPIO_MODER_MODE14_1);

 

 I2C_Read_Reg(lis3dh_address,who_am_i);

       // printf("receive interrupt %d, receive output",a);

}

uint8_t I2C_Read_Reg(uint8_t Device,uint8_t Register)

{

 /*3. I2C configured in master mode to transmit*/

 

 

 I2C2->CR2|= (0x2FF67FF & 0x00); //Reset CR2 Register

 I2C2->TIMINGR |= 0x10420F13;

 RCC->APB1ENR|=RCC_APB1ENR_I2C2EN;

 

 I2C2->CR1 |= I2C_CR1_PE;

 while((I2C2->ISR & I2C_ISR_BUSY) == I2C_ISR_BUSY){};

 I2C2->CR2 |= ~I2C_CR2_ADD10|(Device<<1)|~I2C_CR2_RD_WRN|(1<<16);

 I2C2->CR2 |= I2C_CR2_START;

 

 NVIC_SetPriority(I2C2_IRQn, 0);   // Set priority for I2C2_IRQn

 NVIC_EnableIRQ(I2C2_IRQn);     // Enable I2C2_IRQn 

  

  if((I2C2->ISR & I2C_ISR_TXE) == (I2C_ISR_TXE))

  {

  I2C2->TXDR = Register;  

 I2C2->CR2 |= I2C_CR2_START;

  }

//read mode for Device

  I2C2->CR1 |=I2C_CR1_PE|I2C_CR1_RXIE;

  

  I2C2->CR2 |= (0x2FF67FF)|(Device<<1|(1<<16)|I2C_CR2_RD_WRN);

  while((I2C2->ISR & I2C_ISR_BUSY) != I2C_ISR_BUSY){};

  I2C2->CR2 |= ~I2C_CR2_START;

  

  while((I2C2->ISR & I2C_ISR_RXNE) != I2C_ISR_RXNE){};

  {

   I2C2_RX_Data[buffersize-1]=I2C2->RXDR;

   

  }

 return(*I2C2_RX_Data);

}

This topic has been closed for replies.

2 replies

S.Ma
Principal
January 24, 2019

Plan B: Use my shared SW GPIO I2C Master example.

ASING.91
ASING.91Author
Associate III
January 25, 2019

Well sounds like a good plan ! Thank you. But I have the i2c working using HAL and LL functions. I want to program it register wise, to get more understanding and small code.