cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo-F103RB and L3G4200D.

lemac
Associate II
Posted on August 29, 2014 at 12:21

Hello

I have a Nucleo-F103RB board and a EVK of L3G4200D. I am try connect this via I2C I have this code for config I2C

void Inicializacion_uC(void)
{
RCC_Configuration_IO();
Inicializacion_GPIO();
Inicializacion_GPIO_UART1();
Inicializacion_GPIO_UART2();
Inicializacion_GPIO_UART3();
Inicializacion_GPIO_I2C1();
Configuration_Interrupcion_NVIC_UART1();
Configuration_Interrupcion_NVIC_UART2();
Configuration_Interrupcion_NVIC_UART3();
Inicializacion_UART1();
Inicializacion_UART2();
Inicializacion_UART3();
Inicializacion_I2C1();
}
void RCC_Configuration_IO(void)
{
/* --------------------------- System Clocks Configuration -----------------*/
/* Enable DMA clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 
/* USART clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
/* I2C clock enable */
RCC_APB2PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); 
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // creo que sobra
/* GPIOA clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 
}
void Inicializacion_GPIO_I2C1(void)
{ 
GPIO_InitTypeDef GPIO_InitStruct;
#ifdef REGION /* I2C1 GPIO Configuration 
PB5 --> I2C1_SMBA (IN)
PB6 --> I2C1_SCL (OUT)
PB7 --> I2C1_SDA (IN/OUT) 
*/
/*Configure GPIO pin : PB */
/*
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; 
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
//GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStruct);
*/
/*Configure GPIO pin : PB */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; 
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; 
GPIO_Init(GPIOB, &GPIO_InitStruct);
#endif 
}
void Inicializacion_I2C1(void)
{ 
I2C_InitTypeDef I2C_InitStructure;
/* I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //I2C_Mode_SMBusHost;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2CxSpeed;
I2C_Init(I2C1, &I2C_InitStructure); 
I2C_Cmd(I2C1, ENABLE); 
}

I have this code for config

void InicializaSensores(void)
{
/* Gyroscope initialization */
L3GInit L3GInitStructure;
L3GInitStructure.xPowerMode = L3G_NORMAL_SLEEP_MODE;
L3GInitStructure.xOutputDataRate = L3G_ODR_95_HZ_CUTOFF_12_5;
L3GInitStructure.xEnabledAxes = L3G_ALL_AXES_EN;
L3GInitStructure.xFullScale = L3G_FS_500_DPS;
L3GInitStructure.xDataUpdate = L3G_BLOCK_UPDATE;
L3GInitStructure.xEndianness = L3G_BIG_ENDIAN;
ConfigL3gx(&L3GInitStructure);
}
void ConfigL3gx(L3GInit *pxL3GInitStruct)
{
uint8_t CTRL1 = 0x00, CTRL4 = 0x00;
CTRL1 |= ((uint8_t)pxL3GInitStruct->xPowerMode | (uint8_t)pxL3GInitStruct->xOutputDataRate | (uint8_t)pxL3GInitStruct->xEnabledAxes);
CTRL4 |= ((uint8_t)pxL3GInitStruct->xFullScale | (uint8_t)pxL3GInitStruct->xDataUpdate | (uint8_t)pxL3GInitStruct->xEndianness);
//I2CWriteString(I2C1 , uint8_t cAddr, uint8_t* pcBuffer , uint8_t cWriteAddr , uint8_t cNumByteToWrite) 
I2CWriteString(I2C1 ,Add_Gyr, &CTRL1, L3G_CTRL_REG1 , 1);
I2CWriteString(I2C1 ,Add_Gyr, &CTRL4, L3G_CTRL_REG4 , 1);
}
void I2CWriteString(I2C_TypeDef* I2Cx, uint8_t I2C_Addr, uint8_t* Data, uint8_t WriteAddr, uint8_t NumByteToWrite)
{ 
#ifdef FORCE_CRITICAL_SEC
__disable_irq();
#endif
I2C_GenerateSTART(I2Cx, ENABLE); // Enviamos condicion de Inicion / Envia START condition 
// Esperamos a que el Bus este libre 
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter); // Enviamos direcion para escrivir 
// Comoprobamos si es Maestro esta en modo Tx / check master is now in Tx mode
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2Cx, WriteAddr); // Enviamos direcion del registro a escrivir / Send the register address to write 
// Esperamos a recivir ACK 
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
// enviamos los datos
for(uint8_t i=0 ; i < NumByteToWrite ; i++)
{
// Enviamos los dato
I2C_SendData(I2Cx, Data[i]);
//Esperamos el ACK
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
// Eviamos Stop al sistema 
I2C_GenerateSTOP(I2Cx, ENABLE);
/*stop bit flag*/
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));
#ifdef FORCE_CRITICAL_SEC
__enable_irq();
#endif
}

