简体   繁体   English

STM32中风扇驱动IC的smBus通信测试与C

[英]smBus communication testing for fan driver IC in STM32 with C

I developed a library for fan IC which use smbus protocol.我开发了一个使用 smbus 协议的风扇 IC 库。 However ı have some problems and questions.但是我有一些问题和疑问。 1 -) what is diff between master and slave for smbus? 1 -) smbus 的主从之间有什么区别? whether the IC should be slave or master is not specified in the datasheet.数据表中未指定 IC 是从机还是主机。 Therefore, how can ı decide that stm32 developer board should be slave or master.因此,我如何决定stm32开发板应该是slave还是master。 2-) unfortunately, ı cannot try my code because fan driver IC ı have not received yet sensor. 2-) 不幸的是,我无法尝试我的代码,因为风扇驱动器 IC 我还没有收到传感器。 Do u know any method to test my code.你知道有什么方法可以测试我的代码吗? Maybe ardunio library.也许是ardunio图书馆。 3-) to receive data, ı firstly tranmit the register address of data ı want to read. 3-) 接收数据,我首先发送我要读取的数据的寄存器地址。 is it correct.这是正确的吗。 You can find datasheet of IC and code ı wrote below您可以找到我在下面写的 IC 和代码的数据表

C file C 档案

#include "smbusDriver.h"
#include "stm32f0xx_hal_smbus.h"
#include "stm32f0xx_hal.h"
#include "smbusDriver.h"




