搜索

[STM32F0] 网上PMBus资料太少,大师是否可以帮忙指点迷津?

[复制链接]
464|13
 楼主 | 2020-4-3 20:54 | 显示全部楼层 |阅读模式
本帖最后由 hzocce 于 2020-4-4 19:42 编辑

看了老半天,没有看懂PMBus,MCU需要怎么去设置呢?

有配置好的范例参考么?
初始化,收发那些。

使用特权

评论回复
 楼主 | 2020-4-4 11:31 | 显示全部楼层
有做过的朋友没?

使用特权

评论回复
 楼主 | 2020-4-4 16:03 | 显示全部楼层
本帖最后由 hzocce 于 2020-4-4 16:04 编辑

按理应该是:

PMBus_Init();
PMBus_SendByte();
PMbus_RecByte();

可是为什么找不到呢?

----------------------------------------------------------------------------------------------------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----------------------------------------------------------------------------------------------------------------------------------------------------

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#include "main.h"
#include "stm32_PMBUS_stack.h"
/** @addtogroup STM32F3xx_HAL_Examples
  * @{
  */
/** @addtogroup SMBUS
  * @{
  */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
#ifdef ARP
#ifdef HOST1
static uint32_t        ARP_process = 0U;
#else /* HOST1 */
static uint8_t         UDID[16] =
{
  0x81, 0x23, 0x45, 0x67, 0x78, 0x91, 0xBC, 0xDE, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#endif /* HOST1 */
#ifdef SMB2
static uint8_t         UDID2[16] =
{
  0x81, 0x23, 0x45, 0x67, 0x78, 0x97, 0xBC, 0xDE, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#endif /* SMB2 */
#endif /* ARP */
#ifdef TEST4
#ifdef HOST1
static uint8_t         TEST_PLAN[8] =
{
  0x25, 0x1A, 0x10, 0x78, 0x90, 0x14, 0x3D, 0x65
};
#endif /* HOST1 */
#endif /* TEST4 */
uint32_t               buttonpress = 0U;
SMBUS_HandleTypeDef    handle1, handle2;
uint8_t                deviceList[MAX_DEVICE_NUM];
/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Error_Handler(void);
static void Error_Check( SMBUS_StackHandleTypeDef *pStackContext);
/* Private functions ---------------------------------------------------------*/
/**
  * @brief  Callback function notifying about extended command incoming, implementation
    is supporting extended command defined by PMBus
  * @param  pStackContext : Pointer to a SMBUS_StackHandleTypeDef structure that contains
  *                the configuration information for the specified SMBUS.
  * @retval HAL_StatusTypeDef response code. Equal STACK_OK if success, any other value means problem
  */
HAL_StatusTypeDef STACK_SMBUS_ExtendCommand( SMBUS_StackHandleTypeDef *pStackContext )
{
  uint16_t       size = 0U;
  uint8_t       *piobuf = NULL;
  /* accessing the IO buffer */
  piobuf = STACK_SMBUS_GetBuffer( pStackContext );
  /*
    Extended command must be identified by the value of the actual command code
   */
  switch ( piobuf[0] )
  {
    case 0:
      pStackContext->CurrentCommand = (st_command_t *) & EXTENDED_READ_BYTE;
      break;
    case 1:
      pStackContext->CurrentCommand = (st_command_t *) & EXTENDED_READ_WORD;
      break;
    case 2:
      pStackContext->CurrentCommand = (st_command_t *) & EXTENDED_WRITE_BYTE;
      /*
        size of the bytes yet to be received
       */
      size = 1U;
      break;
    case 3:
      pStackContext->CurrentCommand = (st_command_t *) & EXTENDED_WRITE_WORD;
      size = 2U;
      break;
    default:
      pStackContext->StateMachine |= SMBUS_SMS_ERROR;
      return STACK_ERROR;
  }
  /*
    reading the remaining data (stack won't do that for us this time
  */
  if ((pStackContext->CurrentCommand->cmnd_query & WRITE) == WRITE )
  {
    /*
      To make sure the executecommand is called again once the remaining data
      is in the buffer
    */
    STACK_PMBUS_ExtendExecution(pStackContext);
    /*
    PEC byte y/n?
    */
    if ((pStackContext->StateMachine & SMBUS_SMS_PEC_ACTIVE ) == SMBUS_SMS_PEC_ACTIVE )
    {
      size += PEC_SIZE;
    }
    /*
      asking the HAL for more bytes to receive
    */
    pStackContext->Byte_count += size;
    HAL_SMBUS_Slave_Receive_IT( pStackContext->Device, &(pStackContext->Buffer[2]), size, SMBUS_NEXT_FRAME );
  }
  return STACK_OK;
}
/**
  * @brief  Callback function notifying slave about command incoming, implementation
    is supporting extended command defined by PMBus
  * @param  pStackContext : Pointer to a SMBUS_StackHandleTypeDef structure that contains
  *                the configuration information for the specified SMBUS.
  * @retval HAL_StatusTypeDef response code. Equal STACK_OK if success, any other value means problem
  */
HAL_StatusTypeDef STACK_SMBUS_ExecuteCommand( SMBUS_StackHandleTypeDef *pStackContext )
{
  uint8_t       *piobuf = NULL;
  /* accessing the IO buffer */
  piobuf = STACK_SMBUS_GetBuffer( pStackContext );
  if ( piobuf == NULL )
  {
    pStackContext->StateMachine |= SMBUS_SMS_ERROR;
  }
  else if ( pStackContext->CurrentCommand == (st_command_t *)&HOST_NOTIFY_PROTOCOL )
  {
    /* host notify command */
    if ( pStackContext->Buffer[0] == SMBUS_ADDR_DEFAULT )
    {
      /* Usually the Host notify is used for ARP, but may not be limited to it */
#ifdef ARP
#ifdef HOST1
      /* case of ARP notify */
      ARP_process = 1U;
#endif /* HOST1 */
#endif /* ARP */
    }
  }
  else    /* Normal device command execution */
  {
    /* Zone config command example implementation */
#ifdef PMBUS13
    if ( pStackContext->CurrentCommand->cmnd_code == PMBC_ZONE_CONFIG )
    {
      pStackContext->TheZone.writeZone = pStackContext->Buffer[1];
      pStackContext->TheZone.readZone = pStackContext->Buffer[2];
    }
    else if ( pStackContext->CurrentCommand->cmnd_code ==  PMBC_ZONE_ACTIVE )
    {
      pStackContext->TheZone.activeWriteZone = pStackContext->Buffer[1];
      pStackContext->TheZone.activeReadZone = pStackContext->Buffer[2];
    }
#endif /* PMBUS13 */
    /*
      first step is to see if we have a case of extended command
    */
    if ( pStackContext->CurrentCommand->cmnd_code == PMBC_PMBUS_COMMAND_EXT )
    {
      BSP_LED_Toggle((Led_TypeDef)((piobuf[0] & 0x07U)));
    }
    else /* regular command case */
    {
      BSP_LED_Toggle((Led_TypeDef)(pStackContext->CurrentCommand->cmnd_code & 0x07U));
      if ((pStackContext->CurrentCommand->cmnd_query & BLOCK ) == BLOCK )
      {
        *piobuf = (pStackContext->CurrentCommand->cmnd_master_Rx_size) - 1U;
        /* byte size of reply for block read command */
        /* One byte for size, rest are [size] of data */
      }
    }
  }
  return STACK_OK;
}
/**
  * @brief  Stub of an error treatment function - set to ignore most errors
  * @param  pStackContext : Pointer to a SMBUS_StackHandleTypeDef structure that contains
  *                the configuration information for the specified SMBUS.
  * @retval None
  */
static void Error_Check( SMBUS_StackHandleTypeDef *pStackContext)
{
  if ( ( STACK_SMBUS_IsBlockingError(pStackContext) ) || ( STACK_SMBUS_IsCmdError( pStackContext ) ) )
  {
    /* No action, error symptoms are ignored */
    pStackContext->StateMachine &= ~(SMBUS_ERROR_CRITICAL | SMBUS_COM_ERROR);
  }
  else if ((pStackContext->StateMachine & SMBUS_SMS_ERR_PECERR ) ==
           SMBUS_SMS_ERR_PECERR ) /* PEC error, we won't wait for any more action */
  {
    pStackContext->StateMachine |= SMBUS_SMS_READY;
    pStackContext->CurrentCommand = NULL;
    pStackContext->StateMachine &= ~(SMBUS_SMS_ACTIVE_MASK | SMBUS_SMS_ERR_PECERR);
  }
}
/**
  * @brief  Main program - executes various test sequences
  * @param  None
  * @retval None
  */
int main(void)
{
#ifdef HOST1
  uint32_t      commandi = 0U;
#ifdef TEST5
  SMBUS_ZoneStateTypeDef TheZone;
#endif /* TEST5 */
#endif /* HOST1 */
  uint8_t       *piobuf;
  SMBUS_HandleTypeDef *phandle1;
  SMBUS_StackHandleTypeDef *pcontext1;
  SMBUS_StackHandleTypeDef context1;
#ifdef SMB2
  SMBUS_HandleTypeDef *phandle2;
  SMBUS_StackHandleTypeDef *pcontext2;
  SMBUS_StackHandleTypeDef context2;
#endif /* SMB2 */
  uint32_t      index;
  /* Reset of all peripherals, Initializes the Flash interface and the systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
  /* Configure LEDs */
  BSP_LED_Init(LED3);
  BSP_LED_Init(LED4);
  BSP_LED_Init(LED5);
  BSP_LED_Init(LED6);
#ifdef STM32F303xC
  BSP_LED_Init(LED7);
  BSP_LED_Init(LED8);
  BSP_LED_Init(LED9);
  BSP_LED_Init(LED10);
#endif /*STM32F303xC*/
  /* SMBUS instance initialization - smbus 1. */
  handle1.Instance = SMBUS1;
  handle1.Init.Timing = SMBUS_TIMING_100K;
  handle1.Init.AnalogFilter = SMBUS_ANALOGFILTER_ENABLE;
  handle1.Init.AddressingMode = SMBUS_ADDRESSINGMODE_7BIT;
#ifdef PMBUS13
  handle1.Init.DualAddressMode = SMBUS_DUALADDRESS_ENABLE;
  handle1.Init.OwnAddress2 = 0x40U;
  handle1.Init.OwnAddress2Masks = SMBUS_OA2_MASK05;
#else /* PMBUS13 */
  handle1.Init.DualAddressMode = SMBUS_DUALADDRESS_DISABLE;
  handle1.Init.OwnAddress2 = 0U;
  handle1.Init.OwnAddress2Masks = SMBUS_OA2_NOMASK;
#endif /* PMBUS13 */
  handle1.Init.GeneralCallMode = SMBUS_GENERALCALL_DISABLE;
  handle1.Init.NoStretchMode = SMBUS_NOSTRETCH_DISABLE;
#ifdef ARP
#ifdef DEV_PSA
  handle1.Init.OwnAddress1 = SMBUS_ADDR_DEVICE;
#else /* DEV_PSA */
  handle1.Init.OwnAddress1 = 0U;
#endif /* DEV_PSA */
  handle1.Init.PeripheralMode = SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP;
#else      /* ARP */
  handle1.Init.OwnAddress1 = SMBUS_ADDR_DEVICE;
  handle1.Init.PeripheralMode = SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE;
#endif /* ARP */
#ifdef USE_PEC
  handle1.Init.PacketErrorCheckMode = SMBUS_PEC_ENABLE;
#else
  handle1.Init.PacketErrorCheckMode = SMBUS_PEC_DISABLE;
#endif /* USE_PEC */
#ifdef HOST1
  handle1.Init.PeripheralMode = SMBUS_PERIPHERAL_MODE_SMBUS_HOST;
  handle1.Init.OwnAddress1 = 0U;
#endif /* HOST1 */
  handle1.Init.SMBusTimeout = SMBUS_TIMEOUT_DEFAULT;
  handle1.pBuffPtr = context1.Buffer;
  phandle1 = &handle1;
  HAL_SMBUS_Init( phandle1 );
  context1.CMD_table = (st_command_t *) & PMBUS_COMMANDS_TAB[0];
  context1.CMD_tableSize = PMBUS_COMMANDS_TAB_SIZE;
#ifndef TEST4
#ifndef TEST5
  /* Most tests do not use actual PMBUS commands */
  context1.CMD_table = (st_command_t *) & PMBUS_COMMANDS_TEST[0];
  context1.CMD_tableSize = PMBUS_CMD_TBL_SIZE;
#endif /* TEST4 */
#endif /* TEST5 */
  context1.Device = phandle1;
  context1.SRByte = 0x55U;
  context1.CurrentCommand = NULL;
#ifdef ARP
  context1.StateMachine = SMBUS_SMS_NONE;
#ifdef DEV_PSA
  context1.OwnAddress = SMBUS_ADDR_DEVICE;
#else /* DEV_PSA */
  context1.OwnAddress = 0U;
#endif /* DEV_PSA */
#ifndef  HOST1
  context1.ARP_UDID = (uint8_t *) &UDID;
#endif /* HOST1 */
#else /* ARP */
  context1.StateMachine = SMBUS_SMS_ARP_AR;
  context1.OwnAddress = SMBUS_ADDR_DEVICE;
#endif /* ARP */
#ifdef USE_PEC
  context1.StateMachine |= SMBUS_SMS_PEC_ACTIVE;
#endif
  pcontext1 = &context1;
  STACK_SMBUS_Init( pcontext1 );
  /* SMBUS instance initialization - smbus 2. */
#ifdef SMB2
  handle2.Instance = SMBUS2;
  handle2.Init.Timing = SMBUS_TIMING_100K;
  handle2.Init.AnalogFilter = SMBUS_ANALOGFILTER_ENABLE;
  handle2.Init.AddressingMode = SMBUS_ADDRESSINGMODE_7BIT ;
#ifdef PMBUS13
  handle2.Init.DualAddressMode = SMBUS_DUALADDRESS_ENABLE;
  handle2.Init.OwnAddress2 = 0x40U;
  handle2.Init.OwnAddress2Masks = SMBUS_OA2_MASK05;
#else /* PMBUS13 */
  handle2.Init.DualAddressMode = SMBUS_DUALADDRESS_DISABLE;
  handle2.Init.OwnAddress2 = 0U;
  handle2.Init.OwnAddress2Masks = SMBUS_OA2_NOMASK;
#endif /* PMBUS13 */
  handle2.Init.GeneralCallMode = SMBUS_GENERALCALL_DISABLE;
  handle2.Init.NoStretchMode = SMBUS_NOSTRETCH_DISABLE;
#ifdef ARP
#ifdef DEV_PSA
  handle2.Init.OwnAddress1 = SMBUS_ADDR_DEVICE + 2U;
#else /* DEV_PSA */
  handle2.Init.OwnAddress1 = 0U;
#endif /* DEV_PSA */
  handle2.Init.PeripheralMode = SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP ;
#else /* ARP */
  handle2.Init.OwnAddress1 = SMBUS_ADDR_DEVICE + 2U;
  handle2.Init.PeripheralMode = SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE ;
#endif /* ARP */
#ifdef USE_PEC
  handle2.Init.PacketErrorCheckMode = SMBUS_PEC_ENABLE;
#else
  handle2.Init.PacketErrorCheckMode = SMBUS_PEC_DISABLE;
#endif /* USE_PEC */
  handle2.Init.SMBusTimeout = SMBUS_TIMEOUT_DEFAULT;
  handle2.pBuffPtr = context2.Buffer;
  phandle2 = &handle2;
  HAL_SMBUS_Init( phandle2 );
#ifdef TEST4
  context2.CMD_table = (st_command_t *) & PMBUS_COMMANDS_TAB[0];
  context2.CMD_tableSize = PMBUS_COMMANDS_TAB_SIZE;
#else /* TEST4 */
  context2.CMD_table = (st_command_t *) & PMBUS_COMMANDS_TEST[0];
  context2.CMD_tableSize = PMBUS_CMD_TBL_SIZE;
#endif /* TEST4 */
  context2.Device = phandle2;
  context2.SRByte = 0x55U;
  context2.CurrentCommand = NULL;
#ifdef ARP  
  context2.StateMachine = SMBUS_SMS_NONE;
  context2.ARP_UDID = (uint8_t *) & UDID2;
#ifdef DEV_PSA
  context2.OwnAddress = SMBUS_ADDR_DEVICE + 2U;
#else /* DEV_PSA */
  context2.OwnAddress = 0U;
#endif /* DEV_PSA */
#else /* ARP */
  context2.StateMachine = SMBUS_SMS_ARP_AR;
  context2.OwnAddress = SMBUS_ADDR_DEVICE + 2U;
#endif /* ARP */
#ifdef USE_PEC
  context2.StateMachine |= SMBUS_SMS_PEC_ACTIVE;
#endif
  pcontext2 = &context2;
  STACK_SMBUS_Init( pcontext2 );
#endif /*SMB2*/
  /* Configure the control */
  BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
  piobuf = STACK_SMBUS_GetBuffer( pcontext1 );
  if (piobuf != NULL )
  {
    for (index = 0U; index < STACK_NBYTE_SIZE; index++)
    {
      piobuf[index] = 0U;
    }
  }
#ifdef HOST1
  while (1)
  {
#ifdef ARP
    if ( ARP_process == 1U)
    {
      for (index = 0U; index < 8U; index++)
      {
        deviceList[index] = 0U;
      }
      index = 0U;
      /* sending ARP prepare */
      STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&PMBUS_COMMANDS_ARP[0], SMBUS_ADDR_DEFAULT, WRITE);
      while ( !STACK_SMBUS_IsReady(pcontext1))
      {
        Error_Check( pcontext1 );
      }
      ARP_process ++;
      pcontext1->StateMachine &= ~SMBUS_SMS_ERR_ACKF ;
    }
    while (ARP_process == 2U)
    {
      /* send ARP getID */
      STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&PMBUS_COMMANDS_ARP[2], SMBUS_ADDR_DEFAULT, READ);
      while ( !STACK_SMBUS_IsReady(pcontext1))
      {
        Error_Check( pcontext1 );
      }
      if ((pcontext1->Buffer[2] != 0xFFU)
          && (( pcontext1->StateMachine & (SMBUS_SMS_ERR_ACKF | SMBUS_SMS_ERR_PECERR) ) == 0U)) /* not empty answer */
      {
        /* select a free address */
        deviceList[index] = (uint8_t)(2U * index + 0x16U);
        piobuf = STACK_SMBUS_GetBuffer( pcontext1 );
        if (piobuf == NULL )
        {
          break;
        }
        piobuf[0] = 17U;
        piobuf[17] = deviceList[index];
        STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&PMBUS_COMMANDS_ARP[3], SMBUS_ADDR_DEFAULT, WRITE);
        while ( !STACK_SMBUS_IsReady(pcontext1))
        {
          Error_Check( pcontext1 );
        }
        if (STACK_SMBUS_IsCmdError( pcontext1 ))
        {
          deviceList[index] = 0U;
        }
        else
        {
          index++;
          index &= 7U;
        }
        /* Wait until Tamper push-button is pressed ########################*/
        while (buttonpress == 0U)
        {}
        buttonpress = 0U;
      }
      else
      {
        pcontext1->StateMachine &= ~(SMBUS_SMS_ERR_PECERR | SMBUS_SMS_ERR_BTO);
        ARP_process++;
      }
    }
#else /* ARP */
    deviceList[0] = SMBUS_ADDR_DEVICE;
#endif  /* ARP */
    BSP_LED_On((Led_TypeDef)(commandi & 0x07U));
    HAL_Delay( 250U );
   
#ifdef TEST5
    if (deviceList[0] != 0U)
    {   
    /* TEST5 - sending different Zone commands */
    switch (commandi)
    {
      case 0:
        TheZone.writeZone = 0x01U;
        TheZone.readZone = 0x05U;
        STACK_PMBUS_MasterZoneConfig(pcontext1, SMBUS_ADDR_DEVICE, &TheZone);
        break;
      case 1:
        TheZone.activeWriteZone = 0x01U;
        TheZone.activeReadZone = 0x05U;
        STACK_PMBUS_MasterZoneActive(pcontext1, &TheZone);
        break;
      case 2:
        pcontext1->Buffer[1] = 0x5aU;
        STACK_PMBUS_MasterZoneWrite(pcontext1, (st_command_t *)&PMBUS_COMMANDS_TAB[13] );
        break;
      case 3:
        STACK_PMBUS_MasterReadZoneStatus( pcontext1, 0x00U, 0xFFU);
        break;
      default:
        commandi &= 3U;
        break;
    }
    }
#else
#ifdef TEST4
    if (deviceList[0] != 0U)
    {
      pcontext1->CMD_table = (st_command_t *) & PMBUS_COMMANDS_TAB[0];
      /* Test plan is 8 records */
      commandi &= 7U;
      
      /* Testing selected PMBUS command codes */
      index = TEST_PLAN[commandi];
      /* buffer preparation */
      if (PMBUS_COMMANDS_TAB[commandi].cmnd_query & BLOCK )
      {
        piobuf = STACK_SMBUS_GetBuffer( pcontext1 );
        piobuf[0] = 5U;
      }
      /* Command issued */
      if ( PMBUS_COMMANDS_TAB[index].cmnd_query & WRITE )
      {
        STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&PMBUS_COMMANDS_TAB[index], (uint16_t)deviceList[0], WRITE);
      }
      else if ( PMBUS_COMMANDS_TAB[index].cmnd_query & READ )
      {
        STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&PMBUS_COMMANDS_TAB[index], (uint16_t)deviceList[0], READ);
      }
      else
      {
        STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&PMBUS_COMMANDS_TAB[index], (uint16_t)deviceList[0], 0U);
      }
    }