I have this code for configure the device I don't know because this don't work. The code stop in while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I have a oscilloscope and i measure the SCL and SDA line and this is always to 0V Someone can help me? Regards #nucleo #f103rb #nucleo-f103rb #i2c #i2c
6 REPLIES 6
Posted on August 29, 2014 at 13:40

I have a oscilloscope and i measure the SCL  and SDA line and this is always to  0V

Do you have pull-up resistors on the pins?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lemac
Associate II
Posted on August 29, 2014 at 14:03

Do you have pull-up resistors on the pins?

Yes I put 2 external pull ups 4K7 and 2 resistor in serie of 100 R.

First the series resistor

The pull up are connected to the L3G4200D

o +3.3V

|

_

      | |

      | | 4K7

      | |

_

|

|

|

________ |

    uC ----------| 100R | ----|----------------- Device

------------

When I press the reset, the line go to 3.3V and some time after unpress go to 0V

lemac
Associate II
Posted on September 01, 2014 at 12:18

Hello

I was reviewing the circuit and i eliminate the 100R resistor. I don't know because this don't work. After execute this code

void Inicializacion_I2C1(void)
{
I2C_InitTypeDef I2C_InitStructure;
/* I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //I2C_Mode_SMBusHost;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2CxSpeed;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}

must the SCL start to oscillate? How can I prove that i2C bus work? Regards
lemac
Associate II
Posted on September 01, 2014 at 12:38

Hello

I was reviewing the circuit and i eliminate the 100R resistor. I don't know because this don't work. After execute this code

void Inicializacion_GPIO_I2C1(void)
{ 
GPIO_InitTypeDef GPIO_InitStruct;
#ifdef REGION /* I2C1 GPIO Configuration 
PB5 --> I2C1_SMBA (IN)
PB6 --> I2C1_SCL (OUT)
PB7 --> I2C1_SDA (IN/OUT) 
*/
/*Configure GPIO pin : PB */
/*
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; 
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
//GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStruct);
*/
/*Configure GPIO pin : PB */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; 
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; 
GPIO_Init(GPIOB, &GPIO_InitStruct);
#endif 
}

The lines put a 0V. And never come back to change. I don't understand because in idle mode i2C must have the lines to up level??