resultConditions_t InitializeDriver(SMBUS_HandleTypeDef *hsmbus, uint8_t address, addressValues_t *Daddress){

    Daddress->Fields.configurationRegisterAddress = 0x20;
    Daddress->Fields.FanStatusRegisterAddress = 0x24;
    Daddress->Fields.FanStallRegisterAddress = 0x25;
    Daddress->Fields.FanSpinRegisterAddress = 0x26;
    Daddress->Fields.DriveFailStatusAddress = 0x27;
    Daddress->Fields.FanInterruptEnableRegisterAddress = 0x29;
    Daddress->Fields.PwmPolarityRegisterAddress = 0x2A;
    Daddress->Fields.PwmOutputTypeRegisterAddress = 0x2B;
    Daddress->Fields.PwmFrequency45Address = 0x2C;
    Daddress->Fields.PwmFrequency123Address = 0x2D;
    Daddress->Fields.PwmDivider1Address = 0x31;
    Daddress->Fields.PwmDivider2Address = 0x41;
    Daddress->Fields.PwmDivider3Address = 0x51;
    Daddress->Fields.PwmDivider4Address = 0x61;
    Daddress->Fields.PwmSettingAddress1  = 0x30;
    Daddress->Fields.PwmSettingAddress2  = 0x40;
    Daddress->Fields.PwmSettingAddress3  = 0x50;
    Daddress->Fields.PwmSettingAddress4  = 0x60;
    resultConditions_t result = RESULT_OK;
    uint8_t buf[2];
    configuration_t confDriver;
    confDriver.Fields.MASK = 0 ; // Alert pin activated.
    confDriver.Fields.DIS_TO = 0; // smBUS enabled. If 1, I2C is compatible
    confDriver.Fields.WD_EN = 0; // Watchdog is not enabled
    confDriver.Fields.DRECK = 1; // Enabled internal clock
    confDriver.Fields.USECK = 0; // Connecting internal oscillator
    FanInterruptEnableRegister_t FanIntEn;
    FanIntEn.Fields.F1ITEN = 1;
    FanIntEn.Fields.F2ITEN = 1;
    FanIntEn.Fields.F3ITEN = 1;
    FanIntEn.Fields.F4ITEN = 1;
    FanIntEn.Fields.F5ITEN = 0;
    PwmPolarityRegister_t PwmPolarity;
    PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
    PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
    PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
    PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
    PwmOutputTypeRegister_t OutputType;
    OutputType.Fields.PMOT1 = 0;
    OutputType.Fields.PMOT2 = 0;
    OutputType.Fields.PMOT3 = 0;
    OutputType.Fields.PMOT4 = 0;
    PwmFrequency45_t BaseFrequency_45;
    PwmFrequency123_t BaseFrequency_123;
    BaseFrequency_45.Fields.PwmFrequency4 = 0; // 26kHz
    BaseFrequency_45.Fields.PwmFrequency5 = 0; // 26kHz
    BaseFrequency_123.Fields.PwmFrequency1 = 0; // 26kHz
    BaseFrequency_123.Fields.PwmFrequency2 = 0; // 26kHz
    BaseFrequency_123.Fields.PwmFrequency3 = 0; // 26kHz
    PwmDividerRegister_t Divider;
    Divider.Fields.pwmDivider_1 = 0x01; // PWM Divider
    Divider.Fields.pwmDivider_2 = 0x01; // PWM Divider
    Divider.Fields.pwmDivider_3 = 0x01; // PWM Divider
    Divider.Fields.pwmDivider_4 = 0x01; // PWM Divider
    HAL_SMBUS_Init(hsmbus);
    HAL_Delay(10);
    uint16_t DeviceAddress = 0x0000;
    DeviceAddress = DeviceAddress | address;
    result = HAL_SMBUS_IsDeviceReady(hsmbus, DeviceAddress, 5 , 1000);
    if (result != RESULT_OK) return result;
    HAL_SMBUS_EnableAlert_IT(hsmbus);
    if (result != RESULT_OK) return result;
    HAL_SMBUS_EnableListen_IT(hsmbus);
    if (result != RESULT_OK) return result;

    HAL_Delay(20);
    buf[0] = Daddress->Fields.configurationRegisterAddress; // The configuration of board is set
    buf[1] = confDriver.value;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    if (result != RESULT_OK) return result;
    HAL_Delay(20);
    buf[0] = Daddress->Fields.FanInterruptEnableRegisterAddress; // If any alert shows up, Fans can interrupt the operation
    buf[1] = FanIntEn.value;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    HAL_Delay(20);
    if (result != RESULT_OK) return result;
    buf[0] = Daddress->Fields.PwmPolarityRegisterAddress; // The high to high, low to low
    buf[1] = PwmPolarity.value;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    HAL_Delay(20);
    if (result != RESULT_OK) return result;
    buf[0] = Daddress->Fields.PwmOutputTypeRegisterAddress; // Pull-push and Open Drain choose
    buf[1] = OutputType.value;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    HAL_Delay(20);
    if (result != RESULT_OK) return result;
    buf[0] = Daddress->Fields.PwmFrequency45Address; // Base Frequency 4-5
    buf[1] = BaseFrequency_45.value;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    HAL_Delay(20);
    if (result != RESULT_OK) return result; // Base Frequency 1-2-3
    buf[0] = Daddress->Fields.PwmFrequency123Address;
    buf[1] = BaseFrequency_123.value;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    HAL_Delay(20);
    if (result != RESULT_OK) return result;
    buf[0] = Daddress->Fields.PwmDivider1Address; // Divider of frequency => frequency / divide factor (Duty Cycle is not affected)
    buf[1] = Divider.Fields.pwmDivider_1;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    HAL_Delay(20);
    if (result != RESULT_OK) return result;
    buf[0] = Daddress->Fields.PwmDivider2Address; // Divider of frequency
    buf[1] = Divider.Fields.pwmDivider_2;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    HAL_Delay(20);
    if (result != RESULT_OK) return result;
    buf[0] = Daddress->Fields.PwmDivider3Address; // Divider of frequency
    buf[1] = Divider.Fields.pwmDivider_3;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    HAL_Delay(20);
    if (result != RESULT_OK) return result;
    buf[0] = Daddress->Fields.PwmDivider4Address; // Divider of frequency
    buf[1] = Divider.Fields.pwmDivider_4;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    if (result != RESULT_OK) return result;
    return result;
}



resultConditions_t setPwmConfig(uint8_t Pwm, addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
    resultConditions_t result = HAL_OK;
    PwmSettings_t pwmSet;
    uint8_t buf[2];
    pwmSet.Fields.pwmSettings1 = Pwm;
    pwmSet.Fields.pwmSettings2 = Pwm;
    pwmSet.Fields.pwmSettings3 = Pwm;
    pwmSet.Fields.pwmSettings4 = Pwm;
    uint16_t DeviceAddress = 0x0000;
    DeviceAddress = DeviceAddress | address;
    buf[0] = Daddress->Fields.PwmSettingAddress1; // Pwm set
    buf[1] = pwmSet.Fields.pwmSettings1;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> %100 Duty Cycle /\ 0x00 -> %0 Duty Cycle
    if (result != RESULT_OK) return result;
    buf[0] = Daddress->Fields.PwmSettingAddress2; // Pwm set
    buf[1] = pwmSet.Fields.pwmSettings2;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> %100 Duty Cycle /\ 0x00 -> %0 Duty Cycle
    if (result != RESULT_OK) return result;
    buf[0] = Daddress->Fields.PwmSettingAddress3; // Pwm set
    buf[1] = pwmSet.Fields.pwmSettings3;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> %100 Duty Cycle /\ 0x00 -> %0 Duty Cycle
    if (result != RESULT_OK) return result;
    buf[0] = Daddress->Fields.PwmSettingAddress4; // Pwm set
    buf[1] = pwmSet.Fields.pwmSettings4;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> %100 Duty Cycle /\ 0x00 -> %0 Duty Cycle
    if (result != RESULT_OK) return result;
    return result;
}


