cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32f4Discovery I2C Problem

philipp239955_stm1_st
Associate II
Posted on March 25, 2012 at 16:57

Hello everyone,

I'am new to arm based processors but I have already worked with the Atmel Mega family. I am using Atollic True Studio and thedeliveredstandardlibrary. I try to read the LSM303DLH (magnetometer and accelerometer combination) via I2C. SCL/SDA areconnectedto PB6/7 at I2C1. At first I have to configure the sensor, therefor I send 2 bytes 2 times, the first byte is the register indexer of the sensor and the second one the content of the register. Then I have to send the indexer 0x03, und then I have to read 6 bytes. But the code is not working, I hope somebody can help me.

#include ''stm32f4_discovery.h''
#define ACC_ADDRESS 0x30
#define MAG_ADDRESS 0x3C
/* Private typedef -----------------------------------------------------------*/
GPIO_InitTypeDef GPIO_InitStructure, GPIO_I2C;
I2C_InitTypeDef I2C_init;
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void
Delay(__IO uint32_t nCount);
void
setup_I2C();
void
setup_LED();
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval None
*/
int
main(
void
)
{
setup_LED();
setup_I2C();
uint8_t 
out
[] = {0,0,0,0,0,0,0};
I2C1->DR = 0;
I2C_GenerateSTART(I2C1, ENABLE);
I2C_Send7bitAddress(I2C1,MAG_ADDRESS,I2C_Direction_Transmitter);
I2C_SendData(I2C1,0x02);
I2C_SendData(I2C1,0x00);
I2C_GenerateSTART(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
I2C_GenerateSTOP(I2C1, DISABLE);
I2C_GenerateSTART(I2C1, ENABLE);
I2C_Send7bitAddress(I2C1,MAG_ADDRESS,I2C_Direction_Transmitter);
I2C_SendData(I2C1,0x00);
I2C_SendData(I2C1,(1<<3)|(1<<4));
I2C_GenerateSTART(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
I2C_GenerateSTOP(I2C1, DISABLE);
I2C_GenerateSTART(I2C1, ENABLE);
I2C_Send7bitAddress(I2C1,MAG_ADDRESS,I2C_Direction_Transmitter);
I2C_SendData(I2C1,0x03);
I2C_Send7bitAddress(I2C1,MAG_ADDRESS,I2C_Direction_Receiver);
out
[0] = I2C_ReceiveData(I2C1);
out
[1] = I2C_ReceiveData(I2C1);
out
[2] = I2C_ReceiveData(I2C1);
out
[3] = I2C_ReceiveData(I2C1);
out
[4] = I2C_ReceiveData(I2C1);
out
[5] = I2C_ReceiveData(I2C1);
out
[6] = I2C_ReceiveData(I2C1);
I2C_GenerateSTART(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
I2C_GenerateSTOP(I2C1, DISABLE);
while
(1)
{
/* PD12 to be toggled */
GPIO_SetBits(GPIOD, GPIO_Pin_12);
/* Insert delay */
Delay(0x3FFFFF);
/* PD13 to be toggled */
GPIO_SetBits(GPIOD, GPIO_Pin_13);
/* Insert delay */
Delay(0x3FFFFF);
/* PD14 to be toggled */
GPIO_SetBits(GPIOD, GPIO_Pin_14);
/* Insert delay */
Delay(0x3FFFFF);
/* PD15 to be toggled */
GPIO_SetBits(GPIOD, GPIO_Pin_15);
/* Insert delay */
Delay(0x7FFFFF);
GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
/* Insert delay */
Delay(0xFFFFFF);
}
}
void
setup_I2C()
{
/* GPIO Setup */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_I2C.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_I2C.GPIO_Mode = GPIO_Mode_AF;
GPIO_I2C.GPIO_OType = GPIO_OType_PP;
GPIO_I2C.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_I2C.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_I2C);
/* I2C Setup */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_init.I2C_Mode = I2C_Mode_I2C;
I2C_init.I2C_ClockSpeed = 400000;
I2C_init.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_init.I2C_OwnAddress1 = 0;
I2C_init.I2C_Ack = I2C_Ack_Enable;
I2C_init.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1,&I2C_init);
I2C_Cmd(I2C1,ENABLE);
}
void
setup_LED()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}

Greetings Philipp #stm32f4-discovery-i2c
19 REPLIES 19
philipp239955_stm1_st
Associate II
Posted on March 25, 2012 at 23:02

Sorry myfault, I forgot the while's with the events, now I can read and write the sensor.

But when I read the sensor data, I ever get the same values. The registers I write and read are checked more than one time.

