2024-06-12 01:34 AM - edited 2024-06-12 01:35 AM
Hi everyone,
I'm currently working on an STM32 project where I want to communicate with an SMBus-compliant battery (address 0x0B) using I2C. I'm using an STM32F105 microcontroller and I'm setting up I2C on GPIO pins B6 (SCL) and B7 (SDA). I've encountered some issues and would appreciate some help.
I2C Initialization:
// Enable the I2C1 peripheral clock
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
// Configure GPIOB pins 6 (SCL) and 7 (SDA) for I2C (Alternate function open-drain)
GPIOB->CRL &= ~(GPIO_CRL_MODE6 | GPIO_CRL_CNF6 | GPIO_CRL_MODE7 | GPIO_CRL_CNF7);
GPIOB->CRL |= (GPIO_CRL_MODE6_0 | GPIO_CRL_CNF6_1 | // SCL: Open-drain output
GPIO_CRL_MODE7_0 | GPIO_CRL_CNF7_1); // SDA: Open-drain output
// Reset I2C1
I2C1->CR1 |= I2C_CR1_SWRST;
I2C1->CR1 &= ~I2C_CR1_SWRST;
// Configure I2C1 for SMBus communication
I2C1->CR1 |= I2C_CR1_SMBUS; // Enable SMBus mode
// Set own address to 0x09
I2C1->OAR1 = (0x09 << 1);
I2C1->OAR2 = (0x09 << 1) | I2C_OAR2_ENDUAL;
// Set clock frequency (50 MHz PCLK1)
I2C1->CR2 |= 50; // PCLK1 frequency in MHz
// Configure clock control register (assuming 100 kHz standard mode)
I2C1->CCR = 180; // Clock control value
// Configure rise time register
I2C1->TRISE = 51; // Max rise time in master mode
// Enable I2C1 and its interrupts
I2C1->CR1 |= I2C_CR1_PE; // Enable I2C1
I2C1->CR1 |= I2C_CR1_ACK; // Enable ACK
// Enable event and error interrupts
I2C1->CR2 |= I2C_CR2_ITEVTEN | I2C_CR2_ITERREN;
NVIC_EnableIRQ(I2C1_EV_IRQn);
NVIC_EnableIRQ(I2C1_ER_IRQn);
The STM32's errata sheet mentions a potential issue with the BUSY flag due to the analog filter providing incorrect values. But I am not sure I am running into this issue.
Nevertheless, I've attempted the workaround suggested by the errata, but the problem persists.
see 2.8.7.
Any help is appreciated
Best regards!
2024-06-12 01:50 PM
1k pull-up seems too low. Maybe the slave can't pull SDA line low?
Try using a 4.7k instead.