2014-02-28 08:43 AM
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'); }}