Question
STM 32 F4 Discovery I2C Hanging Up
Posted on November 21, 2013 at 15:51
Hi, I am having a problem with using the I2C on the STM 32 F4 discovery to read 3 DevanTech SRF-08 ultrasonic sensors, There was a previous post on this matter, but it was unresolved as far as I know, clive1 did indiacte that the problem was in addressing, 10 bit vs 7 bit but I dont know how to make it work never the less, please can you help me.
I am pasting the Initialisation code for the I2C and the fucntions I am using the try and read the ultrasonics. (I am working in the free version of Atollic True Studio)// Setup the IIC3 peripheral for the UltraSonic Sensorsvoid init_I2C3(void){ GPIO_InitTypeDef GPIO_InitStruct; I2C_InitTypeDef I2C_InitStruct; // enable APB1 peripheral clock for I2C3 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE); // enable clock for SCL and SDA pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); /* setup SCL and SDA pins * 1. SCL on PA8 and SDA on PC9 */ // Configure the SCL pin GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8; // SCL is on PA8 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // set pins to alternate function GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // set GPIO speed GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; // set output to open drain --> the line has to be only pulled low, not driven high GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // enable pull up resistors GPIO_Init(GPIOA, &GPIO_InitStruct); // initialize GPIOA // Configure the SDA pin GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; // SDA is on PC9 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // set pins to alternate function GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // set GPIO speed GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; // set output to open drain --> the line has to be only pulled low, not driven high GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // enable pull up resistors GPIO_Init(GPIOC, &GPIO_InitStruct); // init GPIOC // Connect I2C3 pins to AF GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_I2C3); // SCL GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_I2C3); // SDA // configure I2C3 I2C_InitStruct.I2C_ClockSpeed = 100000; // 100kHz I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; // I2C mode I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 50% duty cycle --> standard I2C_InitStruct.I2C_OwnAddress1 = 0x00; // own address, not relevant in master mode I2C_InitStruct.I2C_Ack = I2C_Ack_Disable; // disable acknowledge when reading (can be changed later on) I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses I2C_Init(I2C3, &I2C_InitStruct); // init I2C1 // enable I2C3 I2C_Cmd(I2C3, ENABLE);}/* Function to Start I2C communications with specific device */void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction){ // wait until I2C1 is not busy anymore while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); // Send I2C1 START condition I2C_GenerateSTART(I2Cx, ENABLE); // wait for I2C1 EV5 --> Slave has acknowledged start condition while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); // Send slave Address for write I2C_Send7bitAddress(I2Cx, address, direction); /* wait for I2C1 EV6, check if * either Slave has acknowledged Master transmitter or * Master receiver mode, depending on the transmission * direction */ if(direction == I2C_Direction_Transmitter){ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); } else if(direction == I2C_Direction_Receiver){ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); }}/* Function to write one byte to the I2C device */void I2C_write(I2C_TypeDef* I2Cx, uint8_t data){ I2C_SendData(I2Cx, data); // wait for I2C1 EV8_2 --> byte has been transmitted while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));}/* Function to read the first byte from the I2C device */uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){ // enable acknowledge of recieved data I2C_AcknowledgeConfig(I2Cx, ENABLE); // wait until one byte has been received while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) ); // read data from I2C data register and return data byte uint8_t data = I2C_ReceiveData(I2Cx); return data;}/* Function to read a single byte from the I2C device */uint8_t I2C_read_nack(I2C_TypeDef* I2Cx){ // disabe acknowledge of received data // nack also generates stop condition after last byte received // see reference manual for more info I2C_AcknowledgeConfig(I2Cx, DISABLE); I2C_GenerateSTOP(I2Cx, ENABLE); // wait until one byte has been received while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) ); // read data from I2C data register and return data byte uint8_t data = I2C_ReceiveData(I2Cx); return data;}/* Function to stop communication with the I2C device */void I2C_stop(I2C_TypeDef* I2Cx){ // Send I2C1 STOP Condition I2C_GenerateSTOP(I2Cx, ENABLE);}/* Read all three light sensors and distance sensors and save to relevant state variables */void Read_Ldr_Us(){// For the left sensor. int HighByte=111; int LowByte=333; I2C_start(I2C3, USleftAddr>>1, I2C_Direction_Transmitter); I2C_write(I2C3,0x01); I2C_start(I2C3, USleftAddr>>1, I2C_Direction_Receiver); stLDRleft=I2C_read_ack(I2C3); HighByte=I2C_read_ack(I2C3); LowByte=I2C_read_nack(I2C3); stUSleft= ((unsigned int)HighByte << + LowByte); I2C_stop(I2C3);// For the front sensor. I2C_start(I2C3, USfrontAddr>>1, I2C_Direction_Transmitter); I2C_write(I2C3,0x01); I2C_start(I2C3, USfrontAddr>>1, I2C_Direction_Receiver); stLDRfront=I2C_read_ack(I2C3); HighByte=I2C_read_ack(I2C3); LowByte=I2C_read_nack(I2C3); stUSfront= ((unsigned int)HighByte << + LowByte); I2C_stop(I2C3);// For the right sensor. I2C_start(I2C3, USrightAddr>>1, I2C_Direction_Transmitter); I2C_write(I2C3,0x01); I2C_start(I2C3, USrightAddr>>1, I2C_Direction_Receiver); stLDRright=I2C_read_ack(I2C3); HighByte=I2C_read_ack(I2C3); LowByte=I2C_read_nack(I2C3); stUSright= ((unsigned int)HighByte << + LowByte); I2C_stop(I2C3);}Please can you have a look at this and tell me what is wrong, I am tearing my hair out! Please comment if I need to add any more information. #stm32 #stm32f4 #i2c #discovery #clive1 #clive1 #ieeprom