#else /* TEST4 */
    /* buffer preparation */
    if ((PMBUS_COMMANDS_TEST[commandi].cmnd_query & BLOCK) == BLOCK )
    {
      piobuf = STACK_SMBUS_GetBuffer( pcontext1 );
      if ( piobuf == NULL )
      {
        Error_Check( pcontext1 );
      }
      else
      {
        piobuf[0] = PMBUS_COMMANDS_TEST[commandi].cmnd_master_Tx_size - 2U;
      }
    }
    if (deviceList[0] != 0U)
    {
#ifdef TEST3
      /* writing extended command code */
      piobuf = STACK_SMBUS_GetBuffer( pcontext1 );
      if ( piobuf == NULL )
      {
        Error_Check( pcontext1 );
      }
      else
      {
        piobuf[0] = (uint8_t)commandi;
      }
      /* issuing extended commands */
      switch (commandi)
      {
        case 0:
          STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&EXTENDED_READ_BYTE, (uint16_t)deviceList[0], 0U);
          break;
        case 1:
          STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&EXTENDED_READ_WORD, (uint16_t)deviceList[0], 0U);
          break;
        case 2:
          STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&EXTENDED_WRITE_BYTE, (uint16_t)deviceList[0], WRITE);
          break;
        case 3:
          STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&EXTENDED_WRITE_WORD, (uint16_t)deviceList[0], WRITE);
          break;
        default:
          commandi = 0U;
          break;
      }
