0
\$\begingroup\$

I am trying to establish a SMBus connection by using STM32 chip. When I try to transmit data to battery (0x0D) I see 0x0B with oscilloscope. When I change the data that is being transmitted to 0x00 or to 0xFF nothing changes. The data I see in oscilloscope is 0x0B. The slave address is 0x16. Interestingly I can communicate with battery. But it is unreliable. The related part of the code section is:

I2C_HandleTypeDef hi2c1;
I2C_HandleTypeDef hi2c2; 
//! variable which holds the state of charge of Battery 1
int socBattery1;
//! variable which holds the state of charge of Battery 2
int socBattery2;
#define BATTERY_SMBUS_SLAVE_ADDRESS (0x16)

#define SMBBUS_GET_RELATIVE_SOC_COMMAND (0xFF)

int getBatterySOC(I2C_HandleTypeDef *batteryI2CHardwareHandle){
    memset (smbusData,0x00,16);
    smbusData[0] = SMBBUS_GET_RELATIVE_SOC_COMMAND;
    if (HAL_OK != HAL_I2C_Master_Transmit(batteryI2CHardwareHandle,(uint8_t)BATTERY_SMBUS_SLAVE_ADDRESS,smbusData,2,1000)){
        memset (statusString,0x00,255);
        statusStringLength = sprintf(statusString,"I2C Transmit FAIL \r\n");
        CDC_Transmit_FS(statusString,statusStringLength);
        return -1;

    }

    if (HAL_OK != HAL_I2C_Master_Receive(batteryI2CHardwareHandle,(uint8_t)BATTERY_SMBUS_SLAVE_ADDRESS + 1 , smbusData,1,1000)){
        memset (statusString,0x00,255);
        statusStringLength = sprintf(statusString,"I2C Read FAIL \r\n");
        CDC_Transmit_FS(statusString,statusStringLength);
        return -1;

    }

    return smbusData[0];}

void StartDefaultTask(void const * argument)
{
  /* init code for USB_DEVICE */
  MX_USB_DEVICE_Init();

  /* USER CODE BEGIN 5 */
  int dischargeSOCLevel;
    socBattery1 = -1;
    socBattery2 = -1;

    currentDischargerState=DS_INITIALIZING;
    osDelay(13000);

    /* Infinite loop */
    for(;;)
    {if (socBattery1 == -1 && socBattery2 == -1){
            currentDischargerState = DS_FAULT;
        }
        else{

            if (socBattery1 < dischargeSOCLevel && socBattery2 < dischargeSOCLevel){
                currentDischargerState = DS_DISCHARGE_COMPLETE;
                user_pwm_setvalue( 0, &htim4, TIM_CHANNEL_3);
            }
            else{
                currentDischargerState = DS_DISCHARGING;
                pwm_value = 4500;
                user_pwm_setvalue( (12.0/ batteryVoltage1)*8000, &htim4, TIM_CHANNEL_3);
                if(socBattery1 > dischargeSOCLevel && socBattery2 > dischargeSOCLevel){
                    user_pwm_setvalue(6000,&htim2,TIM_CHANNEL_1);
                    user_pwm_setvalue(6000,&htim3,TIM_CHANNEL_1);
                }
                else if(socBattery1 > dischargeSOCLevel && socBattery2 < dischargeSOCLevel){
                    user_pwm_setvalue(6000,&htim2,TIM_CHANNEL_1);
                    user_pwm_setvalue(9999,&htim3,TIM_CHANNEL_1);
                                }
                else {
                                    user_pwm_setvalue(9999,&htim2,TIM_CHANNEL_1);
                                    user_pwm_setvalue(6000,&htim3,TIM_CHANNEL_1);
                                                }

            }
        }
osDelay(400);

    }

void StartSMBUSTask(void const * argument)
{
  /* USER CODE BEGIN StartSMBUSTask */
    /* Infinite loop */
    for(;;)
    {
        int receivedSOC;
        HAL_I2C_DeInit(&hi2c1);
                HAL_I2C_Init(&hi2c1);
        receivedSOC = getBatterySOC(&hi2c1);
        if (receivedSOC != -1){
            socBattery2 = receivedSOC;
        }
        osDelay(100);
        HAL_I2C_DeInit(&hi2c2);
                HAL_I2C_Init(&hi2c2);
        receivedSOC = getBatterySOC(&hi2c2);
        if (receivedSOC != -1){
            socBattery1 = receivedSOC;
        }

        osDelay(100);
    }
  /* USER CODE END StartSMBUSTask */
}

I use 10 K pullups and the I2C frequency is 15 KHz. This is the oscilloscope view:(Yellow is clock and blue is data line) So I cannot understand what might be the reason behind the unchanging data (0x0B) and I cannot see slave address that is being send in oscilloscope either. The only data that is being transmitted is 0x0B.

Oscilloscope img

\$\endgroup\$
3
\$\begingroup\$

That is not 0x0B. Data on oscilloscope is to address 0x16 and as the slave chip does not acknowledge there is no further data transmission.

\$\endgroup\$
  • \$\begingroup\$ How comes it is 0x16 tho? isn't it 0b 0010110 ? \$\endgroup\$ – Günkut Ağabeyoğlu Aug 27 at 9:22
  • \$\begingroup\$ 0x16 is 0001 0110. I don't understand what is unclear. I2C ack bit is the 9th bit so what is on scope screen is 0001 0110 1. Or are you asking about why some datasheets use 7-bit addresses plus read/write bit so the 7-bit address is 0x0b for reading and writing and some datasheets use 8-bit addresses where write address is 0x16 and read address is 0x17? \$\endgroup\$ – Justme Aug 27 at 10:12
  • \$\begingroup\$ Yes my bad I thought 0x16 as decimal. Thanks for the help \$\endgroup\$ – Günkut Ağabeyoğlu Aug 27 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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