generalStatus_t getGeneralStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
    uint8_t buf[2];
    uint8_t DeviceAddress;
    DeviceAddress = DeviceAddress | address;
    resultConditions_t result;
    buf[0] = Daddress->Fields.FanStatusRegisterAddress;
    generalStatus_t returnValue = NO_ERROR;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
    result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf+1,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
    if (buf[0] == 0x00){
        return returnValue;
    }
    else {
        if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000){
            returnValue = DRIVE_FAIL_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b01000000) == (uint8_t)0b01000000){
            returnValue = FAN_SPIN_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000)
        {
            returnValue = FAN_STALL_ERROR;
            return returnValue;
        }
        else{
            returnValue = UNEXPECTED_ERROR;
            return returnValue;
        }
    }
}


specialFanStallStatus_t getStallStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
    uint8_t buf[2];
    uint8_t DeviceAddress;
    DeviceAddress = DeviceAddress | address;
    resultConditions_t result;
    buf[0] = Daddress->Fields.FanStallRegisterAddress;
    specialFanStallStatus_t returnValue = NO_ERROR;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
    result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
    if (buf[0] == 0x00){
        return returnValue;
    }
    else {
        if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
            returnValue = FAN_1_STALL_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
            returnValue = FAN_2_STALL_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000)
        {
            returnValue = FAN_3_STALL_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b00010000) == (uint8_t)0b000100000)
        {
            returnValue = FAN_4_STALL_ERROR;
            return returnValue;
        }
        else{
            returnValue = UNEXPECTED_ERROR;
            return returnValue;
        }
    }
}


specialFanSpinStatus_t getSpinStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
    uint8_t buf[2];
    uint8_t DeviceAddress;
    DeviceAddress = DeviceAddress | address;
    resultConditions_t result;
    buf[0] = Daddress->Fields.FanSpinRegisterAddress;
    specialFanSpinStatus_t returnValue = NO_SPIN_ERROR;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
    result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
    if (buf[0] == 0x00){
        return returnValue;
    }
    else {
        if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
            returnValue = FAN_1_SPIN_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
            returnValue = FAN_2_SPIN_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000)
        {
            returnValue = FAN_3_SPIN_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b00010000) == (uint8_t)0b000100000)
        {
            returnValue = FAN_4_SPIN_ERROR;
            return returnValue;
        }
        else{
            returnValue = UNEXPECTED_ERROR;
            return returnValue;
        }
    }
}

specialFanDriveStatus_t getDriveStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
    uint8_t buf[2];
    uint8_t DeviceAddress;
    DeviceAddress = DeviceAddress | address;
    resultConditions_t result;
    buf[0] = Daddress->Fields.DriveFailStatusAddress;
    specialFanDriveStatus_t returnValue = NO_ERROR;
    result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
    result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
    if (buf[0] == 0x00){
        return returnValue;
    }
    else {
        if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
            returnValue = FAN_1_DRIVE_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
            returnValue = FAN_2_DRIVE_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000)
        {
            returnValue = FAN_3_DRIVE_ERROR;
            return returnValue;
        }
        else if ((buf[0] & (uint8_t)0b00010000) == (uint8_t)0b000100000)
        {
            returnValue = FAN_4_DRIVE_ERROR;
            return returnValue;
        }
        else{
            returnValue = UNEXPECTED_ERROR;
            return returnValue;
        }
    }
}



H file H档

#ifndef smbusDriver
#define smbusDriver