#else   /* TEST3 */
      if (commandi == 0U)
      {
#ifdef TEST2
        /* command group test case */
        for ( index = 0U; index < 4U; index++)
        {
          STACK_PMBUS_HostCommandGroup( pcontext1, (st_command_t *)&PMBUS_COMMANDS_TEST[commandi],
                                        SMBUS_ADDR_DEFAULT + (uint16_t)index - 3U,
                                        (index == 3U) ? 1U : 0U );
          while
          (
            ( pcontext1->Device->State != HAL_SMBUS_STATE_READY ) &&
            ( pcontext1->Device->State != HAL_SMBUS_STATE_LISTEN )
          )
          {}
        }
        /*
        Note: the group command assumes presence of several devices. In their absence it fails to transmit successfully.
        We then reset the stack error.
        */
        pcontext1->StateMachine |= SMBUS_SMS_READY;
        pcontext1->CurrentCommand = NULL;
        pcontext1->StateMachine &= ~(SMBUS_SMS_ACTIVE_MASK | SMBUS_ERROR_CRITICAL);
#else /* TEST2 */
        /* testing receive byte */
        STACK_SMBUS_HostRead( pcontext1, &(context1.SRByte), (uint16_t)deviceList[0]);
#endif /* TEST2 */
      }
      /* issuing command from test table */
      else if (( PMBUS_COMMANDS_TEST[commandi].cmnd_query & READ ) == READ )
      {
        STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&PMBUS_COMMANDS_TEST[commandi], (uint16_t)deviceList[0], READ);
      }
      else if (( PMBUS_COMMANDS_TEST[commandi].cmnd_query & PROCESS_CALL ) == PROCESS_CALL )
      {
        STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&PMBUS_COMMANDS_TEST[commandi], (uint16_t)deviceList[0], 0U);
      }
      else
      {
        STACK_SMBUS_HostCommand( pcontext1, (st_command_t *)&PMBUS_COMMANDS_TEST[commandi], (uint16_t)deviceList[0], WRITE);
      }
