AnsweredAssumed Answered

problem with stm32f4 discovery i2c slave

Question asked by armoun.mohamad on Feb 28, 2014
hi guys, i want to use i2c1 in stm32f4 as master to send some data and use i2c2 as slave to receive that data and show that data in pc through usart , i don't know what is the correct configuration for master and slave i2c in stm32f4 can you help me to do this.

and the condition in WHILE is always true and loops for ever :
if(direction == I2C_Direction_Transmitter){
          while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
     }




here is my code :



#include <stm32f4xx.h>


#define SLAVE_ADDRESS 0x00 


void inti_RCC()
{
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
        /******************************************************/
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
}
void init_I2C1(void){


     GPIO_InitTypeDef GPIO_InitStruct;
     I2C_InitTypeDef I2C_InitStruct;
     /* setup SCL and SDA pins
      * You can connect I2C1 to two different
      * pairs of pins:
      * 1. SCL on PB6 and SDA on PB6 
      * 2. SCL on PB8 and SDA on PB7
      */
     GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; 
     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;               
     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;          
     GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;               
     GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;               
     GPIO_Init(GPIOB, &GPIO_InitStruct);                         


     // Connect I2C1 pins to AF  
     GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);     // SCL
     GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1); // SDA


     // configure I2C1 
     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_Enable;          // 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(I2C1, &I2C_InitStruct);                    // init I2C1
     // enable I2C1
     I2C_Cmd(I2C1, ENABLE);
}


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));
     }
}


/* This function transmits one byte to the slave device
 * Parameters:
 *          I2Cx --> the I2C peripheral e.g. I2C1 
 *          data --> the data byte to be transmitted
 */
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));
}


/* This funtion issues a stop condition and therefore
 * releases the bus
 */
void I2C_stop(I2C_TypeDef* I2Cx){
     // Send I2C1 STOP Condition 
     I2C_GenerateSTOP(I2Cx, ENABLE);
}
void init_i2c2()
{
    GPIO_InitTypeDef GPIO_InitStruct;
     I2C_InitTypeDef I2C_InitStruct;


     /* setup SCL and SDA pins
      * You can connect I2C2 to pins:
      * 1. SCL on PB10 and SDA on PB11 
      */
     GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; 
     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;               
     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;          
     GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;               
     GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;               
     GPIO_Init(GPIOB, &GPIO_InitStruct);




    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2);     // SCL
     GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2); // SDA


     // configure I2C2 
     //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_Enable;          // 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(I2C2, &I2C_InitStruct);


     I2C_Cmd(I2C2, ENABLE);
}




void init_usart(void){
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
     GPIO_InitTypeDef GPIO_InitStructure;
     USART_InitTypeDef USART_InitStructure;
      
     
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
     GPIO_Init(GPIOA, &GPIO_InitStructure);


     
     GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);


     USART_InitStructure.USART_BaudRate = 9600;
     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
     USART_InitStructure.USART_StopBits = USART_StopBits_1;
     USART_InitStructure.USART_Parity = USART_Parity_No;
     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
     USART_InitStructure.USART_Mode = USART_Mode_Tx;
     USART_Init(USART2, &USART_InitStructure);


     USART_Cmd(USART2, ENABLE); 


}
int main(void)
{
        inti_RCC();
     init_I2C1(); // initialize I2C peripheral
        init_usart();
     uint8_t received_data[2];


     while(1)
        {


          I2C_start(I2C1, SLAVE_ADDRESS<<1, I2C_Direction_Transmitter); 
          I2C_write(I2C1, 0x20); 
          I2C_write(I2C1, 0x03); 
          I2C_stop(I2C1);
          
          
          received_data[0] = I2C_read_ack(I2C2); 
          received_data[1] = I2C_read_nack(I2C2); 
        USART_SendData(USART2,'a');
     }
}








        



Outcomes