#include ''stm32f4_discovery.h''
#include <stdio.h>
#define ACC_ADDRESS 0x30
#define MAG_ADDRESS 0x3C
int
x, y, z;
/* Private typedef -----------------------------------------------------------*/
GPIO_InitTypeDef GPIO_InitStructure, GPIO_I2C;
I2C_InitTypeDef I2C_init;
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void
Delay(__IO uint32_t nCount);
void
setup_I2C();
void
setup_LED();
void
write_LSM303DLH(uint8_t adr, uint8_t * data, uint8_t lenght,
uint8_t offset);
void
read_LSM303DLH(uint8_t adr, uint8_t * data, uint8_t lenght, uint8_t index);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval None
*/
int
main(
void
) {
setup_LED();
setup_I2C();
I2C1->DR = 0;
/* Setup */
///////////////////////////////////////////////////////////////////////////////////////////
uint8_t t[] = { 0x02, 0x00 };
write_LSM303DLH(MAG_ADDRESS, t, 2, 0);
t[0] = 0x00;
t[1] = (1 << 3) | (1 << 4);
write_LSM303DLH(MAG_ADDRESS, t, 2, 0);
t[0] = 0x20;
t[1] = 0x27;
write_LSM303DLH(ACC_ADDRESS, t, 2, 0);
/* Get */
///////////////////////////////////////////////////////////////////////////////////////////
while
(1) {
/* PD12 to be toggled */
GPIO_SetBits(GPIOD, GPIO_Pin_12);
/* Insert delay */
Delay(0x3FFFFF);
uint8_t 
out
[] = { 0, 0, 0, 0, 0, 0, 0 };
read_LSM303DLH(MAG_ADDRESS, 
out
, 6, 0x03);
x = (
out
[0] << 8 | 
out
[1]);
y = (
out
[2] << 8 | 
out
[3]);
z = (
out
[4] << 8 | 
out
[5]);
/* PD13 to be toggled */
GPIO_SetBits(GPIOD, GPIO_Pin_13);
/* Insert delay */
Delay(0x3FFFFF);
read_LSM303DLH(MAG_ADDRESS, 
out
, 6, 0x03);
x = (
out
[0] << 8 | 
out
[1]);
y = (
out
[2] << 8 | 
out
[3]);
z = (
out
[4] << 8 | 
out
[5]);
/* PD14 to be toggled */
GPIO_SetBits(GPIOD, GPIO_Pin_14);
/* Insert delay */
Delay(0x3FFFFF);
read_LSM303DLH(MAG_ADDRESS, 
out
, 6, 0x03);
x = (
out
[0] << 8 | 
out
[1]);
y = (
out
[2] << 8 | 
out
[3]);
z = (
out
[4] << 8 | 
out
[5]);
/* PD15 to be toggled */
GPIO_SetBits(GPIOD, GPIO_Pin_15);
/* Insert delay */
Delay(0x7FFFFF);
read_LSM303DLH(MAG_ADDRESS, 
out
, 6, 0x03);
x = (
out
[0] << 8 | 
out
[1]);
y = (
out
[2] << 8 | 
out
[3]);
z = (
out
[4] << 8 | 
out
[5]);
GPIO_ResetBits(GPIOD,
GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
/* Insert delay */
Delay(0xFFFFFF);
read_LSM303DLH(MAG_ADDRESS, 
out
, 6, 0x03);
x = (
out
[0] << 8 | 
out
[1]);
y = (
out
[2] << 8 | 
out
[3]);
z = (
out
[4] << 8 | 
out
[5]);
}
}
void
setup_I2C() {
/* GPIO Setup */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_I2C.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_I2C.GPIO_Mode = GPIO_Mode_AF;
GPIO_I2C.GPIO_OType = GPIO_OType_OD;
GPIO_I2C.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_I2C.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_I2C);
/* I2C Setup */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_init.I2C_Mode = I2C_Mode_I2C;
I2C_init.I2C_ClockSpeed = 400000;
I2C_init.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_init.I2C_OwnAddress1 = MAG_ADDRESS;
I2C_init.I2C_Ack = I2C_Ack_Enable;
I2C_init.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Cmd(I2C1, ENABLE);
I2C_Init(I2C1, &I2C_init);
/* 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);
}
void
setup_LED() {
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14
| GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
void
write_LSM303DLH(uint8_t adr, uint8_t * data, uint8_t lenght,
uint8_t offset) {
uint8_t i = 0;
while
(i < lenght) {
while
(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) {
;
}
I2C_GenerateSTART(I2C1, ENABLE);
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {
;
}
I2C_Send7bitAddress(I2C1, adr, I2C_Direction_Transmitter);
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
;
}
I2C_SendData(I2C1, data[offset + i]);
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
;
}
I2C_SendData(I2C1, offset + i + 1);
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
;
}
I2C_GenerateSTOP(I2C1, ENABLE);
i += 2;
}
}
void
read_LSM303DLH(uint8_t adr, uint8_t * data, uint8_t lenght, uint8_t index) {
while
(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) {
;
}
I2C_GenerateSTART(I2C1, ENABLE);
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {
;
}
I2C_Send7bitAddress(I2C1, adr, I2C_Direction_Transmitter);
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
;
}
I2C_SendData(I2C1, index);
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
;
}
I2C_GenerateSTART(I2C1, ENABLE);
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {
;
}
I2C_Send7bitAddress(I2C1, adr, I2C_Direction_Receiver);
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {
;
}
for
(uint8_t i = 0; i < lenght; i++) {
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) {
;
}
data[i] = I2C_ReceiveData(I2C1);
}
I2C_GenerateSTOP(I2C1, ENABLE);
}
/**
* @brief Delay Function.
* @param nCount:specifies the Delay time length.
* @retval None
*/
void
Delay(__IO uint32_t nCount) {
while
(nCount--) {
}
}

Greetings Philipp
fe_tondo
Associate
Posted on April 24, 2012 at 00:02

My name is

felipe

tondo

and I'm

working on a

similar project and

using the

board

and the same

st

accelerometer that

you

use

this

code.

My question is about

the library ''

# include

''

stm32f4_discovery.h

''which is in

code,

is

that you

could publish

the library

for me

.

Thank you

...

hugs

.

Posted on April 24, 2012 at 01:11

My question is about

the library ''

# include

''

stm32f4_discovery.h

''which is in

code,

is

that you

could publish

the library

for me

.

 

I'm confused, Why wouldn't you just download it from the STM32F4 Discovery Page, Design Support tab.

http://www.st.com/internet/evalboard/product/252419.jsp

http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4discovery_fw.zip

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
arbona
Associate II
Posted on November 13, 2012 at 07:37

Hello Philipp,

I was just wondering if you had gotten the code to work for you. I am working on a school project and am having trouble communicating between the STM32F4 discovery board and the LSM303DLHC compass. I am trying to use I2C3, but I'm not sure that's the problem.

Any comments or tips regarding what you learned from this experience would be helpful. I am new to STM as well as to ARM microprocessors.

Thanks!!

-Carolina

frankmeyer9
Associate II
Posted on November 13, 2012 at 11:01

I suggest to download the firmware package for the STM32F3 discovery kit, which contains tested (kind of) routines for the LSM303DL, and port it to the F4 discovery.

The implementation files can be found in the

.../STM32F3-Discovery_FW_V1.1.0/Utilities/STM32F3_Discovery/...

subfolder of the package.

Any comments or tips regarding what you learned from this experience would be helpful. I am new to STM as well as to ARM microprocessors.

 

To be honest, these are not the best preconditions to get something running quickly.

The i2c bus proved to be a beast on STM32 controllers...

arbona
Associate II
Posted on November 13, 2012 at 14:25

Actually, that's exactly what I've been doing. I took the library for the F3 board and I've been trying to re-purpose it to work with the F4: I took the lsm303dlhc .c and .h files from the F3 and kept the i2c .c and .h files from the F4. I've been trying to get that to work but it's proving quite difficult. 

The i2c libraries on the F4 do not have the ''transfer handling'' function that the F3 has, and many of the flags that exist for the F3 do not exist (or I am failing to find) for the F4. I am specifically struggling with transferring the LSM303DLHC_Read and the LSM303DLHC_Write functions.

If anyone knows of any workarounds it'd be much appreciated.

Thanks!!

frankmeyer9
Associate II
Posted on November 13, 2012 at 15:21

I am trying to use I2C3, but I'm not sure that's the problem.

 

Why not using I2C_1 ?

You just need to check that the I2C address of your sensor does not clash with that of the onboard audio device, and use the audio driver low-level routines from the F4 firmware package as template.

arbona
Associate II
Posted on November 13, 2012 at 16:09

I'm not using I2C1 because it's already connected to the audio, I2C3 was the only one available that didn't already have some hardware connected to it. 

I actually started my code from a project meant for the audio block on the F4 discovery board, however it uses I2S and not I2C, so I gave up there. I am currently trying to merge a lot of code from all over the internet to get it to work but it doesn't. I'll post the code I have thus far and see if it helps.

Please note that the code is messy and has some leftover things from the audio project that I started off with.

arbona
Associate II
Posted on November 13, 2012 at 16:11

Attached is the header file for the compass library

________________

Attachments :

stm32f4_discovery_lsm303dlhc.h : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HziP&d=%2Fa%2F0X0000000bOy%2FQhs6OPpFVJ_b1_6hNqGB8tWHxfaQ_3KXzpbC82WFtZ8&asPdf=false