I have a problem with i2c communication(I have written my i2c library)
Hi
i2c.c------------------------------------------------------
&sharpinclude <stm32f10x.h>
&sharpinclude ''i2c.h''
void i2c_hazirla(void) //i2c_init function.
{
RCC->APB1RSTR = 0x00200000; //I2C1 reset.
RCC->APB1RSTR &=0xFFDFFFFF; //I2C1 exit at reset state.
RCC->APB1ENR |= 0x00200000; //I2C1 clock enabled.
//I2C1 PB8,PB9(SCL,SDA)
AFIO->MAPR &= 0x00000000;
AFIO->MAPR |= 0x00000002;
GPIOB->CRH &= 0x00000000;
GPIOB->CRH |= 0x000000DD; //OpenDrain,Max 10MHz
I2C1->CR2 |= 0x0008; //Freq = 8MHz
I2C1->CCR |= 0x0028;
I2C1->TRISE &= 0x0000;
I2C1->TRISE |= 0x0009; //1000ns SCL rise time (1000/Tpclk1)+1=9 , I did Pclk1 = 8MHz so Tpclk1 = 125ns
I2C1->CR1 &= 0x0000;
I2C1->CR1 |= 0x0001; //PE: Peripheral enable
I2C1->CR1 |= 0x0400; //ACK: Acknowledge enable
}
void i2c_baslat(void) //i2c_start funciton.
{
i2c_mesgul(); //wait for idle.
I2C1->CR1 |= 0x0100; //Start verildi(START BIT = 1)
while(!(I2C1->SR1 & 0x0001)); //Wait to SB bit is set.
}
void i2c_durdur(void) //i2c_stop funciton.
{
i2c_mesgul(); //wait for idle.
I2C1->CR1 |= 0x0200; //Stop
}
void i2c_restart(void)
{
i2c_mesgul();
I2C1->CR1 |= 0x8000; //software reset.
}
unsigned char i2c_adress_yaz(unsigned char adress) //I'm writing Atmel24C02 eeprom's adress here.
{
I2C1->DR = adress;
i2c_mesgul();
I2C1->OAR1 |= 0x4000; //14.bit 1 olmak zorundaym??(In datasheet says, this 14th bit must be Set.)
i2c_mesgul();
while(!(I2C1->SR1 & 0x0002)); //ADDR bit . if this bit did set so this means I already sent Device adress.
return 1;
}
unsigned char i2c_yaz(unsigned char data) //i2c_write funciton.
{
i2c_mesgul();
I2C1->DR = data;
// while(!(I2C1->SR1 & 0x0004));
return 1;
}
unsigned char i2c_oku(unsigned char wadress) //i2c_read funciton.
{
unsigned char data=0;
i2c_mesgul();
i2c_yaz(wadress);
i2c_mesgul();
data=I2C1->DR;
return (unsigned char)data;
}
void i2c_mesgul(void) //i2c_busy funciton.
{
while((I2C1->SR2 & 0x0002)); //wait for Idle.
}
------------------------------------------------------------------------
i2c.h
-----------------------------------------------------------------
extern void i2c_hazirla(void); //i2c_init funciton
extern void i2c_baslat(void); //i2c_start funciton
extern void i2c_durdur(void); //i2c_stop funciton
extern void i2c_restart(void);
extern unsigned char i2c_adress_yaz(unsigned char adress); //i2c_deviceadress_write funciton.
extern unsigned char i2c_yaz(unsigned char data); //i2c_write funciton.
extern unsigned char i2c_oku(unsigned char wadress); //i2c_read funciton.
extern void i2c_mesgul(void); //i2c_busy funciton.
----------------------------------------------------------------------------------------------------------
I'm trying to send data of my Atmel24C02 eeprom then read it.
The problem is:After I started i2c with i2c_baslat() funciton ,The BUSY(I2C_SR2 register's first bit) bit staying at 1 so I cant pass the idle state to write Atmel24c02 device adress.
I'm supplying i2c bus with +4.5V(with stm32's 5V pin) and the pull ups resistors are 4.7k
main.c
-----------------------------------------------------------------
&sharpinclude <stm32f10x.h>
&sharpinclude ''LCD.h''
&sharpinclude ''i2c.h''
void rcc_init(void);
void delay(unsigned long delay);
unsigned char x=0;
int main(void)
{
rcc_init();
GPIOC->CRL &= 0x0000000;
GPIOC->CRL |= 0x1111111; //10MHz max.
GPIOA->CRL &= 0x0000000; GPIOA->CRL |= 0x00000008; //PA0 input pulldown.
GPIOC->CRH &= 0x00000000; GPIOC->CRH |= 0x00000022; //2MHz max pushpull.
lcd_hazirla();
i2c_hazirla();
GPIOC->ODR = 0x00000300;
//LD3 and LD4 are high.
i2c_baslat();
i2c_adress_yaz(0xA0); //24C02 device adress is 0b1010000(0)-> write mode. (A0=low,A1=low,A2=low) and
i2c_yaz(0x00); //Eepromun 0x00h adresine gidiyoruz
i2c_yaz('N'); //0x00h adresine N yaz?ld?.
i2c_durdur();
i2c_baslat();
i2c_adress_yaz(0xA1);
x=i2c_oku(0x00);
i2c_durdur();
imlec(1,1);
lcd_karakter(x);
for(;;);
}
void rcc_init(void)
{
RCC->CR |= 0x00030000; //HSEON=1
while(!(RCC->CR & 0x00020000)); //Wait to HSE be stabilized
RCC->CIR |= 0x00080000; //HSERDYC: HSE ready interrupt cleared
RCC->CR |= 0x00080000; //Clock security system Enabled.
RCC->CIR |= 0x00800000; //CSSC: Clock security system interrupt cleared.
// RCC->CR |= 0x00040000; //HSE bypassed.
RCC->CFGR |= 0x06000001; //SW[1:0]=01: HSE selected as system clock , MCO[26:24] = 110: HSE clock selected
RCC->APB2ENR |= 0x0000001D; //PORT A,B,C AFIO aktif.
}
void delay(unsigned long delay)
{
while(delay--);
}
-----------------------------------------------------------------------------------
Note:I never tryed i2c communitacion before , this is my first experience :)
#i2c-afio-remap-swd