#endif /* TEST3 */
    }
#endif /* TEST4 */
#endif /* TEST5 */
    while ( STACK_SMBUS_IsReady(pcontext1) != SMBUS_SMS_READY)
    {
      Error_Check( pcontext1 );
    }
    for (index = 0; index < 8; index++)
    {
      BSP_LED_Off((Led_TypeDef)index);
    }
    HAL_Delay( 750U );
    if (buttonpress == 1U)
    {
      /* next test case */
      commandi++;
      if (commandi >= PMBUS_CMD_TBL_SIZE)
      {
        commandi = 0U;
      }
      buttonpress = 0U;
    }
  }
#else   /* HOST1 */
#ifdef ARP
  if ( ( context1.OwnAddress == 0U ) || ((context1.StateMachine & SMBUS_SMS_ARP_AR) == 0U ) )
  {
    STACK_SMBUS_NotifyHost( pcontext1 );
  }
#ifdef SMB2
  else if ( ( context2.OwnAddress == 0U ) || ((context2.StateMachine & SMBUS_SMS_ARP_AR) == 0U ) )
  {
    STACK_SMBUS_NotifyHost( pcontext2 );
  }
#endif /* SMB2 */
#endif /* ARP */
  while (1)
  {
    HAL_Delay( 200U );
    /* Periodically checking error state of the stack */
    Error_Check( &context1 );
    /* Periodically checking for Quick command */
    if ( context1.StateMachine & ( SMBUS_SMS_QUICK_CMD_W | SMBUS_SMS_QUICK_CMD_R ) )
    {
      BSP_LED_On((Led_TypeDef)0U);
      context1.StateMachine &= ~( SMBUS_SMS_QUICK_CMD_W | SMBUS_SMS_QUICK_CMD_R );
    }
#ifdef SMB2
    Error_Check( &context2 );
    if ( context2.StateMachine & ( SMBUS_SMS_QUICK_CMD_W | SMBUS_SMS_QUICK_CMD_R ) )
    {
      BSP_LED_On((Led_TypeDef)0U);
      context2.StateMachine &= ~( SMBUS_SMS_QUICK_CMD_W | SMBUS_SMS_QUICK_CMD_R );
    }
    context2.StateMachine &= ~SMBUS_SMS_ERR_ARLO;
#endif /* SMB2 */
    /* Dim the LED */
    for (index = 0; index < 8; index++)
    {
      BSP_LED_Off((Led_TypeDef)index);
    }
    /* Cleaning arbitration loss flag */
    context1.StateMachine &= ~SMBUS_SMS_ERR_ARLO;
    if (buttonpress == 1U)
    {
#ifdef ALERT
      STACK_SMBUS_SendAlert( pcontext1 );
#else /* ALERT */
      STACK_SMBUS_NotifyHost( pcontext1 );
#endif /* ALERT */
      buttonpress = 0U;
    }
  }
