cancel
Showing results for 
Search instead for 
Did you mean: 

I2C TXDR doesnt send the data on SDA. STM32F3 Discovery.

daniil-denisov
Associate
Posted on July 03, 2016 at 14:04

Sample program to get accelerometer data.


#include ''stm32f3xx.h'' // Device header


void
initSystem()

{

// LSM303DLHC wiring: SCL to PB6, SDA to PB7.

// Enable port B timing and set pins to alternate function mode. No pull-up/pull-down. 

RCC->AHBENR |= RCC_AHBENR_GPIOBEN;

GPIOB->MODER |= GPIO_MODER_MODER6_1|GPIO_MODER_MODER7_1;

GPIOB->OTYPER |= GPIO_OTYPER_OT_6|GPIO_OTYPER_OT_7;

GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR6 | GPIO_PUPDR_PUPDR7 );

GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 |GPIO_OSPEEDER_OSPEEDR7;

// Select AF4 (0100=0x4) to toggle I2C_SCL function on pin PB6 and I2C_SDA on pin PB7.

GPIOB->AFR[0] |= (0x4 << GPIO_AFRL_AFRL6_Pos);

GPIOB->AFR[0] |= (0x4 << GPIO_AFRL_AFRL7_Pos);


// Enable I2C peripheral clock.

RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;

// Set up TIMINGR (CubeMX).

I2C1->TIMINGR = 0x00501E26;

// Peripheral Enable.

I2C1->CR1 |= I2C_CR1_PE;

}


// Variable to store the data.

uint32_t buffer[5];

// Counter.

uint32_t i = 5;


int
main()

{

initSystem();


// Set up CR2 register for data writing.

I2C1->CR2 |= (I2C_CR2_NBYTES & 1); 
// 1 byte to transfer (NBYTES).

I2C1->CR2 &= ~I2C_CR2_RD_WRN; 
// Write. Set 0 in RD_WRN bit for transfer direction in master mode.

I2C1->CR2 |= 0x19 << 1; 
// Accelerometer address (without r/w bit).

I2C1->CR2 |= I2C_CR2_START; 
// Set START bit. Master sends start condition, slave address and R/W bit.

while
((I2C1->ISR & I2C_ISR_TC) == 0); 
// Wait for transfer complete.

I2C1->TXDR = 0x28; 
// Put data (inernal registry address) into TXDR.

while
((I2C1->ISR & I2C_ISR_TXIS) == 0); 
// Wait for TXDR is empty and ready for the new data.


// Set up CR2 register for data reading and set START bit.

I2C1->CR2 = I2C_CR2_AUTOEND | (I2C_CR2_NBYTES & 5) | I2C_CR2_RD_WRN | 0x19 << 1;

I2C1->CR2 |= I2C_CR2_START;

// Read the data.

while
(i-- > 0) 

{

while
((I2C1->ISR & I2C_ISR_RXNE) == 0); 
// Wait for recieve data register is ready.

buffer [i] = I2C1->RXDR; 
// Copy the data from recieve data register.

}


while
(1)

{


}

}

The program execution can't pass line The line 39 should transmit an internal register address of the accelerometer. The data remain in the TXDR. How can I check if ACK from the slave device (LSM303DLHC) is recieved? #stm32f3-discovery #accelerometer
1 REPLY 1
slimen
Senior
Posted on July 13, 2016 at 22:38

Hi,

If you are using Standard Peripherals Library, you cancompare your generated code with one of the provided I2C Standard Lib examplesunder

/content/my_st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-libraries/stsw-stm32license=1468578123html

packageand identify what you have missed.

The I2C examples areavailable in this path:

STM32F30x_DSP_StdPeriph_Lib_V1.2.3\Projects\STM32F30x_StdPeriph_Examples\I2C\

You can refer to this

/content/ccc/resource/technical/document/user_manual/d1/02/f0/b6/1a/8a/43/de/DM00068pdf/files/DM00068pdf/jcr:content/translations/en.DM00068pdf

(Description of STM32F30xx/31xx Standard Peripheral Library) in thesection 13 Inter-integrated circuit interface (I2C), it may be helpful for you.

Regards