#ifdef __cplusplus
 extern "C" {
#endif


#include "smbusDriver.h"
#include "stm32f0xx_hal_smbus.h"
#include "stm32f0xx_hal.h"


typedef union {
    struct{
        uint8_t configurationRegisterAddress;
        uint8_t FanStatusRegisterAddress;
        uint8_t FanStallRegisterAddress;
        uint8_t FanSpinRegisterAddress;
        uint8_t DriveFailStatusAddress;
        uint8_t FanInterruptEnableRegisterAddress;
        uint8_t PwmPolarityRegisterAddress;
        uint8_t PwmOutputTypeRegisterAddress;
        uint8_t PwmFrequency45Address;
        uint8_t PwmFrequency123Address;
        uint8_t PwmDivider1Address;
        uint8_t PwmDivider2Address;
        uint8_t PwmDivider3Address;
        uint8_t PwmDivider4Address;
        uint8_t PwmSettingAddress1;
        uint8_t PwmSettingAddress2;
        uint8_t PwmSettingAddress3;
        uint8_t PwmSettingAddress4;
    }Fields;

}addressValues_t;


typedef enum{
    NO_ERROR,
    DRIVE_FAIL_ERROR, // indicate that one or more fan could not be driven  (ProgrammingError)
    FAN_SPIN_ERROR,  //  indicate that one or more fan spin
    FAN_STALL_ERROR, //  indicate that one or more fan is stuck
    UNEXPECTED_ERROR
} generalStatus_t;

typedef enum {
    NO_STALL_ERROR,
    FAN_5_STALL_ERROR,
    FAN_4_STALL_ERROR,
    FAN_3_STALL_ERROR,
    FAN_2_STALL_ERROR,
    FAN_1_STALL_ERROR,
    UNEXPECTED_STALL_ERROR
} specialFanStallStatus_t;

typedef enum {
    NO_SPIN_ERROR,
    FAN_5_SPIN_ERROR,
    FAN_4_SPIN_ERROR,
    FAN_3_SPIN_ERROR,
    FAN_2_SPIN_ERROR,
    FAN_1_SPIN_ERROR,
    UNEXPECTED_SPIN_ERROR
} specialFanSpinStatus_t;

typedef enum {
    NO_DRIVE_ERROR,
    FAN_5_DRIVE_ERROR,
    FAN_4_DRIVE_ERROR,
    FAN_3_DRIVE_ERROR,
    FAN_2_DRIVE_ERROR,
    FAN_1_DRIVE_ERROR,
    UNEXPECTED_DRIVE_ERROR
} specialFanDriveStatus_t;







typedef enum{
    RESULT_OK,
    RESULT_ERROR,
    RESULT_TIMEOUT,
    RESULT_BUSY,
    RESULT_INVALID,
} resultConditions_t;

typedef union  {
    struct {
        uint8_t USECK       : 1; // 1 => External Clock  &  0 => Internal Clock
        uint8_t DRECK       : 1; // 1 => Clock pin output and push-pull driver 0 => Clock pin input
        uint8_t reserved    : 3;
        uint8_t WD_EN       : 1; // 1 => Watch clock is activated 0 => 0 watch clock is deactivated.
        uint8_t DIS_TO      : 1; // 1 => I2C is compatible 0 => SMBus time-out is enabled
        uint8_t MASK        : 1; // 1 => Alert is deactivated  0 => Alert is activated
        } Fields;
    uint8_t value;
} configuration_t;

typedef union  {
    struct
    {
        uint8_t  FNSTL      : 1; // stall error <=> 1
        uint8_t  FNSPIN     : 1; // Spin up error <=> 1
        uint8_t  DVFAIL     : 1; // Maximum speed PWM error <=> 1
        uint8_t  reserved   : 5;
    }Fields;
    uint8_t value;
}FanStatusRegister_t;

typedef union  {
    struct {
        uint8_t F1STL       : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
        uint8_t F2STL       : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
        uint8_t F3STL       : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
        uint8_t F4STL       : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
        uint8_t F5STL       : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
        uint8_t reserved    : 3; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
    } Fields;
    uint8_t value;
} FanStallStatusRegister_t;


typedef union {
    struct {
        uint8_t F1SPIN      : 1; // spin start error <=> 1
        uint8_t F2SPIN      : 1; // spin start error <=> 1
        uint8_t F3SPIN      : 1; // spin start error <=> 1
        uint8_t F4SPIN      : 1; // spin start error <=> 1
        uint8_t F5SPIN      : 1; // spin start error <=> 1
        uint8_t reserved    : 3; // spin start error <=> 1
    } Fields;
    uint8_t value;
}FanSpinStatusRegister_t;

typedef union {
    struct{
        uint8_t DRVF1       : 1; // rpm error <=> 1
        uint8_t DRVF2       : 1; // rpm error <=> 1
        uint8_t DRVF3       : 1; // rpm error <=> 1
        uint8_t DRVF4       : 1; // rpm error <=> 1
        uint8_t DRVF5       : 1; // rpm error <=> 1
        uint8_t reserved    : 3; // rpm error <=> 1
    }Fields;
    uint8_t value;
} DriveFailStatus_t;

typedef union  {
    struct  {
        uint8_t F1ITEN      : 1; // Alert Fan 1 enable  <=> 1
        uint8_t F2ITEN      : 1; // Alert Fan 2 enable  <=> 1
        uint8_t F3ITEN      : 1; // Alert Fan 3 enable  <=> 1
        uint8_t F4ITEN      : 1; // Alert Fan 4 enable  <=> 1
        uint8_t F5ITEN      : 1; // Alert Fan 5 enable  <=> 1
        uint8_t reserved    : 3;
    }Fields;
    uint8_t value;
}FanInterruptEnableRegister_t;

typedef union  {
    struct {
        uint8_t PLRITY1     : 1; // FFh produce 100% duty cycle <=> 1
        uint8_t PLRITY2     : 1; // FFh produce 100% duty cycle <=> 1
        uint8_t PLRITY3     : 1; // FFh produce 100% duty cycle <=> 1
        uint8_t PLRITY4     : 1; // FFh produce 100% duty cycle <=> 1
        uint8_t PLRITY5     : 1; // FFh produce 100% duty cycle <=> 1
        uint8_t reserved    : 3;
    }Fields;
    uint8_t value;
}PwmPolarityRegister_t;

typedef union  {
    struct {
        uint8_t PMOT1       : 1; // OpenDrain <=> 0 and PullPush output <=> 1
        uint8_t PMOT2       : 1; // OpenDrain <=> 0 and PullPush output <=> 1
        uint8_t PMOT3       : 1; // OpenDrain <=> 0 and PullPush output <=> 1
        uint8_t PMOT4       : 1; // OpenDrain <=> 0 and PullPush output <=> 1
        uint8_t PMOT5       : 1; // OpenDrain <=> 0 and PullPush output <=> 1
        uint8_t reserved    : 3;
    } Fields;
    uint8_t value;
} PwmOutputTypeRegister_t;
typedef union  {
    struct {
        uint8_t PwmFrequency4   : 2;
        uint8_t PwmFrequency5   : 2;
        uint8_t reserved        : 4;
    }Fields;
    uint8_t value;
}PwmFrequency45_t;

typedef union  {
    struct  {
        uint8_t PwmFrequency1   : 2;
        uint8_t PwmFrequency2   : 2;
        uint8_t PwmFrequency3   : 2;
        uint8_t reserved        : 2;
    }Fields;
    uint8_t value;
}PwmFrequency123_t;

typedef union {
    struct {
        uint8_t DriveSetting_1: 8;
        uint8_t DriveSetting_2: 8;
        uint8_t DriveSetting_3: 8;
        uint8_t DriveSetting_4: 8;
    }Fields;
        uint32_t value;
}CurrentDriveSettings_t;

typedef union {
    struct{
        uint8_t pwmDivider_1 :8;
        uint8_t pwmDivider_2 :8;
        uint8_t pwmDivider_3 :8;
        uint8_t pwmDivider_4 :8;
    }Fields;
        uint32_t value;
}PwmDividerRegister_t;

typedef union{
    struct {
        uint8_t pwmSettings1 :8;
        uint8_t pwmSettings2 :8;
        uint8_t pwmSettings3 :8;
        uint8_t pwmSettings4 :8;
    }Fields;
}PwmSettings_t;



resultConditions_t InitializeDriver(SMBUS_HandleTypeDef *hsmbus, uint8_t address, addressValues_t *Daddress);
resultConditions_t setPwmConfig(uint8_t Pwm, addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address);
generalStatus_t getGeneralStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address);


