cancel
Showing results for 
Search instead for 
Did you mean: 

I2C program for STM32L053R8T6 not working.

ASING.91
Associate II

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);

}

2 REPLIES 2
S.Ma
Principal

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

ASING.91
Associate II

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.