cancel
Showing results for 
Search instead for 
Did you mean: 

I2C

ezrab
Associate II
Posted on October 21, 2010 at 16:50

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.
12 REPLIES 12
spam23
Associate
Posted on April 16, 2012 at 15:03

Sorry for digging out this old stuff, but I've got a problem with a digital potentiometer. I'm using it for a variable LP Filter. So my question is, when I use the source code as in your in examples, I can send some data Bytes on the Bus and the potentiometers give me Acknowledge, but the problem is, they don't change their values. I got it working a time ago, but changed my code slightly, but can't remember why. But is it right that the data is delivered without failure to the Pots when I get ACK by them? 

Best regards...

Posted on April 16, 2012 at 18:46

I have no idea what digi-pot you're using, or the requirements it's documentation might express.

Make sure you are writing the correct register, perhaps try dumping out all the registers on this I2C device to confirm that they appear to be correct.

The ACK simply means that the transmission protocol worked, and that the I2C device received the bits being sent. ie You got the part address correct, there is a part attached to the bus at this address. It does not mean you wrote the correct register for the digi-pot output, or that you have the part correctly configured.

Review any documentation, or example code for the part. Google to see if anyone else uses the part, and perhaps how they programmed it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
danielhaensse9
Associate
Posted on May 05, 2012 at 08:11

Hi Clive

how does your code look when using remap of the i2c1 on pins pb8 and pb9 (stm32f103ze).

I placed a GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE); line

just before the port initialization which is also modified to pb8 and pb9 of course.

Both I2C lines go low as soon as GPIO_Init is called. Any idea?

When I declare the pins as inputs, the lines stay high. So I expect that something inside the STM32f103 or most probably me does wrong :)

best regards

Dani