cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to setup I2C communication between 2 x STM32F103 blue pill boards.

mrjay
Visitor

Hello,

I am unable to setup I2C communication between 2 x STM32F103 blue pill boards. I have pasted code and the hardware setup below. Would appreciate help trying to pinpoint the problem. 

Hardware setup:

  • Both boards are connected to an adapter via an ST-LINK V2 with SWCLK, SWDIO, GND, and 3.3V connections.
  • SCL pins are connected together (B6 -> B6) and SDA pins are connected together (B7 -> B7)
  • The SCL and SDA pins of the Master STM32 are connected to 3.3V via 4.7kΩ resistors. 
  • The GND of Master and Slave are connected together 
  • I have probed all the pins and they are at the correct levels so I doubt hardware is the problem (see image attached)

Software setup:

  • One thing worth mentioning is that trying to debug the projects through the IDE results in the following message: "Target no device found... Error in initializing ST-LINK device. Reason: No device found on target."
  • Therefore I have been running the project on STM32CubeProgrammer using the bin file that gets generated after running the file on the IDE. Also, the only way to connect to the STM is by holding the reset button on the STM, pressing connect, then letting go of the reset button. I wonder if this Temu way of connecting to the STM has anything to do with my shortcomings.

I2C Configuration:

  • The GPIO settings for both SDA and SCL have "No pull-up and no pull-down" indicated, the maximum output speed is "Low"
  • The clock speed is 100kHz
  • The slave has "I2C1 event interrupt" and "I2C error interrupt" enabled but the master does not. 

Run Procedure:

  • 1. Flash to master 
  • 2. Take out Master ST-LINK, Flash to slave 
  • 3. Plug back in the Master ST-Link so they both flash together
  • Currently the PC13 LED for Master is off so it is sending the data but the PC13 LED for the slave is stuck at 50ms blink speed so I don't think it is seeing the sent 

Firmware setup:

Master:

  • Sends a bit stream of all 1's (0xFF) or all 0's to the slave (0x00)
  • Turns on an LED if there is an error or NACK: 
 
int main(void)
{
 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_I2C1_Init();
 while (1)
 {
  HAL_StatusTypeDef status;
  //send address byte, wait for acknowledge from slave, send 1 data byte
  status = HAL_I2C_Master_Transmit(&hi2c1, slave_addr, &fast_cmd, 1, 200);

  //checks if there is a NACK, bus error, etc and turns led ON
  if (status != HAL_OK) {
   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
  } else {
   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
  }
  HAL_Delay(5000); // Wait 5 seconds

  //send address byte, wait for acknowledge from slave, send 1 data byte
  status = HAL_I2C_Master_Transmit(&hi2c1, slave_addr, &slow_cmd, 1, 200);

  //checks if there is a NACK, bus error, etc and turns led ON
  if (status != HAL_OK) {
   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
  } else {
   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
  }
  HAL_Delay(5000); // Wait 5 seconds

  /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */

 

Slave: 

  • Listening to the I2C in main using: HAL_I2C_EnableListen_IT(&hi2c1);
  • changing the blink speed according to the data sent (1's/0's)
 
I2C_HandleTypeDef hi2c1;
uint8_t rx_buffer = 0; // Buffer to receive I2C data
volatile uint32_t blink_speed = 50; // Initial blink speed (ms)

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);

int main(void)
{
 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_I2C1_Init();

 /* Enable I2C slave listening */
 HAL_I2C_EnableListen_IT(&hi2c1);

 while (1)
 {
  HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
  HAL_Delay(blink_speed);
 }
}

void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
 if (hi2c->Instance == I2C1 &&
   TransferDirection == I2C_DIRECTION_TRANSMIT)
 {
  HAL_I2C_Slave_Receive_IT(hi2c, &rx_buffer, 1);
 }
}

void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
 if (rx_buffer == 0xFF)
 {
  blink_speed = 100;
 }
 else if (rx_buffer == 0x00)
 {
  blink_speed = 1000;
 }
 HAL_I2C_EnableListen_IT(hi2c);
}

void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
{
  HAL_I2C_EnableListen_IT(hi2c);
}

 


Edited to apply source code formatting - please see How to insert source code for future reference.

2 REPLIES 2
AScha.3
Super User

Hi,

> IDE results in the following message: "Target no device found...

This happens , if there is not a STM cpu , but some cpu by GD or CKS or other.

Probably you use the st-link V2 "sticks" , = clones of st-link .

>Also, the only way to connect to the STM is by holding the reset button

Set connect to "software reset" , as V2 sticks have no working hard reset.

So dont expect this mix of unknown cpu's working "fine" , or much help here from STM for your cpu mix from other manufacturers.

Maybe try on the forum or help they provide...Knowledge of Chinese could be helpful.

Or look at comments of the product, before buying ; is there any "dont work with STM..IDE " or "is not genuine STM" ?

Then dont buy, look for another with good comment "works with STM..IDE " , maybe this will be ok.

Or buy some boards with genuine STM chips, like cheap nucleo boards. ymmv.

If you feel a post has answered your question, please click "Accept as Solution".
Andrew Neil
Super User

Note that Blue Pill is not an ST product, and likely contains a clone/fake STM32.

As @AScha.3 says, this is most likely why STM32CubeIDE refuses to connect.

 

Regarding the ST-Link, see also: How to recognize a genuine ST-LINK/V2 versus a cloned one;

In particular, this comment.

 

You could save yourself a load of grief by using genuine ST NUCLEO-F103RB boards;  then you could take advantage of the ready-to-go examples - which include connecting 2 boards via I2C!

 

As to your I2C experiment, you are making the common mistake of trying to do both ends at once.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.