Question
Problem with data transfer between 2 MCUs via I2C
Hello, dear collegues!
Please help me with I2C!
I use I2C to transfer data between 2 controllers: STM32F051C8T6(Master) and STM32F100C8T6 (Slave). When I use laboratory power supply, it works without some problems. But when I use external power supply based on the pulse transformer, it does not work. Program stops in some infinitie loop and waits for some flag.
Please, help with this problem!
My code is bellow!
//for transmiting
uint16_t Load_FROM_Single (uint8_t word_number)
{
uint8_t msb;
uint8_t lsb;
uint16_t retval;
I2C_10BitAddressingModeCmd(I2C1,DISABLE);
I2C_SlaveAddressConfig(I2C1,25);
I2C1->CR2&= ~I2C_CR2_RD_WRN;
I2C_NumberOfBytesConfig(I2C1,1);
I2C_AutoEndCmd(I2C1,DISABLE);
I2C_GenerateSTART(I2C1,ENABLE);
int timeout=0;
while((!I2C_GetFlagStatus(I2C1,I2C_FLAG_TXIS))&&( timeout!=1000))
{
timeout++;
}
if (timeout==1000) {
I2C_DeInit(I2C1);
Simple_Delay(100);
I2C1_Init();
Simple_Delay(100);
return 0;
}
timeout=0;
I2C_SendData(I2C1,word_number);
while((!I2C_GetFlagStatus(I2C1,I2C_FLAG_TC))&&( timeout!=1000)) //Передача закончена - вы�?тавил�?�? бит TC в реги�?тре ISR
{
timeout++;
}
if (timeout==1000) {
I2C_DeInit(I2C1);
Simple_Delay(100);
I2C1_Init();
Simple_Delay(100);
return 0;
}
timeout=0;
I2C_GenerateSTOP(I2C1,ENABLE);
I2C_GenerateSTOP(I2C1,DISABLE);
I2C_ClearFlag(I2C1,I2C_FLAG_STOPF);
I2C1->CR2|=I2C_CR2_RD_WRN;
I2C_NumberOfBytesConfig(I2C1,2);
I2C_AcknowledgeConfig(I2C1,ENABLE);
I2C_GenerateSTART(I2C1,ENABLE);
while((!I2C_GetFlagStatus(I2C1,I2C_FLAG_RXNE))&&( timeout!=1000))
{
timeout++;
}
if (timeout==1000) {
I2C_DeInit(I2C1);
Simple_Delay(100);
I2C1_Init();
Simple_Delay(100);
return 0;
}
timeout=0;
lsb=I2C1->RXDR;
I2C_AcknowledgeConfig(I2C1,DISABLE);
while((!I2C_GetFlagStatus(I2C1,I2C_FLAG_RXNE))&&( timeout!=1000))
{
timeout++;
}
if (timeout==1000) {
I2C_DeInit(I2C1);
Simple_Delay(100);
I2C1_Init();
Simple_Delay(100);
return 0;
}
timeout=0;
msb=I2C1->RXDR;
while((!I2C_GetFlagStatus(I2C1,I2C_FLAG_TC))&&( timeout!=1000))
{
timeout++;
}
if (timeout==1000) {
I2C_DeInit(I2C1);
Simple_Delay(100);
I2C1_Init();
Simple_Delay(100);
return 0;
}
timeout=0;
I2C_GenerateSTOP(I2C1,ENABLE);
I2C_GenerateSTOP(I2C1,DISABLE);
I2C_ClearFlag(I2C1,I2C_FLAG_STOPF);
retval=(msb<<8)+lsb;
return retval+1;
}
//for recieving
int Load_TO (uint16_t Pxxx_val, uint8_t Pxxx_numb)
{
int k=0;
uint8_t msb;
uint8_t lsb;
uint8_t c=0;
I2C_10BitAddressingModeCmd(I2C1,DISABLE);
I2C_SlaveAddressConfig(I2C1,25);
I2C1->CR2&= ~I2C_CR2_RD_WRN;
I2C_NumberOfBytesConfig(I2C1,3);
I2C_AutoEndCmd(I2C1,DISABLE);
I2C_GenerateSTART(I2C1,ENABLE);
int timeout=0;
while((!I2C_GetFlagStatus(I2C1,I2C_FLAG_TXIS))&&( timeout!=1000))
{
timeout++;
}
if (timeout==1000) {
I2C_DeInit(I2C1);
Simple_Delay(100);
I2C1_Init();
Simple_Delay(100);
return 0;
}
timeout=0;
I2C_SendData(I2C1,Pxxx_numb);
while((!I2C_GetFlagStatus(I2C1,I2C_FLAG_TXIS))&&( timeout!=1000))
{
timeout++;
}
if (timeout==1000) {
I2C_DeInit(I2C1);
Simple_Delay(100);
I2C1_Init();
Simple_Delay(100);
return 0;
}
timeout=0;
lsb=(uint8_t)(Pxxx_val);
I2C_SendData(I2C1,lsb);
while((!I2C_GetFlagStatus(I2C1,I2C_FLAG_TXIS))&&( timeout!=1000))
{
timeout++;
}
if (timeout==1000) {
I2C_DeInit(I2C1);
Simple_Delay(100);
I2C1_Init();
Simple_Delay(100);
return 0;
}
timeout=0;
msb=(uint8_t)((Pxxx_val>>8));
I2C_SendData(I2C1,msb);
while((!I2C_GetFlagStatus(I2C1,I2C_FLAG_TC))&&( timeout!=1000))
{
timeout++;
}
if (timeout==1000) {
I2C_DeInit(I2C1);
Simple_Delay(100);
I2C1_Init();
Simple_Delay(100);
return 0;
}
timeout=0;
I2C_GenerateSTOP(I2C1,ENABLE);
I2C_GenerateSTOP(I2C1,DISABLE);
I2C_ClearFlag(I2C1,I2C_FLAG_STOPF);
return 1;
}
//On STM32F100C8T6 I use interupts
void I2C1_EV_IRQHandler(void) //Обработчик прерываний от I2C1 -
//
{
if(I2C1->SR1&I2C_SR1_ADDR)
{
I2C1->SR1;
I2C1->SR2;
b=1;
}
if(I2C1->SR1&I2C_SR1_RXNE)
{
switch(c)
{
case 0:
{
a=I2C_ReceiveData(I2C1);
c++;
break;
}
case 1:
{
lsb=I2C_ReceiveData(I2C1);
c++;
break;
}
case 2:
{
msb=I2C_ReceiveData(I2C1);
i[a]=(msb<<8)+lsb;
c=0;
a=0;
msb=0;
lsb=0;
break;
}
}
}
if((I2C1->SR1&I2C_SR1_TXE)&&(b==1))
{
switch (c)
{
case 0:
{
lsb=(uint8_t)((i[a]));
I2C_SendData(I2C1,lsb);
c++;
break;
}
case 1:
{
msb=(uint8_t)((i[a]>>8));
I2C_SendData(I2C1,msb);
c=0;
a=a+1;
break;
}
}
}
if((I2C1->SR1&I2C_SR1_AF))
{
I2C1->CR1=I2C1->CR1;
I2C1->SR1&= ~I2C_SR1_AF;
c=0;//Сбра�?ываем �?четчик
a=0;
}
if(I2C1->SR1&I2C_SR1_STOPF)
{
//i[2*n-1]=I2C_ReceiveData(I2C1);//Сохранили по�?ледний прин�?тый байт
I2C1->CR1=I2C1->CR1;
I2C1->SR1&= ~I2C_SR1_AF;//Сбро�? флага
c=0;
}
if(a==n)
{
a=0;
b=0;
}
}.