void Inicializacion_I2C1(void)
{
I2C_InitTypeDef I2C_InitStructure;
/* I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //I2C_Mode_SMBusHost;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2CxSpeed;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}

must the SCL start to oscillate? How can I prove that i2C bus work? Regards
lemac
Associate II
Posted on September 01, 2014 at 18:38

Hello

I find a error in my code.

There are a mistake in this line

RCC_APB2PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); 

The correct line must be

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

But making more probes the problem is that the code stop in 

while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));

Someone help me?

Regards

Regards
lemac
Associate II
Posted on September 02, 2014 at 18:35

Hello

Problem repared. 1º be careful with the oscillator config. 2º the code is wrong. Here Is the correct code

void Inicializacion_uC(void)
{ 
RCC_Configuration_IO();
Inicializacion_GPIO();
Inicializacion_GPIO_I2C1();
Inicializacion_I2C1();
}
void RCC_Configuration_IO(void)
{
/* --------------------------- System Clocks Configuration -----------------*/ 
/* GPIOA y GPIOB clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 
/* USART clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); 
/* I2C clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* Enable the DMA1 clock */
//RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 
}
void Inicializacion_GPIO(void)
{ 
#ifdef REGION /* IO 
PC13 ------> (IN)
PA5 ------> (OUT)
*/
RCC_ClocksTypeDef RCC_Clocks; 
// SysTick end of count event each 1ms 
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
// Initialize LED2 
STM_EVAL_LEDInit(LED2);
// Initialize User_Button on STM32NUCLEO 
STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI); 
/* 
//Enable or disable APB2 peripheral clock 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE);
//Configure GPIO pin : PC 
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStruct);
//Configure GPIO pin : PA 
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
*/
#endif 
}
void Inicializacion_GPIO_I2C1(void)
{ 
GPIO_InitTypeDef GPIO_InitStruct;
#ifdef REGION /* I2C1 GPIO Configuration 
PB5 --> I2C1_SMBA (IN)
PB6 --> I2C1_SCL (OUT)
PB7 --> I2C1_SDA (IN/OUT) 
*/
/*Configure GPIO pin : PB */
/*
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; 
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
//GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStruct);
*/
/*Configure GPIO pin : PB */ 
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; 
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; 
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 
GPIO_Init(GPIOB, &GPIO_InitStruct); 
#endif 
}
void Inicializacion_I2C1(void)
{ 
I2C_InitTypeDef I2C_InitStructure;
/* I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //I2C_Mode_SMBusHost;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 40000;
I2C_Init(I2C1, &I2C_InitStructure); 
I2C_Cmd(I2C1, ENABLE); 
}
/**
* @brief Writes a block of data to the device by polling.
* @brief I2Cx: I2C peripherial to use.
* @param I2C_Addr : slave address.
* @param Data : pointer to the buffer containing the data to be written.
* @param WriteAddr : register internal address to write to.
* @param NumByteToWrite : number of bytes to write.
* @retval None
*/
void I2CWriteString(I2C_TypeDef* I2Cx, uint8_t I2C_Addr, uint8_t* Data, uint8_t WriteAddr, uint8_t NumByteToWrite)
{ 
/* Set to 1 the MSb of the register address in case of multiple byte writing */
// if(cNumByteToWrite>1)
// cWriteAddr |= 0x80;
#ifdef FORCE_CRITICAL_SEC
__disable_irq();
#endif
/* While the bus is busy */
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
/* Send START condition */
I2C_GenerateSTART(I2Cx, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
/* Send LSM303DLH address for write */
I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* Send the LSM303DLHC_internal register address to write */
I2C_SendData(I2Cx, WriteAddr);
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
for(uint8_t i=0 ; i<
NumByteToWrite
; i++)
{
/* Send the byte to be written */
I2C_SendData(I2Cx, Data[i]);
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
/* Send STOP condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
#ifdef FORCE_CRITICAL_SEC
__enable_irq();
#endif
}
/**
* @brief Reads a block of data from the device by polling.
* @brief I2Cx: I2C peripherial to use.
* @param I2C_Addr: slave address.
* @param Data: pointer to the buffer that receives the data read.
* @param ReadAddr: register internal address to read from.
* @param NumByteToRead: number of bytes to read.
* @retval None
*/
void I2CReadString(I2C_TypeDef* I2Cx, uint8_t I2C_Addr, uint8_t* Data, uint8_t ReadAddr, uint8_t NumByteToRead)
{
/* Set the MSb of the register address in case of multiple readings */
// if(NumByteToRead>1)
// ReadAddr |= 0x80;
#ifdef FORCE_CRITICAL_SEC
__disable_irq();
#endif
/* Esperamos a que el Bus este libre / While the bus is busy */
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2Cx, ENABLE); /* Enviamos condicion de Inicion / Envia START condition */
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
/* Send LSM303DLH address for write */
I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* Clear EV6 by setting again the PE bit */
I2C_Cmd(I2Cx, ENABLE);
/* Send the LSM303DLH_Magn's internal address to write to */
I2C_SendData(I2Cx, ReadAddr);
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Send START condition a second time */
I2C_GenerateSTART(I2Cx, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
/* Send LSM303DLH address for read */
I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* While there is data to be read */
while(NumByteToRead)
{
if(NumByteToRead == 1)
{
/* Disable Acknowledgement */
I2C_AcknowledgeConfig(I2Cx, DISABLE);
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
}
/* Test on EV7 and clear it */
if(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))
{
/* Read a byte from the LSM303DLH */
*Data = I2C_ReceiveData(I2Cx);
/* Point to the next location where the byte read will be saved */
Data++;
/* Decrement the read bytes counter */
NumByteToRead--;
}
}
/* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(I2Cx, ENABLE);
#ifdef FORCE_CRITICAL_SEC
__enable_irq();
#endif
}
/******************************************************************************/

Regards