#endif /* HOST1 */
}
/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
static void Error_Handler(void)
{
  /* User may add here some code to deal with this error */
  while (1)
  {}
}
/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow :
  *        System Clock source                    | PLL (HSI)
  *        SYSCLK(Hz)                             | 48000000
  *        HCLK(Hz)                               | 48000000
  *        AHB Prescaler                          | 1
  *        APB2 Prescaler                         | 2
  *        APB1 Prescaler                         | 2
  *        HSI Frequency(Hz)                      | 8000000
  *        PLLMUL                                 | 12
  *        PREDIV                                 | 2
  *        USB Clock                              | DISABLE
  *        Flash Latency(WS)                      | 2
  *        Prefetch Buffer                        | OFF
  * @param  None
  * @retval None
  */
static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_PeriphCLKInitTypeDef RCC_Peri = {0};
  /* Enable HSI Oscillator and activate PLL with HSI as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /* Set the I2C clock */
  RCC_Peri.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
  RCC_Peri.I2c1ClockSelection = RCC_I2C1CLKSOURCE_SYSCLK;
  HAL_RCCEx_PeriphCLKConfig(&RCC_Peri);
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
/**
  * @brief EXTI line detection callbacks
  * @param GPIO_Pin: Specifies the pins connected EXTI line
  * @retval None
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  buttonpress = 1U;
}
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* Infinite loop */
  Error_Handler();
}
#endif

  

main.rar

6.64 KB, 下载次数: 5

使用特权

评论回复
 楼主 | 2020-4-4 19:40 | 显示全部楼层
本帖最后由 hzocce 于 2020-4-4 19:41 编辑

还是说,只有有普通的I2C初始化就好了?



I2C_Init();
PMBus_process();

PMBus就是I2C,然后只是数据命令而已???

如果是普通的I2C,那为什么规格书上面说支持SMBus/PMBus呢?
而又的规格书上面又未提及支持PMBus

使用特权

评论回复
 楼主 | 2020-4-5 14:44 | 显示全部楼层
??

使用特权

