STM32 i²c Slave
i²c Slave configurationI²c works by default in the slave mode
The input clock frequency needs to be set in the I2C_CR2 register.
Initialization code I2C2
/ * GPIO and IIC initialization structure * /
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
/ * GPIO and IIC clock enable * /
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); // GPIOB clock enable
RCC_APB1PeriphClockCmd (RCC_APB1Periph_I2C2, ENABLE); // IIC2 clock enable
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; // Initialize GPIO.B10 (IIC2_SCL), GPIO.B11 (IIC2_SDA)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Maximum output speed 50Hz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // The input / output mode is an open-drain output with alternate functions
GPIO_Init (GPIOB, & GPIO_InitStructure); // initialize GPIOB according to GPIO initialization structure
I2C_DeInit (I2C2); // Reset I2C
/ * Initialize IIC2 * /
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; // Set to IIC mode
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; // Set the duty cycle of IIC, the low level divided by the high level value is 2
I2C_InitStructure.I2C_OwnAddress1 = addr; // Specify the address of the first device as a 7-bit address The slave device address is the function parameter addr
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; // Enable ACK signal
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // Specify a 7-bit address
I2C_InitStructure.I2C_ClockSpeed = 100000; // The clock frequency must be less than or equal to 400KHz
I2C_Init (I2C2, & I2C_InitStructure);
I2C2-> CR2 & = 0xff00; ** // Set the I2C input clock frequency to 4Mhz ** according to the clock tree configuration
I2C2-> CR2 | = 0x04;
I2C_Cmd (I2C2, ENABLE); // Enable hardware IIC2
I2C_ITConfig (I2C2, I2C_IT_EVT | I2C_IT_BUF, ENABLE);
Address matching:
1. ACK 1 generates answer
2. Addr set-up, Itevfen interrupt is generated
Data Sending
Tra bit indicates if i²c is in send or receive mode, and Tra = 1 is sent
from Send:
1. After the receiving address clears the addr bit, sends the data from the transmitter to the SDA
2. When the addr bit is not cleared or the pending data is not written to the Dr Register, the SCL is pulled down by
3. When an ACK is received, the TXE is placed, resulting in interrupts (enable Itevfen and Itbuffen).
If Txe is set, but no new data is written to I2C_DR,BTF before the end of the next data send, the read SR1 write DR can clear the BTF bit from receiving:
1. After the receive address clears the addr bit, the data from the receiver is collected from SDA to the Dr Register.
2. The I²c interface will do the following when each byte receipt is received:
3. If the ACK position bit, the answer 4 is generated
. Rxne set, Interrupt
5. If the Rxne is set, the DR Data has not been read out, the BTF is set, and the BTF bit is not cleared, the SCL is pulled
6. Read SR1 Write Dr to clear the BTF bit
End Communication:
The main device produces a stop condition, and after the slave detects the stop condition, the stopf=1, resulting in an interrupt.
I²c waiting to read SR1 write CR1
Interrupt handler function
void I2C2_EV_IRQHandler(void)
{
uint8_t temp;
gwTimeout=0;
if(I2C_GetFlagStatus(I2C2,I2C_FLAG_BERR)){//
I2C_ClearFlag(I2C2,I2C_FLAG_BERR);
}
if(I2C_GetFlagStatus(I2C2,I2C_FLAG_ADDR)){
if(I2C_GetFlagStatus(I2C2,I2C_FLAG_TRA)){
I2C_SendData(I2C2,arryBuffer_Tx[gwOffset++]);
}
else{
gwOffset= I2C_ReceiveData(I2C2);
}
}
if(I2C_GetFlagStatus(I2C2,I2C_FLAG_RXNE)){
arryBuffer_Rx[gwOffset]= I2C_ReceiveData(I2C2);
}
if(I2C_GetFlagStatus(I2C2,I2C_FLAG_TXE))
{
I2C_SendData(I2C2,arryBuffer_Tx[gwOffset]);
gwOffset++;
}
if(I2C_GetFlagStatus(I2C2,I2C_FLAG_STOPF))
{
addr=0;
I2C2->CR1|= 0x0001;//清除I2C_FLAG_STOPF
}
}