2012-03-25 07:57 AM
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
2012-03-25 02:02 PM
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
2012-04-23 03:02 PM
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
.
2012-04-23 04:11 PM
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
2012-11-12 10:37 PM
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!!-Carolina2012-11-13 02:01 AM
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...
2012-11-13 05:25 AM
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!!2012-11-13 06:21 AM
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.
2012-11-13 07:09 AM
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.2012-11-13 07:11 AM
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