评论回复
 楼主 | 2020-4-6 14:52 | 显示全部楼层
求关注~~

使用特权

评论回复
 楼主 | 2020-4-7 20:50 | 显示全部楼层
浮起来~~

使用特权

评论回复
 楼主 | 2020-4-9 10:25 | 显示全部楼层
深度求关注~~

使用特权

评论回复
 楼主 | 2020-4-10 15:13 | 显示全部楼层
CubeMX中的I2C 3中工作方式指示的是什么?
STM32_I2C工作方式.PNG

使用特权

评论回复
 楼主 | 2020-4-22 17:10 | 显示全部楼层
别沉了

使用特权

评论回复
| 2020-4-22 21:33 | 显示全部楼层
我之前用过smbus,只用了几条指令。iic,smbus,pmbus其实都是一样的,只是smbus和pmbus的时序更加严格一些。smbus和pmbus大多都是用在电源上的。
我用的CPU是stm32f429IG和stm32f103c8(调试使用),控制数字电源模块。当时选定了3个厂家的电源模块,其中两个厂家模块我是用IO口模拟的SMBUS,可以正常使用,有一个厂家无法正常使用,想了很多的办法,调整上拉电阻,修改延时等等,最后还是不行,试着用了一下stm32的硬件IIC,可以正常控制。
另外就是stm32有部分的单片机是由smbus模式(就是IIC的一种形式),大部分是不支持的。
之前调试的时候,看过stm32的smbus库,感觉就是根据行业标准,直接把寄存器都定义好,在IIC的基础上加了一个封装,方便直接调用。(类似于stm32的寄存器版和库函数版)

使用特权

评论回复
 楼主 | 2020-4-23 21:09 | 显示全部楼层
g753388438 发表于 2020-4-22 21:33
我之前用过smbus,只用了几条指令。iic,smbus,pmbus其实都是一样的,只是smbus和pmbus的时序更加严格一些 ...

I2C没有校验部分。

I2C 就是:发器件地址>>发内部寄存器地址>>发数据>>发数据>>发数据>>发数据>>发数据。。。

可是SMBUS,PMBUS 多了校验字节。

如果用于SMBus,PMBus 在CubeMX是不是需要配置成SMBUS工作方式? 那cube界面上面有3个方式可选。
你是用那个工作方式实现的SMbus控制?

STM32作为从机??

能给些文件研究学习些么?

使用特权

评论回复
| 2020-4-24 08:48 | 显示全部楼层
hzocce 发表于 2020-4-23 21:09
I2C没有校验部分。

I2C 就是:发器件地址>>发内部寄存器地址>>发数据>>发数据>>发数据>>发数据>>发数据 ...

我这边用的STM32是作为主机的。
cubemx配置的是IIC,没有选择SMBUS.使用的时候就是把库函数简单的封装了一下。
我看的资料主要有两个,一个是smbus的标准手册SMBus_3_0_20141220,另外的就是模块的使用手册


  1. static uint8_t SM_Read(uint8_t dev,uint8_t addr)
  2. {
  3.         uint8_t dat;
  4.         vTaskDelay(2);
  5.         if(dev<2)
  6.         {
  7.                 MX_I2C2_Init();
  8.                 HAL_I2C_Mem_Read(&hi2c2,DEVICE_ADD[dev],addr,I2C_MEMADD_SIZE_8BIT,(uint8_t *)&dat,1,1000);       
  9.         }                       
  10.        
  11.        
  12.         return dat;
  13. }

  14. static uint16_t SM_ReadN(uint8_t dev,uint8_t addr)
  15. {
  16.         uint16_t dat;
  17.         vTaskDelay(2);
  18.         if(dev<2)
  19.         {
  20.                 MX_I2C2_Init();
  21.                 HAL_I2C_Mem_Read(&hi2c2,DEVICE_ADD[dev],addr,I2C_MEMADD_SIZE_8BIT,(uint8_t *)&dat,2,1000);       
  22.         }
  23.        
  24.         return dat;
  25. }
  26.        
  27. static uint32_t SM_ReadN2(uint8_t dev,uint8_t addr)
  28. {
  29.         uint64_t da2t;
  30.                 vTaskDelay(2);
  31.         if(dev<2)
  32.         {
  33.                 MX_I2C2_Init();
  34.                 HAL_I2C_Mem_Read(&hi2c2,DEVICE_ADD[dev],addr,I2C_MEMADD_SIZE_8BIT,(uint8_t *)&da2t,5,1000);       
  35.         }
  36.        
  37.         return ((da2t>>8)&0xFFFFFFFF);
  38. }

  39. static void SM_Write(uint8_t dev,uint8_t addr,uint8_t dat)
  40. {
  41.                 vTaskDelay(10);
  42.         if(dev<2)
  43.         {
  44.                 MX_I2C2_Init();
  45.                 HAL_I2C_Mem_Write(&hi2c2,DEVICE_ADD[dev],addr,I2C_MEMADD_SIZE_8BIT,(uint8_t *)&dat,1,1000);       
  46.         }
  47.        
  48. }

  49. static void SM_WriteN(uint8_t dev,uint8_t addr,uint16_t buf)
  50. {
  51.                 vTaskDelay(10);
  52.         if(dev<2)
  53.         {
  54.                 MX_I2C2_Init();
  55.                 HAL_I2C_Mem_Write(&hi2c2,DEVICE_ADD[dev],addr,I2C_MEMADD_SIZE_8BIT,(uint8_t *)&buf,2,1000);       
  56.         }
  57.        
  58.        
  59. }
  60. static void SM_WriteN2(uint8_t dev,uint8_t addr,uint32_t buf)
  61. {
  62.         uint64_t dat;
  63.         dat=buf;
  64.         dat<<=8;
  65.         dat|=0x04;
  66.         vTaskDelay(10);
  67.         if(dev<2)
  68.                 {
  69.                 MX_I2C2_Init();
  70.         HAL_I2C_Mem_Write(&hi2c2,DEVICE_ADD[dev],addr,I2C_MEMADD_SIZE_8BIT,(uint8_t *)&dat,5,1000);       
  71.         }
  72.        
  73. }
