I'm using stm32f103c8 and PCA9685 devices. I'm trying to send data to PCA9685 via I2C bus. I send data using I2C_DR register. But when i write a data to I2C_DR register it sticks to it. After the data is send thee I2C_DR register should be cleared but it wont happen in my code. I have no idea why this is happening. This is what i see in logic analyzer.
#include "stm32f10x.h" void I2C_Write_Single(int device_address, int mem_address, int data); void I2C_Restart(int device_address, int data); uint32_t temp = 0; int main(){ /*********STEPS FOLLOWED********* 1. Enable the I2C Clock and GPIO Clock 2. Configure I2C Pins for alternate funtion 3. Reset I2C 4. Program the peripherald input clock in I2C_CR2 Register in order to generate correct timing 5. configure the clock control register 6. Configure the rise time register 7. Program the I2C_CR1 register to enable the peripheral */ I2C1->CR1 |= (1<<15); I2C1->CR1 &=~ (1<<15); //GPIO Port B neabled RCC->APB2ENR |= (1<<3); //I2C enabled RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; //timer enable TIM2 (general timer) RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; //TIM2 config TIM4->PSC |= 0; TIM4->ARR |= 71; TIM4->CR1 |= TIM_CR1_URS; TIM4->DIER |= TIM_DIER_UIE; TIM4->EGR |= TIM_EGR_UG; NVIC_EnableIRQ(TIM4_IRQn); //Mode register set for 50MHz (B7 and B6) GPIOB->CRL |= (1<<25) | (1<<24); GPIOB->CRL |= (1<<29) | (1<<28); //GPIO B7 and B6 pin registers (alternate function open drain) GPIOB->CRL |= (1<<27) | (1<<26); GPIOB->CRL |= GPIO_CRL_CNF7_1 | (1<<30); //Peripherald frequency (APB1) 36MHz (its written in datasheet) I2C1->CR2 |= 36 ; //I2C clock control register /* to calculate CCR (Clock Control Register) CCR= [((I2C_Period)/2)/(APB1_Period)] I2C preiod is 400KHz(from user manual page 781) Ti2c= 1/100K = 10us APB1 Period = 1/36 = 27.7 ns CCR = [(5000ns)/(27.7ns)]= 180 */ I2C1->CCR |= 180; I2C1->TRISE |= 37 ; // TRise = CR2+1 (from datasheet page 783) I2C1->CR1 |= I2C_CR1_ACK; I2C1->CR1 |= I2C_CR1_PE; I2C_Restart(0x00, 0x06); I2C_Write_Single( 0x80, 0x00, 0x08); //SLEEP bit gets cleared so we can get PWM signal I2C_Write_Single( 0x40, 0x00, 1<<6); //EXTERNAL CLOCK bit gets cleared so we can get PWM signal I2C_Write_Single( 0x40, 0xFE, 0XB0); // PRE_SCALE registers set to 0xB0 that way PWM Frequency will be 50 MHz (PCA9685 Datasheet page 9) // PWM delay %0 so LED0_ON_L and LED0_ON_H registers set to 0 I2C_Write_Single( 0x40, 0x06, 0X01); I2C_Write_Single( 0x40, 0x07, 0X99); // 1.5ms PWM will be given (1,5/20)*4096=307 LED0_OFF_H= 3 (decimal) LED0_OFF_H= 07 (decimal) I2C_Write_Single( 0x41, 0x09, 0X08); I2C_Write_Single( 0x41, 0x08, 0X00); return 0; } void I2C_Write_Single(int device_address, int mem_address, int data) { I2C1->CR1 |= I2C_CR1_START; //generate start condition while (!(I2C1->SR1 & I2C_SR1_SB)); // we check the SB flag if start bit didnt sent master device will stay in this loop I2C1->DR |= device_address ; // device adrees is 0x00 while (!(I2C1->SR1 & I2C_SR1_ADDR)); // we check ADDR flag. Once there is address mach dvice will exit the loop temp = I2C1->SR1 | I2C1->SR2; // we need to cleear ADDR bit after we checked the flags. To reset SR1 and SR2 registers we just read them while (!(I2C1->SR1 & I2C_SR1_TXE)); // wait for the byte transfer I2C1->DR |= mem_address ; // MODE1 register (PCA9685 datasheet page 9) while (!(I2C1->SR1 & I2C_SR1_BTF));//wait for transmit while (!(I2C1->SR1 & I2C_SR1_TXE)); // wait for the byte transfer I2C1->DR |= data << 1 ; // to set PWM frequeency we set SLEEP bit 1 (PCA9685 datasheet page 24) while (!(I2C1->SR1 & I2C_SR1_BTF));//wait for transmit I2C1->CR1 |= I2C_CR1_STOP; //generate stop condition } void I2C_Restart(int device_address, int data){ I2C1->CR1 |= I2C_CR1_START; //generate start condition while (!(I2C1->SR1 & I2C_SR1_SB)); // we check the SB flag if start bit didnt sent master device will stay in this loop I2C1->DR |= device_address; // device adrees is 0x00 while (!(I2C1->SR1 & I2C_SR1_ADDR)); // we check ADDR flag. Once there is address mach dvice will exit the loop temp = I2C1->SR1 | I2C1->SR2; // we need to cleear ADDR bit after we checked the flags. To reset SR1 and SR2 registers we just read them while (!(I2C1->SR1 & I2C_SR1_TXE)); // wait for the byte transfer I2C1->DR |= data; // MODE1 register (PCA9685 datasheet page 9) while (!(I2C1->SR1 & I2C_SR1_BTF));//wait for transmit while (!(I2C1->SR1 & I2C_SR1_TXE)); // wait for the byte transfer I2C1->CR1 |= I2C_CR1_STOP; //generate stop condition }
the solution is not using I2C1->DR |=... instead it should be I2C1-> Dr =