2014-08-29 03:21 AM
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 I2Cvoid 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
2014-08-29 04:40 AM
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?2014-08-29 05:03 AM
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 resistorThe 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
2014-09-01 03:18 AM
Hello
I was reviewing the circuit and i eliminate the 100R resistor. I don't know because this don't work. After execute this codevoid 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
2014-09-01 03:38 AM
Hello
I was reviewing the circuit and i eliminate the 100R resistor. I don't know because this don't work. After execute this codevoid 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
2014-09-01 09:38 AM
Hello
I find a error in my code.There are a mistake in this lineRCC_APB2PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); The correct line must beRCC_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?RegardsRegards2014-09-02 09:35 AM
Hello
Problem repared. 1º be careful with the oscillator config. 2º the code is wrong. Here Is the correct codevoid 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