AnsweredAssumed Answered

I2C doesn't send data and...

Question asked by fairchild.brian on Sep 26, 2014
Latest reply on Oct 1, 2014 by fairchild.brian
Hi everybody
I want to connect my two MCU together over I2C. one STM32F103ZE (as master) and one STM32F103RE (as slave).
The master program:

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <string.h>
 
/* Private macro -------------------------------------------------------------*/
#define SYSCLK_FREQ_72MHz
#define RxBufferSize   0x20
 
/* Private variables ---------------------------------------------------------*/
 
char RxBuffer[RxBufferSize];
uint8_t NbrOfDataToRead = RxBufferSize;
uint16_t RxCounter = 0;
char aTxBuffer[0x20] = "Rohalamin";
uint8_t S=0;
 
/* Private functions ---------------------------------------------------------*/
 
RCC_ClocksTypeDef RCC_ClockFreq;
ErrorStatus HSEStartUpStatus;
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
 
void SetSysClockTo72(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void _I2C1(void);
void EXTI_Configuration(void);
 
/*******************************************************************************
* Function Name  : main
* Description    : Main Programme
* Input          : None
* Output         : None
* Return         : None
* Attention      : None
*******************************************************************************/
 
 
int main(void)
{
    GPIO_Configuration();
    EXTI_Configuration();
    _I2C1();
    NVIC_Configuration();
     
     
    I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE);
  I2C_ITConfig(I2C2, I2C_IT_ERR, ENABLE);
  I2C_ITConfig(I2C2, I2C_IT_BUF, ENABLE);
     
 
    /* Infinite loop */
    while (1)
        {
            if(S==1){
                 
                while (I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)) {}
         
                I2C_GenerateSTART(I2C1, ENABLE);
                     
                while (I2C_GetFlagStatus(I2C1,I2C_FLAG_SB) == RESET){} 
 
                // ersale adrese marbot be PCF8583
                /* Transmit the slave address and enable writing operation */
                I2C_Send7bitAddress(I2C1, 0x12, I2C_Direction_Transmitter);
                 
                while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){}
 
                // ersale adrese registere
                I2C_SendData(I2C1,0xA1);
                while ((!I2C_GetFlagStatus(I2C1,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(I2C1,I2C_FLAG_BTF))){}
         
                //while (I2C_GetFlagStatus(I2C2,I2C_FLAG_BTF)){}
                I2C_GenerateSTOP(I2C1, ENABLE);
            }
        }
}
 
 
/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configure GPIO Pin
* Input          : None
* Output         : None
* Return         : None
* Attention      : None
*******************************************************************************/
 
void GPIO_Configuration(void)
{
   
    RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOB , ENABLE );
    RCC_APB2PeriphClockCmd ( RCC_APB2Periph_AFIO , ENABLE );
/**
 *  LED1 -> PB0
 */                 
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
  GPIO_Init( GPIOB , &GPIO_InitStructure );
     
    /* PB2-> Input */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
     
    /**
 *  SCL -> PB6
        SDA -> PB7
         
 */
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOB , &GPIO_InitStructure );
     
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOB , &GPIO_InitStructure );
     
}
 
void EXTI_Configuration(void)
{
     
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
     
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource2);
  EXTI_ClearITPendingBit(EXTI_Line2);
     
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_Line = EXTI_Line2;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
     
}
 
/* I2C1 init function */
void _I2C1(void)
{  
     
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1 , ENABLE );
     
    I2C_DeInit(I2C1);
     
    I2C_InitStructure.I2C_ClockSpeed          = 100000;
    I2C_InitStructure.I2C_Mode                = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle           = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1         = 0x10;
    I2C_InitStructure.I2C_Ack                 = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
     
    I2C_Init( I2C1 , &I2C_InitStructure );
    I2C_Cmd( I2C1 , ENABLE );
     
}
 
 
void NVIC_Configuration(void)
{
  /* Enable and configure I2C1 Event Interrupt channel */
  NVIC_InitStructure.NVIC_IRQChannel                   = I2C1_EV_IRQn;  
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;  
  NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
     
    NVIC_InitStructure.NVIC_IRQChannel                   = I2C1_ER_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
     
    /* Enable and configure RCC global IRQ channel */
  NVIC_InitStructure.NVIC_IRQChannel                   = RCC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0; 
  NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
     
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;    
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;     
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
     
}
 
/******************************************************************************/
/*            STM32F10x Peripherals Interrupt Handlers                        */
/******************************************************************************/
 
/**
  * @brief  This function handles I2C1 global interrupt request.
  * @param  None
  * @retval None
  */
