1
\$\begingroup\$

I use I2C communication with two stm8s boards.

My master code:

I2C_GenerateSTART(ENABLE);
I2C_Send7bitAddress(0x30, I2C_DIRECTION_TX);
I2C_SendData(0x61);
I2C_GenerateSTOP(ENABLE);
delay(1500);

My slave address is 0x30. I send 0x61. I analyzed stm8s master board with ossiloscope. I see from lister:

Address:30R

Data: anything

Missing ACK: X(with red background)

My signal from master board with stm8s: [![enter image description here][1]][1]

what could be the problem for missing ack? And, is it true address and data values? Thank you!

And,

My master arduino code:

Wire.beginTransmission(0x30); // transmit to device 0x30
Wire.write(0x61);              // sends one byte
Wire.endTransmission();    // stop transmitting
delay(500);

And this picture from master arduino code with ossiloscope: enter image description here

Here, adress is 30W, but adress of my stm8s master code is 30R. I changed this line of the stm8s master code:

I2C_Send7bitAddress(0x30, I2C_DIRECTION_RX); 
//I2C_Send7bitAddress(0x30, I2C_DIRECTION_TX);

But adress is still 30R.

code of this line:

/**
  * @brief  Transmits the 7-bit address (to select the) slave device.
  * @param   Address : Specifies the slave address which will be transmitted.
  * @param   Direction : Specifies whether the I2C device will be a Transmitter or a Receiver.
  * This parameter can be any of the @ref I2C_Direction_TypeDef enumeration.
  * @retval None
  */
void I2C_Send7bitAddress(uint8_t Address, I2C_Direction_TypeDef Direction)
{
  /* Check function parameters */
  assert_param(IS_I2C_ADDRESS_OK(Address));
  assert_param(IS_I2C_DIRECTION_OK(Direction));

  /* Clear bit0 (direction) just in case */
  Address &= (uint8_t)0xFE;

  /* Send the Address + Direction */
  I2C->DR = (uint8_t)(Address | (uint8_t)Direction);
}

and

/**
  * @brief  I2C transfer direction
  * Warning: the values correspond to the ADD0 bit position in the OARL register
  */
typedef enum
{
  I2C_DIRECTION_TX = (uint8_t)0x00,  /*!< Transmission direction */
  I2C_DIRECTION_RX = (uint8_t)0x01   /*!< Reception direction */
} I2C_Direction_TypeDef;

/**************************NOW*******************************************/ I changed my stm8s I2C master code:

I2C_GenerateSTART(ENABLE);
I2C_Send7bitAddress(0x30, I2C_DIRECTION_TX);
I2C_SendData(0x60); //I have no idea, i tried it and works for write/read selection
I2C_SendData(0x61); //my send data
I2C_GenerateSTOP(ENABLE);
delay_delay(1500);

Adress is 30W, now. It is true because i want to write to slave. Then, I saw this signal from ossiloscope:

enter image description here

This signal is same with Arduino master transmitter.

But, I can't see signal of the data. What could be the reason for this? Missing ACK or another thing? I don't know, but data signal is no of the arduino signal. Missing ACK?

Thank you!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Your slave is supposed to be sending the ACK back to your master. Have you enabled that in your slave code? \$\endgroup\$
    – brhans
    Feb 15, 2016 at 22:26
  • 1
    \$\begingroup\$ We'd need to see your slave code to know more. Your master code says I2C_DIRECTION_TX but the bus shows a read, not a write. The eighth bit of the transfer should be a 0 for TX. Also, I'm not sure you need to send a stop condition after an address NACK. \$\endgroup\$
    – Adam Haun
    Feb 15, 2016 at 22:33
  • \$\begingroup\$ I edited my post for your comment. @AdamHaun \$\endgroup\$
    – kbtr
    Feb 15, 2016 at 22:45

1 Answer 1

1
\$\begingroup\$

There are two standard formats for 7-bit I2C addresses -- 0x7F and 0xFE. It looks like I2C_Send7bitAddress() expects 0xFE format. If your actual slave address is 0x30, try sending 0x60 (which is 0x30 << 1) and see if that works.

The reason for the 0xFE format is that it lets you treat the read/write direction bit as part of the slave address, giving an 8-bit value. That's what you actually see on the bus.

\$\endgroup\$
4
  • \$\begingroup\$ Ok, i tried with online c compiler, but 0xC0 << 1 is: goo.gl/XfbymG \$\endgroup\$
    – kbtr
    Feb 15, 2016 at 23:03
  • \$\begingroup\$ Oops! It's not 0xC0, it's 0x60. You left-shift the address (0x30) by one to convert to 0xFE form, which gives you 0x60. \$\endgroup\$
    – Adam Haun
    Feb 15, 2016 at 23:19
  • \$\begingroup\$ Hello @AdamHaun, I can change write/read selection. Address(0x30) and data direction(write) are true, now. But, I can't see signal of the data. What could be the reason for this? Missing ACK or another thing? I don't know, but data signal is no of the arduino signal. Missing ACK? Thank you! \$\endgroup\$
    – kbtr
    Feb 16, 2016 at 18:33
  • \$\begingroup\$ It's almost certainly the missing ACK. The problem is probably on the slave side. \$\endgroup\$
    – Adam Haun
    Feb 16, 2016 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.