cancel
Showing results for 
Search instead for 
Did you mean: 

problem with stm32f4 discovery i2c slave

mohamad_armoon
Associate III
Posted on February 28, 2014 at 17:43

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

}

}

        

0 REPLIES 0