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-11-13 07:12 AM
2012-11-13 07:13 AM
2012-11-13 07:14 AM
2012-11-13 07:22 AM
2012-11-13 07:32 AM
I'm not using I2C1 because it's already connected to the audio, ...
And so what ? I2C is an addressed bus, you can have up to 112 devices on the bus, as long as the addresses do not clash. SPI, for example, is not. It has introduced SS (slave select) signals late to overcome this.
2012-11-13 08:51 AM
That is true... do you think that's the problem though?? It really does seem like I'm initializing I2C3 correctly, I think the problem is more in the read and write functions.
2012-11-13 11:08 AM
That is true... do you think that's the problem though?? It really does seem like I'm initializing I2C3 correctly, I think the problem is more in the read and write functions.
Having some experience with I2C, that's the very reason why I avoided I2C on STM32 up to now. Other ARM controllers have simpler and more comprehensible I2C units, and are less bug-ridden (at least compared to the F10x devices). You will need detailed knowledge of the I2C protocol and of the slave device specification, and you need a scope to verify the actual events on the bus. Maybe your school has a scope with i2c decoder sw package, i.e. it can show you the transfered addresses and data in real-time...
2012-11-13 11:22 AM
I already switched back to i2c1, but it isn't working either. It's getting stuck waiting for the busy_flag to clear (at the very beginning of the write function). It doesn't even start anything. I have an oscilloscope but it's hard to see the waveforms because it goes by too fast for me to stop it.
2012-11-13 11:53 PM
I have an oscilloscope but it's hard to see the waveforms because it goes by too fast for me to stop it.
Dealing with a scope is another important thing you might need in your carreer. Doesn't your one have single-shot capability ?I already switched back to i2c1, but it isn't working either. It's getting stuck waiting for the busy_flag to clear (at the very beginning of the write function). It doesn't even start anything.One common mistake is to assume a wrong address. Standard i2c addresses are 7 bit, the LSB differs between read and write access. So actually every device has two addresse. The specs are sometimes confusing, because they specify it left-shifted or not. Another issue (seen on several threads here), is that slaves might startup in an undefined or unknown state, and block the bus by holding SDA down. A common circumvention is to reconfigure the i2c pins to GPIO, and pulse SCL until the slave releases the bus. And of cource, check that the address of the sensor doesn't collide with that of the onboard audio device.
2013-12-02 04:00 AM