复制代码

使用特权

评论回复
| 2020-4-24 08:51 | 显示全部楼层
这个是我用IO口模拟smbus。
部分厂家的模块是可以正常用的,部分厂家的不能用。你自己参考一下

  1. #define DL_L         500         // 长延时
  2. #define DL_S         20         // 短延时
  3. #define ADDDD 82 //41//0X52
  4. #define WRITE 0x00         // SMBus 写命令
  5. #define READ         0x01         // SMBus 读命令


  6. static void BRD_IO_IN(void)
  7. {
  8.         GPIO_InitTypeDef GPIO_InitStruct = {0};

  9.         GPIO_InitStruct.Pin = G_BRD_DATA_Pin;
  10.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  11.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  12.   HAL_GPIO_Init(G_BRD_DATA_GPIO_Port, &GPIO_InitStruct);
  13. }
  14. static void BRD_IO_OUT(void)
  15. {
  16.         GPIO_InitTypeDef GPIO_InitStruct = {0};
  17.        
  18.         GPIO_InitStruct.Pin = G_BRD_DATA_Pin;
  19.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  20.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  21.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  22.   HAL_GPIO_Init(G_BRD_DATA_GPIO_Port, &GPIO_InitStruct);
  23. }

  24. void Delay_us(uint16_t time)
  25. {   
  26.   uint16_t i=0;  
  27.         while(time--)
  28.         {
  29. //                i=5;
  30.                 i=41;
  31.                 while(i--);
  32.         }
  33. }



  34. /*********************************************************************************************************
  35. ** 函数名称: I2C_Start
  36. ** 功能描述: 启动
  37. ** 输   入: 无
  38. ** 输          出: 无
  39. ********************************************************************************************************/
  40. void I2C_Start(void)
  41. {
  42.         BRD_IO_OUT();// 把 SDA SCL 引脚配置成输出模式
  43.         Delay_us(DL_L);
  44.         I2C_SDA_H;
  45.         Delay_us(DL_S);
  46.         I2C_SCL_H;
  47.         Delay_us(DL_L);
  48.         I2C_SDA_L;
  49.         Delay_us(DL_L);
  50. //        I2C_SCL_L;
  51. //        Delay_us(DL_L);
  52. }

  53. /*********************************************************************************************************
  54. ** 函数名称: I2C_Stop
  55. ** 功能描述: 停止
  56. ** 输   入: 无
  57. ** 输          出: 无
  58. ********************************************************************************************************/
  59. void  I2C_Stop(void)
  60. {
  61.         BRD_IO_OUT();// 把 SDA SCL 引脚配置成输出模式
  62.         Delay_us(DL_L);
  63.         I2C_SDA_L;
  64.         Delay_us(DL_S);
  65.         I2C_SCL_H;
  66.         Delay_us(DL_L);
  67.         I2C_SDA_H;
  68.         Delay_us(DL_L);
  69. }

  70. /*********************************************************************************************************
  71. ** 函数名称: I2C_Ack
  72. ** 功能描述: 需应答
  73. ** 输   入: 无
  74. ** 输          出: 0-正常;1-故障
  75. ********************************************************************************************************/
  76. uint8_t I2C_Ack(void)
  77. {
  78.         uint8_t i;
  79.         uint8_t bit_ack;
  80.         BRD_IO_IN();        // 把 SDA 引脚配置成输入模式
  81.         I2C_SCL_H;
  82.         Delay_us(DL_L);
  83.         for(i=0;i<200;i++)
  84.         {
  85.                 bit_ack = READ_SDA;
  86. //                Delay_us(DL_S);
  87.                 if(bit_ack == 0)
  88.                         break;
  89.         }
  90.         I2C_SCL_L;
  91.         Delay_us(DL_L);
  92.         return bit_ack;
  93. }

  94. /*********************************************************************************************************
  95. ** 函数名称: I2C_Nack
  96. ** 功能描述: 无需应答
  97. ** 输   入: 无
  98. ** 输          出: 无
  99. ********************************************************************************************************/
  100. void I2C_Nack(void)
  101. {
  102.         BRD_IO_OUT();// 把 SDA SCL 引脚配置成输出模式
  103.         Delay_us(DL_L);
  104.         I2C_SDA_H;
  105.         Delay_us(DL_L);
  106.         I2C_SCL_H;
  107.         Delay_us(DL_L);
  108.         I2C_SCL_L;
  109.         Delay_us(DL_L);

  110. }
  111. /*********************************************************************************************************
  112. ** 函数名称: I2C_Cack
  113. ** 功能描述: 产生应答
  114. ** 输   入: 无
  115. ** 输          出: 无
  116. ********************************************************************************************************/

  117. void I2C_Cack(void)
  118. {
  119.         BRD_IO_OUT();// 把 SDA SCL 引脚配置成输出模式
  120.         Delay_us(DL_L);
  121.         I2C_SDA_L;
  122.         Delay_us(DL_L);
  123.         I2C_SCL_H;
  124.         Delay_us(DL_L);
  125.         I2C_SCL_L;
  126.         Delay_us(DL_L);
  127. }
  128. /*********************************************************************************************************
  129. ** 函数名称: I2C_write_data
  130. ** 功能描述: 单字节写函数
  131. ** 输   入: 待写数据 dat
  132. ** 输          出: 无
  133. ********************************************************************************************************/
  134. void I2C_write_data( uint8_t dat)
  135. {
  136.         uint8_t i = 8;
  137.         BRD_IO_OUT();// 把 SDA SCL 引脚配置成输出模式
  138.         while( i-- )
  139.         {
  140.                 Delay_us(DL_L);
  141.                 I2C_SCL_L;
  142.                 Delay_us(DL_L);
  143.                 if ( dat &0x80 )
  144.                         I2C_SDA_H;
  145.                 else
  146.                         I2C_SDA_L;
  147.                 Delay_us(DL_L);
  148.                 I2C_SCL_H;
  149.                 dat = dat << 1;
  150.         }
  151.         Delay_us(DL_L);
  152.         I2C_SCL_L;
  153.         Delay_us(DL_S);
  154.         I2C_SDA_H;
  155.         Delay_us(DL_L);
  156. }

  157. void I2C_write_data1( uint8_t dat)
  158. {
  159.         uint8_t i = 8;
  160.         BRD_IO_OUT();// 把 SDA SCL 引脚配置成输出模式
  161.         while( i-- )
  162.         {
  163.                 Delay_us(DL_L);
  164.                 I2C_SCL_L;
  165.                 Delay_us(DL_L);
  166.                 if ( dat &0x80 )
  167.                         I2C_SDA_H;
  168.                 else
  169.                         I2C_SDA_L;
  170.                 Delay_us(DL_L);
  171.                 I2C_SCL_H;
  172.                 dat = dat << 1;
  173.         }
  174.         Delay_us(DL_L);
  175.         I2C_SCL_L;
  176. //        Delay_us(DL_S);
  177. //        I2C_SDA_H;
  178. //        Delay_us(DL_L);
  179. }

  180. /*********************************************************************************************************
  181. ** 函数名称: I2C_read_data
  182. ** 功能描述: 单字节读函数
  183. ** 输   入: 无
  184. ** 输          出: 数据
  185. ********************************************************************************************************/
  186. uint8_t I2C_read_data(void)
  187. {
  188.         uint8_t i = 8;
  189.         uint8_t dat = 0;
  190.         BRD_IO_OUT();// 把 SDA SCL 引脚配置成输出模式
  191.         Delay_us(DL_L);
  192.         I2C_SCL_L;
  193.         Delay_us(DL_S);
  194.         I2C_SDA_H;
  195.         Delay_us(DL_L);
  196.         BRD_IO_IN();        // 把 SDA 引脚配置成输入模式
  197.         Delay_us(DL_L);
  198.         while(i--)
  199.         {
  200.                 dat = dat << 1;
  201.                 I2C_SCL_H;
  202.                 Delay_us(DL_L);
  203.                 if(READ_SDA)
  204.                         dat++;
  205.                 I2C_SCL_L;
  206.                 Delay_us(DL_L);
  207.         }
  208.         return dat;
  209. }

  210. /*********************************************************************************************************
  211. ** 函数名称: SM_Write
  212. ** 功能描述: SMBus 单字节写函数,向给定存储器地址写一个字节
  213. ** 输   入: 待写数据 dat
  214. **                         待写存储器地址(2字节)addr
  215. **                         待写EEPROM芯片的器件地址0xA0
  216. ** 输          出: 无
  217. ********************************************************************************************************/
  218. void SM_Write(uint8_t addr,uint8_t dat)
  219. {
  220.         I2C_Start();
  221.         I2C_write_data(ADDDD | WRITE);        // 片选 + WRITE
  222.         I2C_Ack();
  223.         I2C_write_data(addr);                         // 地址
  224.         I2C_Ack();
  225.         I2C_write_data(dat);
  226.         I2C_Nack();
  227.         I2C_Stop();
  228. }

  229. /*********************************************************************************************************
  230. ** 函数名称: SM_Write
  231. ** 功能描述: SMBus 多字节写函数,从向给定存储器地址开始写多个字节
  232. ** 输   入: 待写存储器起始地址(1字节)addr
  233. **                         待写数据 I2C_Buf
  234. **                         待写数据个数 count
  235. ** 输          出: 无
  236. ********************************************************************************************************/
  237. void SM_WriteN1(uint8_t addr,uint16_t buf)
  238. {
  239.         I2C_Start();
  240.         I2C_write_data(ADDDD | WRITE);        // 片选 + WRITE
  241.         I2C_Ack();
  242.         I2C_write_data(addr);                         // 地址
  243.         I2C_Ack();
  244.         I2C_write_data(buf&0XFF);
  245.         I2C_Ack();
  246.         //I2C_Nack();
  247.         I2C_write_data((buf>>8)&0XFF);
  248.         I2C_Ack();
  249.         I2C_Stop();
  250.        

  251. }

  252. /*********************************************************************************************************
  253. ** 函数名称: SM_Read
  254. ** 功能描述: SMBus 字节读函数,从给定存储器地址读一个字节
  255. ** 输   入: 待读存储器地址(1字节)addr
  256. **                         待读EEPROM芯片的器件地址 0xA0
  257. ** 输          出: 数据
  258. ********************************************************************************************************/
  259. uint8_t SM_Read(uint8_t addr)
  260. {
  261.         uint8_t dat;
  262.         I2C_Start();
  263.         I2C_write_data(ADDDD | WRITE);        // 片选 + WRITE
  264.         I2C_Ack();
  265.         I2C_write_data(addr);                                         // 地址
  266.         I2C_Ack();
  267.         I2C_Start();
  268.         I2C_write_data(ADDDD | READ);                // 片选 + READ
  269.         I2C_Ack();
  270.         dat = I2C_read_data();
  271.         I2C_Ack();
  272.         I2C_Stop();

  273.         return dat;
  274. }


  275. /*********************************************************************************************************
  276. ** 函数名称: SM_ReadN
  277. ** 功能描述: SMBus 多字节读函数,从给定存储器地址起读多个字节
  278. ** 输   入: 待读存储器起始地址(2字节)addr
  279. **                         待读数据个数 count
  280. ** 输          出: 数据
  281. ********************************************************************************************************/
  282. uint16_t SM_ReadN(uint8_t addr)
  283. {
  284.         uint16_t dat;
  285.         uint8_t ddda;
  286.         I2C_Start();
  287.         I2C_write_data(ADDDD | WRITE);        // 片选 + WRITE
  288.         I2C_Ack();
  289.         I2C_write_data(addr);                                         // 地址
  290.         I2C_Ack();       
  291.         I2C_Start();
  292.         I2C_write_data(ADDDD | READ);                // 片选 + READ
  293.         I2C_Ack();
  294.         ddda = I2C_read_data();
  295.         I2C_Cack();
  296.         dat=ddda;
  297.         ddda = I2C_read_data();
  298.         I2C_Cack();
  299.         dat+=(ddda<<8);
  300.         I2C_Stop();
  301.         return dat;
  302. }


复制代码

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表