AnsweredAssumed Answered

I2C

Question asked by be_senyor.ezra on Oct 21, 2010
Latest reply on May 5, 2012 by haensse.daniel
hi

i am tring to activate the I2C in order to External EEPROM i used this code but nothing is in the output on PB why?

#include "stm32F10x.h"

#define IWDG_WriteAccess_Enable     ((uint16_t)0x5555)
#define IWDG_Prescaler_32           ((uint8_t)0x03)
#define KR_KEY_Reload    ((uint16_t)0xAAAA)
#define KR_KEY_Enable    ((uint16_t)0xCCCC)
/* I2C F/S mask */
#define CCR_FS_Set              ((uint16_t)0x8000)
#define I2C_AcknowledgedAddress_7bit    ((uint16_t)0x4000)
#define I2C_SLAVE_ADDRESS7     0xA0
/* I2C FLAG mask */
#define FLAG_Mask               ((uint32_t)0x00FFFFFF)
#define I2C_FLAG_BUSY                   ((uint32_t)0x00020000)
#define  I2C_EVENT_MASTER_MODE_SELECT                      ((uint32_t)0x00030001)  /* BUSY, MSL and SB flag */
#define  I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED        ((uint32_t)0x00070082)  /* BUSY, MSL, ADDR, TXE and TRA flags */

void setsystemclock(void);


FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);

uint16_t Address=0,PageStatus0=0;
int main(void)
{
  char byte_temp=0;

  setsystemclock(); //set system clock to 24Mhz


  RCC->APB2ENR |=  RCC_APB2RSTR_AFIORST |  RCC_APB2RSTR_IOPBRST |RCC_APB2RSTR_IOPARST  ;//activate i2c ,port C ,port A, portB, clock and alternative clock enable. page 79

  //GPIO configuration
  GPIOB->CRL=0XBB000000;
      GPIOA->CRL=0x333333;
   GPIOA->CRH=0x333333;


//I2C Configuration
  I2C1->CR1=I2C_CR1_PE  ;/*!<Peripheral Enable */
  I2C1->CR2 = 24;// 24mhz/1000000 work on 2Mhz
  I2C1->CR1 &= ~I2C_CR1_PE;  /* Disable the selected I2C peripheral to configure TRISE */
  I2C1->TRISE =8;//24*300/1000 +1
  I2C1->CCR =40|CCR_FS_Set;
  I2C1->CR1=I2C_CR1_PE  ;/*!<Peripheral Enable */
 // I2C1->CR1|=I2C_CR1_ACK; /*!<Acknowledge Enable */
  I2C1->OAR1 =I2C_AcknowledgedAddress_7bit | I2C_SLAVE_ADDRESS7; /* Set I2Cx Own Address1 and acknowledged address */



  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
   {
   }

  I2C1->CR1 |=I2C_CR1_START ;



   I2C1->DR =0;//address
   I2C1->DR =0x5;//data



GPIOA->ODR=0;
  while(1)
  {
    I2C1->DR =0x5;
    GPIOA->ODR^=0xff;

   }
}

void setsystemclock(void)
{
  RCC->CR |= RCC_CR_HSEON;
  // Wait until it's ready
  while ((RCC->CR & RCC_CR_HSERDY) == 0)
        ;

  // Select PREDIV1 as PLL source and sett PLL mul to 3 (set bit 0)
  // for 8*3 = 24 MHz
  RCC->CFGR |= RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL_0;

  // Start PLL
  RCC->CR |= RCC_CR_PLLON;

  // Wait until it's ready
  while ((RCC->CR & RCC_CR_PLLRDY) == 0)
        ;

  // Select PLL as system clock
  RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL;

  // Wait until PLL is used as system clock source
  while ((RCC->CFGR & RCC_CFGR_SWS) != 0x08)
        ;

  // Here we can check if PLL is used, and maybe disable HSI

  // Disable HSI
  RCC->CR &= ~RCC_CR_HSION;

  RCC->CFGR|=RCC_CFGR_MCO_2; //sys clock output
}

FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
{
  FlagStatus bitstatus = RESET;
  __IO uint32_t i2creg = 0, i2cxbase = 0;




  /* Get the I2Cx peripheral base address */
  i2cxbase = (uint32_t)I2Cx;

  /* Read flag register index */
  i2creg = I2C_FLAG >> 28;

  /* Get bit[23:0] of the flag */
  I2C_FLAG &= FLAG_Mask;

  if(i2creg != 0)
  {
    /* Get the I2Cx SR1 register address */
    i2cxbase += 0x14;
  }
  else
  {
    /* Flag in I2Cx SR2 Register */
    I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);
    /* Get the I2Cx SR2 register address */
    i2cxbase += 0x18;
  }

  if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET)
  {
    /* I2C_FLAG is set */
    bitstatus = SET;
  }
  else
  {
    /* I2C_FLAG is reset */
    bitstatus = RESET;
  }

  /* Return the I2C_FLAG status */
  return  bitstatus;
}

ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{
  uint32_t lastevent = 0;
  uint32_t flag1 = 0, flag2 = 0;
  ErrorStatus status = ERROR;



  /* Read the I2Cx status register */
  flag1 = I2Cx->SR1;
  flag2 = I2Cx->SR2;
  flag2 = flag2 << 16;

  /* Get the last event value from I2C status register */
  lastevent = (flag1 | flag2) & FLAG_Mask;

  /* Check whether the last event contains the I2C_EVENT */
  if ((lastevent & I2C_EVENT) == I2C_EVENT)
  {
    /* SUCCESS: last event is equal to I2C_EVENT */
    status = SUCCESS;
  }
  else
  {
    /* ERROR: last event is different from I2C_EVENT */
    status = ERROR;
  }
  /* Return status */
  return status;
}

thanks. 

Outcomes