void I2C1_EV_IRQHandler(void)
{
    if (I2C_GetITStatus(I2C1, I2C_IT_RXNE))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_RXNE);
         
  }
     
    if (I2C_GetITStatus(I2C1, I2C_IT_SMBALERT))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_SMBALERT);
     
  }
  /* Check on I2C1 Time out flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_TIMEOUT))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_TIMEOUT);
  }
  /* Check on I2C1 Arbitration Lost flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_ARLO))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_ARLO);
  }
 
  /* Check on I2C1 PEC error flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_PECERR))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_PECERR);
  }
  /* Check on I2C1 Overrun/Underrun error flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_OVR))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_OVR);
  }
  /* Check on I2C1 Acknowledge failure error flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_AF))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
  }
  /* Check on I2C1 Bus error flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_BERR))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_BERR);
  }
     
   
}
 
void I2C1_ER_IRQHandler(void)
{
     
         
 
}
 
void EXTI2_IRQHandler(void)
{
    if ( EXTI_GetITStatus(EXTI_Line2) != RESET ) {
        EXTI_ClearITPendingBit(EXTI_Line2);
      GPIOB->ODR ^= GPIO_Pin_0;
        S=1;
    }
     
}

The Slave program:

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <string.h>
 
/* Private macro -------------------------------------------------------------*/
#define SYSCLK_FREQ_72MHz
 
/* Private variables ---------------------------------------------------------*/
 
uint8_t RxBuffer;
uint8_t aTxBuffer = 0xA1;
 
/* Private functions ---------------------------------------------------------*/
 
RCC_ClocksTypeDef RCC_ClockFreq;
ErrorStatus HSEStartUpStatus;
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
 
void SetSysClockTo72(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void _I2C1(void);
 
/*******************************************************************************
* Function Name  : main
* Description    : Main Programme
* Input          : None
* Output         : None
* Return         : None
* Attention      : None
*******************************************************************************/
 
 
int main(void)
{
    GPIO_Configuration();
    _I2C1();
    NVIC_Configuration();
     
     
    I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
  I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
  I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);
     
         
    /* Infinite loop */
    while (1)
        {
            if( RxBuffer == aTxBuffer )
            {
                GPIOB->ODR ^= GPIO_Pin_0;
                RxBuffer = 0x00;
                 
            }                              
        }
}
 
 
/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configure GPIO Pin
* Input          : None
* Output         : None
* Return         : None
* Attention      : None
*******************************************************************************/
 
void GPIO_Configuration(void)
{
   
    RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOB , ENABLE );
    RCC_APB2PeriphClockCmd ( RCC_APB2Periph_AFIO , ENABLE );
/**
 *  LED1 -> PB0
 */                 
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
  GPIO_Init( GPIOB , &GPIO_InitStructure );
     
    /**
 *  SCL -> PB6
        SDA -> PB7
         
 */
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOB , &GPIO_InitStructure );
     
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOB , &GPIO_InitStructure );
     
}
 
/* I2C1 init function */
void _I2C1(void)
{  
     
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1 , ENABLE );
     
    I2C_DeInit(I2C1);
     
    I2C_InitStructure.I2C_ClockSpeed          = 100000;
    I2C_InitStructure.I2C_Mode                = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle           = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1         = 0x12;
    I2C_InitStructure.I2C_Ack                 = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
     
    I2C_Init( I2C1 , &I2C_InitStructure );
    I2C_Cmd( I2C1 , ENABLE );
     
}
 
 
void NVIC_Configuration(void)
{
  /* Enable and configure I2C1 Event Interrupt channel */
  NVIC_InitStructure.NVIC_IRQChannel                   = I2C1_EV_IRQn;  
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;  
  NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
     
    NVIC_InitStructure.NVIC_IRQChannel                   = I2C1_ER_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
     
    /* Enable and configure RCC global IRQ channel */
  NVIC_InitStructure.NVIC_IRQChannel                   = RCC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0; 
  NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
     
}
 
/******************************************************************************/
/*            STM32F10x Peripherals Interrupt Handlers                        */
/******************************************************************************/
 
/**
  * @brief  This function handles I2C1 global interrupt request.
  * @param  None
  * @retval None
  */
void I2C1_EV_IRQHandler(void)
{
    if (I2C_GetITStatus(I2C1, I2C_IT_RXNE))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_RXNE);
         
        RxBuffer = I2C_ReceiveData(I2C1);
         
        /* Disable the I2C1 Receive interrupt */
    I2C_ITConfig(I2C1, I2C_IT_BUF , DISABLE);
     
     
  }
     
    if (I2C_GetITStatus(I2C1, I2C_IT_SMBALERT))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_SMBALERT);
     
  }
  /* Check on I2C1 Time out flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_TIMEOUT))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_TIMEOUT);
  }
  /* Check on I2C1 Arbitration Lost flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_ARLO))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_ARLO);
  }
 
  /* Check on I2C1 PEC error flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_PECERR))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_PECERR);
  }
  /* Check on I2C1 Overrun/Underrun error flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_OVR))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_OVR);
  }
  /* Check on I2C1 Acknowledge failure error flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_AF))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
  }
  /* Check on I2C1 Bus error flag and clear it */
  if (I2C_GetITStatus(I2C1, I2C_IT_BERR))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_BERR);
  }
     
   
}
 
void I2C1_ER_IRQHandler(void)
{
     
         
 
}


One button is connected to the master that when I would push it, the master should send "Ro" string. all things that I can see (when I push the button) via my logic analyzer is this:

http://www.imageupload.co.uk/images/2014/09/26/1WFLPz.jpg

I checked the master in the debugger. when the master reached to this line:

while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){}

it was halted. I'm newbie to work with I2C. What's the problem? Why isn't there an acknowledge at the end of the address?

Outcomes