AnsweredAssumed Answered

I2C basic EEPROM communications

Question asked by cawthorne.darren on Aug 17, 2011
Latest reply on Oct 17, 2013 by matthies.jonatha.001
Hi,

I have been trying now for longer than i care to admit at getting my development board ( STM32F103R ) to talk to a sensor ( HMC5843 ) via I2C. I have gone through the STM32 code examples but they were frankly kind of useless.

I have put in the following code which i pasted together from pages of this forum and what little understanding of this peripheral i have.:

##########START CODE############

#include "stm32f10x.h"
#include "Libs.h"

u16 loop1 = 0,loop2 = 0,loop3 = 0, Loop_Delay = 0; //loops for 1ms interrupts

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define I2C1_SLAVE_ADDRESS7     0x1E   // EEPROM I2C Address
#define ClockSpeed              50000 // 50 KHz
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u8 i2c_var = 123;
/* Private function prototypes -----------------------------------------------*/
void Delay(u16);
void I2C_Setup(void);
void Transmit (void);
void Recieve(void);

int main(void)
{


     Setup ();
     //ADCconfig();
     //PWMinit();
     USART_Setup();
     I2C_Setup();




  while(1)
  {

       if (loop1>=100)
            {
            Transmit();
            SendData(1,i2c_var);
            loop1=0;
            GPIOB->BSRR |= GPIO_Pin_8 | GPIO_Pin_9 ; // switch of LED's
            Recieve();
            }
  }


}//end main

void Transmit (void)
{

      /* Send I2C1 START condition */
       I2C_GenerateSTART(I2C1, ENABLE);

       /* Test on I2C1 EV5 and clear it */
//       while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

       /* Send EEPROM slave Address for write */
       I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7, I2C_Direction_Transmitter);

       /* Test on I2C1 EV6 and clear it */
//       while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

       /* Send I2C1 EEPROM internal address */
       I2C_SendData(I2C1, 0x02); // 0x02 is config register

       /* Test on I2C1 EV8 and clear it */
//       while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

       /* Send I2C1 EEPROM data */
       I2C_SendData(I2C1, 0x00);//puts config register into continious measurement mode.

       /* Test on I2C1 EV8 and clear it */
//       while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

       /* Send I2C1 STOP Condition */
       I2C_GenerateSTOP(I2C1, ENABLE);
}



void I2C_Setup(void)
{


       GPIO_InitTypeDef GPIO_InitStructure;
       I2C_InitTypeDef  I2C_InitStructure;

       /* GPIOB Periph clock enable */
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

       /* I2C1 and I2C2 Periph clock enable */
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

       /* Configure I2C1 pins: SCL and SDA ----------------------------------------*/
       GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // Open Drain, I2C bus pulled high externally
       GPIO_Init(GPIOB, &GPIO_InitStructure);

       /* Enable I2C1 -------------------------------------------------------------*/
       I2C_Cmd(I2C1, ENABLE);

       /* I2C1 configuration ------------------------------------------------------*/
       I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
       I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
       I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
       I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
       I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
       I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
       I2C_Init(I2C1, &I2C_InitStructure);

}

void Recieve(void)
{
      /* Send I2C1 START condition */
       I2C_GenerateSTART(I2C1, ENABLE);

       /* Test on I2C1 EV5 and clear it */
       while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

       /* Send EEPROM slave Address for write */
       I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7, I2C_Direction_Receiver);


       i2c_var =  I2C_ReceiveData(I2C1);//puts config register into continious measurement mode.


       /* Send I2C1 STOP Condition */
       I2C_GenerateSTOP(I2C1, ENABLE);


}

//Increment function called by Systick every 1ms
inline void Increment (void)
{
loop1++;
loop2++;
loop3++;
Loop_Delay++;
}

void Delay(u16 count)
{
Loop_Delay=0;
  while (Loop_Delay <= count)
  {
       asm("nop");
  }

}//end Delay


#########END CODE##########

The Libs.h file just contains some setup functions for setting up the USART and GPIOS. i made sure i called the I2C setup after my setups just incase it was setting some ports incorrectly.

All i am trying to do is read data from the sensors registers , any of them! 

if i uncomment the while check events then it hangs on all of them. if i comment them all out and then run the code it just returns "31" to serial , which is the number i am putting into the DR register in the first place. so im figuring that whatever im putting into the register is just sitting there and not being sent anywhere.

any help in pointing out my stupidity would be appreciated :/

Thanks in advance.

Outcomes