#endif

Datasheet: https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/EMC2301-2-3-5-Data-Sheet-DS20006532A.pdf数据表: https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/EMC2301-2-3-5-Data-Sheet-DS20006532A.pdf

Estimation whether code is working or not估计代码是否有效

Firstly, I would recommend that you use STM's library AN4502 .首先,我建议您使用 STM 的库AN4502

  1. The difference between the master and the slave is the same as for the i2c bus.主从之间的区别与 i2c 总线相同。 All bus transfers are initialized by the master.所有总线传输都由主机初始化。
  2. I think there is not emulator of EMC2301.我认为没有EMC2301的仿真器。 But to test the bus you can use examples from the STM AN4502 .但要测试总线,您可以使用 STM AN4502中的示例。
  3. Your code won't work because the HAL_SMBUS_Master_Transmit_IT and HAL_SMBUS_Master_Receive_IT functions are called asynchronously and require you to wait for the execution to finish when you call two functions in a row, you will get the result HAL_BUSY .您的代码将无法运行,因为HAL_SMBUS_Master_Transmit_ITHAL_SMBUS_Master_Receive_IT函数是异步调用的,当您连续调用两个函数时需要等待执行完成,您将得到结果HAL_BUSY Use the library AN4502 , it will make it easier to interact with the peripheral.使用库AN4502 ,它将更容易与外围设备交互。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM