如何对MAX14915/16进行编程 - 8通道高边开关

描述

MAX14915为8通道高边开关。它支持8通道驱动1A。微控制器兼容型串行外设接口(SPI)提供对许多诊断功能的访问。本应用笔记提供了C代码实现示例,包括设置、监控和诊断功能。

介绍

MAX14915/MAX14916集成8个高边开关,提供输出通道数、限流和诊断功能等特性。MAX14915为八通道高边开关,具有丰富的诊断功能和每通道1A (典型值)电流限值。MAX14916可配置为八通道高边开关(1A限流)或四通道高边开关(2A限流)。这些器件具有单独的通道热保护、用于快速感应退磁的内部箝位以及用于开和关状态的开路检测。此外,还有一个集成的发光二极管(LED)矩阵,可显示每个通道的状态(开/关)以及故障条件。

本应用笔记介绍了一系列功能,为MAX14915/6编程提供简单且经过验证的解决方案(图1)。它们是用C语言编写的,应该很容易移植到任何常见的微控制器上。有关MAX14915引脚、工作模式和控制寄存器的详细信息,请参考MAX14915数据资料。有关MAX14916引脚、工作模式和控制寄存器的详细信息,请参考MAX14916数据资料。

本应用笔记主要展示了MAX14915的编程,但MAX14916的技术非常相似。

SPI

图1.MAX14915功能框图

MAX14915 SPI

MAX14915 SPI命令长度为16位(8位指令+8位数据),CRC禁用,如果使能CRC,则CRC8将增加8位。命令字节的 2 MSB 是芯片地址位,它们允许 4 个芯片共享相同的芯片选择 (CS) 引脚。 SPI 命令结构如表 1 所示。MAX14915的SPI模式为CPOL = 0 (CLK空闲= 0),CPHA = 0 (上升沿/第一沿对数据进行采样),数据/命令需要先以MSB时钟。

 

芯片地址 突发位 注册 -
地址
R/W 数据
2 位
A[1:0]
1 位
BRST[0]
4 位
R[3:0]
MSB 至 LSB
1 位
RW[0]
8 位
D[7:0]
MSB 至 LSB

 

有关SPI读写周期以及寄存器表和指令的更多详细信息,请参考MAX14915和MAX14916数据资料。

图1所示为MAX14915的主要功能块。基本上,有8个输出通道高边驱动器、看门狗和诊断、一个16个LED(4x4)矩阵驱动器和逻辑端接口(SPI端口),用于访问所有器件寄存器和硬件标志以进行诊断。

MAX14915 – 代码应用示例

MAX14915设计用于支持终端设备的工业应用,如需要多个高边开关的可编程逻辑控制器(PLC)。支持16通道组隔离的典型应用电路采用单个MAX14483数字隔离器,如图2所示。

SPI

图2.16通道高边开关组隔离。

每个单独的输出可以驱动高达 1A 的电流,并具有单独的开路、过流和过温诊断

为了简化需要电流隔离的系统,MAX14915支持菊花链和寻址SPI模式。

注意: 某些诊断功能仅在直接 SPI 或寻址 SPI 模式下可用,但在菊花链模式下不可用。详情请参考MAX14915数据资料。

源代码

本应用笔记提供了C源代码示例,主要提供驱动器功能,用于访问MAX14915中的多个寄存器,以实现配置、控制和诊断功能。所有软件均使用MAX14915评估板进行实现和测试。客户应仅将本文档中的功能用作参考,并根据其应用程序中的微控制器和硬件实现设计自己的固件/软件。

寄存器地址定义:

 

#define REG_SetOUT       0x00
#define REG_SetFLED      0x01
#define REG_SetSLED      0x02
#define REG_Interupt     0x03
#define REG_OvlChF       0x04
#define REG_CurrLimF     0x05
#define REG_OwOffChF     0x06
#define REG_OwOnChF      0x07
#define REG_ShtVDDChF    0x08
#define REG_GlobalErr    0x09
#define REG_OwOffEn      0x0a
#define REG_OwOnEn       0x0b
#define REG_ShtVddEn     0x0c
#define REG_Config1      0x0d
#define REG_Config2      0x0e
#define REG_Mask         0x0f

其他定义:

#define OUT1             0x01
#define OUT2             0x02
#define OUT3             0x04
#define OUT4             0x08
#define OUT5             0x10
#define OUT6             0x20
#define OUT7             0x40
#define OUT8             0x80

#define GLB_ShrtVDD      0x20
#define GLB_OWOnF        0x10
#define GLB_OWOffF       0x08
#define GLB_CurrLim      0x04
#define GLB_OverLdF      0x02
#define GLB_GloblF       0x01

bool CRC_Enabled = true;             // if pin CRCEN = high, then this must be true
//bool CRC_Enabled = false;            // if pin CRCEN = low, then this must be false
const int CRC_ERROR = 0xffff;
 

该测试程序等待MAX14915,直到它没有报告任何故障,例如在上电MAX14915报告上电复位条件之后。接下来,对MAX14915进行初始化,以便报告任何故障,作为典型上电自检程序的一部分,二进制计数器在8个通道上运行并打印故障条件。

 

void test()
{
  uint8_t ADR = 0;                   // MAX14915 Chip-Address Allows multiple Chips with 1 Chip-Select
  uint16_t loop_count = 0;

  // Check status, only continue if All OK.
  uint16_t fault = 0xffff;
  while (fault != 0)                 // Halt until MAX14915 has no faults
  {
	  fault = MAX14915_Init(ADR);
	  if ( (fault) != 0) MAX14915_Identify_Error(ADR, fault);  // check for errors if any bit is set
  }

  // Writes a binary counter to the 8 Ports
  // Checks for any errors and prints them
  while (1)
  {
	  printf("Writing %i\r\n", loop_count);

	  uint16_t w_result = MAX14915_write_register(ADR, REG_SetOUT, loop_count);
	  w_result = w_result & 0x3fff;                                     // ignore the 2 MSBs, they're not used

	  printf("W-Result 0x%04x\r\n", w_result);
	  if ( (w_result) != 0) MAX14915_Identify_Error(ADR, w_result);     // only check if any bit is set

	  delay_ms(100);
	  loop_count++;
	  if (loop_count > 255) loop_count = 0;
  }
}
 

这些是初始化和使用MAX14915所需的功能,包括寄存器读写操作、CRC代码生成和解码以及错误标志轮询。

 

//********************************************************************
//*
//* Function: MAX14915_Init
//* Description: Initialize MAX14915
//*
//* Input:
//*         Chip_Address:     Chip address selected by pins A1 and A0
//*
//* Output, none
//*         Initializes the device after power-up
//*
//* if CRC is enabled, then crc5 is sent accordingly
//*
//********************************************************************/
uint16_t MAX14915_Init(uint8_t Chip_Address)
{
	// **********************************************************************************
	// *   D07   *   D06   *   D05   *   D04   **   D03   *   D02   *   D01   *   D00   *
	// * ComErrM *SuplErrM *  VddOKM * ShtVddM **  OWOnM  *  OWOffM * OWOffM  * OverLdM *
	// *    1    *    0    *    0    *    0    **    0    *    0    *    0    *    0    *
	// **********************************************************************************
	// -> 0x80   // All warnings enabled, just Watchdog off
	uint16_t result = MAX14915_write_register(Chip_Address, REG_Mask, 0x80);

	// **********************************************************************************
	// *   D07   *   D06   *   D05   *   D04   **   D03   *   D02   *   D01   *   D00   *
	// * LEDCLim * FLatchEn*FiltrLong*FFilterEn**FLEDStr1 *FLEDStr0 * SLEDSet * FLEDSet *
	// *    0    *    1    *    0    *    1    **    0    *    0    *    0    *    0    *
	// **********************************************************************************
	// -> 0x50   // Enable Status and Fault LEDs
	             // Keep Fault-Latch and Filter-Blanking on
	result |= MAX14915_write_register(Chip_Address, REG_Config1, 0x50);

	// enable Open-Wire when off detection on all Channels
	// this only works if a load is connected on all channels
	// Maybe should be handled by the Application?
	result |= MAX14915_write_register(Chip_Address, REG_OwOffEn, 0xff);

	// enable Open-Wire when on detection on all Channels
	// this only works if a load is connected on all channels
	// Maybe should be handled by the Application?
	result |= MAX14915_write_register(Chip_Address, REG_OwOnEn, 0xff);

	// enable Short to VDD detection on all Channels
	// this only works if a load is connected on all channels
	// Maybe should be handled by the Application?
	result |= MAX14915_write_register(Chip_Address, REG_ShtVddEn, 0xff);


	return result & 0x3fff; // discard the 2 MSBs, since they're unused
}
 
//********************************************************************
//*
//* Function: MAX14915_write_register
//* Description: Write one Register to MAX14915
//*
//* Input:
//*         Chip_Address:     Chip address selected by pins A1 and A0
//*         Register-Address  take from definitions in header-file
//*         data              Data to be written into the register
//*
//* Output, 16bit result:
//*         MSB 8-bits = Global Error uint8_t
//*         LSB 8-bits = Fault bits F8 to F1
//*
//* if CRC is enabled, then crc5 is sent accordingly
//*
//********************************************************************/
uint16_t MAX14915_write_register(uint8_t Chip_Address, uint8_t Register_Address, uint8_t data)
{
    // Construct the SPI uint8_t to transmit
    uint8_t  CHIP_ADR = (uint8_t) (Chip_Address<<6);       // 2 MSBs are the Chip Address (A1 and A0)
    uint8_t  BRST     = 0;                              // 0 = no burst read; 1 = burst read  -> 0x20 to set this bit
    uint8_t  R_ADR    = (uint8_t) (Register_Address<<1);   // Register Address

    uint8_t  command  = (uint8_t) (CHIP_ADR | BRST | R_ADR | 1); // construct SPI Command uint8_t. LSB = 1 for Write-Command
    // END Construct the SPI uint8_t to transmit

    MAX14915_CS_Low();
    // Write Command-uint8_t, Receive the Global Error uint8_t at the same time
    uint8_t GLOB_ERROR = MAX14915_SPI_RW_8bit(command);
    // Write Data-uint8_t, Receive the Individual Fault-Bits at the same time
    uint8_t FAULT_BITS = MAX14915_SPI_RW_8bit(data);

    if (CRC_Enabled == true)
    {
        uint8_t crc5_checksum;
        crc5_checksum = MAX14915_crc5_encode_2byte(command, data);
        MAX14915_SPI_RW_8bit(crc5_checksum);
    }
    MAX14915_CS_High();

    return (uint16_t) ((GLOB_ERROR << 8) | FAULT_BITS);;
}

 
//********************************************************************
//*
//* Function: MAX14915_read_register
//* Description: Read one Register from MAX14915
//*
//* Input:
//*         Chip_Address:     Chip address selected by pins A1 and A0
//*         Register-Address  take from definitions in header-file
//*         data              Data to be written into the register
//*
//*
//* Output, 16bit result:
//*         MSB 8-bits = Global Error uint8_t
//*         LSB 8-bits = Register content 8-bits
//*
//* if CRC is enabled and there was a CRC error, then Output is CRC_ERROR
//*
//********************************************************************/
uint16_t MAX14915_read_register (uint8_t Chip_Address, uint8_t Register_Address)
{
    // Construct the SPI uint8_t to transmit
    uint8_t  CHIP_ADR = (uint8_t) (Chip_Address<<6);       // 2 MSBs are the Chip Address (A1 and A0)
    uint8_t  BRST     = 0;                                 // 0 = no burst read; 1 = burst read  -> 0x20 to set this bit
    uint8_t  R_ADR    = (uint8_t) (Register_Address<<1);   // Register Address

    uint8_t  command  = (uint8_t) (CHIP_ADR | BRST | R_ADR); // construct SPI Command uint8_t. LSB = 0 for Read-Command
    // END Construct the SPI uint8_t to transmit

    MAX14915_CS_Low();
    // Write Command-uint8_t, Receive the Global Error uint8_t at the same time
    uint8_t GLOB_ERROR = MAX14915_SPI_RW_8bit(command);
    GLOB_ERROR = GLOB_ERROR & 0x3f;                      // Discard the 2 MSBs, they're not used

    // Write Data-uint8_t, Receive the Individual Fault-Bits at the same time
    uint8_t data       = MAX14915_SPI_RW_8bit(0);

    if (CRC_Enabled == true)
    {
        uint8_t crc5_read;
        uint8_t crc5_calc;

        crc5_calc = MAX14915_crc5_decode_2byte(GLOB_ERROR, data);
    	crc5_read = MAX14915_SPI_RW_8bit(MAX14915_crc5_encode_2byte(command,0));

    	if (crc5_read != crc5_calc) System_Handle_CRC_Error(Chip_Address);
    }
    MAX14915_CS_High();

    return (uint16_t) ((GLOB_ERROR << 8) | data);
}
 
//********************************************************************
//*
//* Function: MAX14915_crc5encode_2byte
//* Description: Generates CRC5 byte for 2 byte-Command
//*                        this is needed for WRITE commands
//*
//* Input:
//*         byte1:     Usually Command Byte
//*         byte2:     Byte written to MAX14915
//*
//* Output, 8bit result:
//*         CRC5 of the 2 Bytes
//*
//********************************************************************/
uint8_t MAX14915_crc5_encode_2byte(uint8_t byte1, uint8_t byte2)
{
    uint8_t crc5_start = 0x1f;
    uint8_t crc5_poly  = 0x15;
    uint8_t crc_result = crc5_start;

    // byte1
    for (int i=0; i<8; i++)
    {
        if( ((( byte1>>(7-i) )&0x01) ^ ((crc_result & 0x10)>>4)) > 0  )
        {
            crc_result = (uint8_t) (crc5_poly ^ ((crc_result<<1) & 0x1f));
        }
        else
        {
            crc_result = (uint8_t)((crc_result<<1) & 0x1f);
        }
    }
    // END byte1

    // byte2
    for (int i=0; i<8; i++)
    {
        if( ((( byte2>>(7-i) )&0x01) ^ ((crc_result & 0x10)>>4)) > 0  )
        {
            crc_result = (uint8_t) (crc5_poly ^ ((crc_result<<1) & 0x1f));
        }
        else
        {
            crc_result = (uint8_t)((crc_result<<1) & 0x1f);
        }
    }
    // END byte2

    // 3 extra bits set to zero
    uint8_t uint8_t3=0x00;
    for (int i=0; i<3; i++)
    {
        if( ((( uint8_t3>>(7-i) )&0x01) ^ ((crc_result & 0x10)>>4)) > 0  )
        {
            crc_result = (uint8_t) (crc5_poly ^ ((crc_result<<1) & 0x1f));
        }
        else
        {
            crc_result = (uint8_t)((crc_result<<1) & 0x1f);
        }
    }
    // END 3 extra bits set to zero

    return crc_result;
}
 
//********************************************************************
//*
//* Function: MAX14915_crc5_decode_2byte
//* Description: Decodes   CRC5 byte for 2 byte-Command
//*                        this is needed for READ commands
//*
//* Input:
//*         byte1:     Usually Command Byte
//*         byte2:     byte read from MAX14915
//*
//* Output, 8bit result:
//*         CRC5 of the 2 Bytes
//*
//********************************************************************/
uint8_t MAX14915_crc5_decode_2byte(uint8_t byte1, uint8_t byte2)
{
	uint8_t crc5_start = 0x1f;
	uint8_t crc5_poly  = 0x15;
	uint8_t crc_result = crc5_start;

    // BYTE1
    for (int i=2; i<8; i++)
    {
        if( ((( byte1>>(7-i) )&0x01) ^ ((crc_result & 0x10)>>4)) > 0  )  // IF(XOR(C6;BITAND(D5;2^4)/2^4)
        {  // BITXOR($D$1;BITAND((D5*2);31))
            crc_result = (uint8_t) (crc5_poly ^ ((crc_result<<1) & 0x1f));
        }
        else
        {
            crc_result = (uint8_t)((crc_result<<1) & 0x1f);
        }
    }
    // END BYTE1

    // BYTE2
    for (int i=0; i<8; i++)
    {
        if( ((( byte2>>(7-i) )&0x01) ^ ((crc_result & 0x10)>>4)) > 0  )  // IF(XOR(C6;BITAND(D5;2^4)/2^4)
        {  // BITXOR($D$1;BITAND((D5*2);31))
            crc_result = (uint8_t) (crc5_poly ^ ((crc_result<<1) & 0x1f));
        }
        else
        {
            crc_result = (uint8_t)((crc_result<<1) & 0x1f);
        }
    }
    // END BYTE2

    // 3 extra bits set to zero
    uint8_t byte3=0x00;
    for (int i=0; i<3; i++)
    {
        if( ((( byte3>>(7-i) )&0x01) ^ ((crc_result & 0x10)>>4)) > 0  )  // IF(XOR(C6;BITAND(D5;2^4)/2^4)
        {  // BITXOR($D$1;BITAND((D5*2);31))
            crc_result = (uint8_t) (crc5_poly ^ ((crc_result<<1) & 0x1f));
        }
        else
        {
            crc_result = (uint8_t)((crc_result<<1) & 0x1f);
        }
    }
    // END 3 extra bits set to zero

    return crc_result;
}

 
//********************************************************************
//*
//* Function: MAX14915_Identify_Error
//* Description: This should be called if one of the Global-Error bits
//*              or Fault bits is set
//*              This function identifies the error and calls
//*
//* Input:
//*         uint16_t:    MS-uint8_t = Global Errors from SPI transfer
//*                    LS-uint8_t = Channel Fault bits from SPI transfer
//*
//* Output:
//*         none, will call System Level function to handle the error
//*
//********************************************************************/
void MAX14915_Identify_Error(uint8_t Chip_Address, uint16_t ERROR_INFO)
{
    uint8_t   GlobalERR  = (uint8_t) ((ERROR_INFO>>8) & 0xff); // MSB 8-bits = Global Error uint8_t
    uint8_t   CH_FAULT   = (uint8_t) ((ERROR_INFO)    & 0xff); // LSB 8-bits = Fault bits F8 to F1

    if ((GlobalERR & GLB_GloblF)  != 0)   System_Handle_Global_fault(Chip_Address);

    // If no Channel Fault, then no further checking is needed:
    if (CH_FAULT == 0) return;

    // if only one single fault exists, then Error-Type is already known by Global_Error_uint8_t
    if ( (CH_FAULT == OUT1) ||
         (CH_FAULT == OUT2) ||
         (CH_FAULT == OUT3) ||
         (CH_FAULT == OUT4) ||
         (CH_FAULT == OUT5) ||
         (CH_FAULT == OUT6) ||
         (CH_FAULT == OUT7) ||
         (CH_FAULT == OUT8) )
    {
    	uint8_t ch_number = MAX14915_decode_channel_number(CH_FAULT);
        if ((GlobalERR & GLB_ShrtVDD) != 0)   System_Handle_Short_to_VDD_CH(ch_number, Chip_Address);
        if ((GlobalERR & GLB_OWOnF)   != 0)   System_Handle_OpenWire_CH(ch_number, Chip_Address);
        if ((GlobalERR & GLB_OWOffF)  != 0)   System_Handle_OpenWire_CH(ch_number, Chip_Address);
        if ((GlobalERR & GLB_CurrLim) != 0)   System_Handle_Current_Limit_CH(ch_number, Chip_Address);
        if ((GlobalERR & GLB_OverLdF) != 0)   System_Handle_Overload_CH(ch_number, Chip_Address);
    }
    else
    {   // there is more than 1 error present
        // so we need to check each channel

        // first read each Error Register:
        uint16_t OvlChF    = MAX14915_read_register (Chip_Address, REG_OvlChF);
        uint16_t CurrLim   = MAX14915_read_register (Chip_Address, REG_CurrLimF);
        uint16_t OwOffChF  = MAX14915_read_register (Chip_Address, REG_OwOffChF);
        uint16_t OwOnChF   = MAX14915_read_register (Chip_Address, REG_OwOnChF);
        uint16_t ShtVDDChF = MAX14915_read_register (Chip_Address, REG_ShtVDDChF);

        if ((OvlChF    & OUT1) != 0) System_Handle_Overload_CH(1, Chip_Address);
        if ((OvlChF    & OUT2) != 0) System_Handle_Overload_CH(2, Chip_Address);
        if ((OvlChF    & OUT3) != 0) System_Handle_Overload_CH(3, Chip_Address);
        if ((OvlChF    & OUT4) != 0) System_Handle_Overload_CH(4, Chip_Address);
        if ((OvlChF    & OUT5) != 0) System_Handle_Overload_CH(5, Chip_Address);
        if ((OvlChF    & OUT6) != 0) System_Handle_Overload_CH(6, Chip_Address);
        if ((OvlChF    & OUT7) != 0) System_Handle_Overload_CH(7, Chip_Address);
        if ((OvlChF    & OUT8) != 0) System_Handle_Overload_CH(8, Chip_Address);

        if ((CurrLim   & OUT1) != 0) System_Handle_Current_Limit_CH(1, Chip_Address);
        if ((CurrLim   & OUT2) != 0) System_Handle_Current_Limit_CH(2, Chip_Address);
        if ((CurrLim   & OUT3) != 0) System_Handle_Current_Limit_CH(3, Chip_Address);
        if ((CurrLim   & OUT4) != 0) System_Handle_Current_Limit_CH(4, Chip_Address);
        if ((CurrLim   & OUT5) != 0) System_Handle_Current_Limit_CH(5, Chip_Address);
        if ((CurrLim   & OUT6) != 0) System_Handle_Current_Limit_CH(6, Chip_Address);
        if ((CurrLim   & OUT7) != 0) System_Handle_Current_Limit_CH(7, Chip_Address);
        if ((CurrLim   & OUT8) != 0) System_Handle_Current_Limit_CH(8, Chip_Address);

        if ((OwOffChF  & OUT1) != 0) System_Handle_OpenWire_CH(1, Chip_Address);
        if ((OwOffChF  & OUT2) != 0) System_Handle_OpenWire_CH(2, Chip_Address);
        if ((OwOffChF  & OUT3) != 0) System_Handle_OpenWire_CH(3, Chip_Address);
        if ((OwOffChF  & OUT4) != 0) System_Handle_OpenWire_CH(4, Chip_Address);
        if ((OwOffChF  & OUT5) != 0) System_Handle_OpenWire_CH(5, Chip_Address);
        if ((OwOffChF  & OUT6) != 0) System_Handle_OpenWire_CH(6, Chip_Address);
        if ((OwOffChF  & OUT7) != 0) System_Handle_OpenWire_CH(7, Chip_Address);
        if ((OwOffChF  & OUT8) != 0) System_Handle_OpenWire_CH(8, Chip_Address);

        if ((OwOnChF   & OUT1) != 0) System_Handle_OpenWire_CH(1, Chip_Address);
        if ((OwOnChF   & OUT2) != 0) System_Handle_OpenWire_CH(2, Chip_Address);
        if ((OwOnChF   & OUT3) != 0) System_Handle_OpenWire_CH(3, Chip_Address);
        if ((OwOnChF   & OUT4) != 0) System_Handle_OpenWire_CH(4, Chip_Address);
        if ((OwOnChF   & OUT5) != 0) System_Handle_OpenWire_CH(5, Chip_Address);
        if ((OwOnChF   & OUT6) != 0) System_Handle_OpenWire_CH(6, Chip_Address);
        if ((OwOnChF   & OUT7) != 0) System_Handle_OpenWire_CH(7, Chip_Address);
        if ((OwOnChF   & OUT8) != 0) System_Handle_OpenWire_CH(8, Chip_Address);

        if ((ShtVDDChF & OUT1) != 0) System_Handle_Short_to_VDD_CH(1, Chip_Address);
        if ((ShtVDDChF & OUT2) != 0) System_Handle_Short_to_VDD_CH(2, Chip_Address);
        if ((ShtVDDChF & OUT3) != 0) System_Handle_Short_to_VDD_CH(3, Chip_Address);
        if ((ShtVDDChF & OUT4) != 0) System_Handle_Short_to_VDD_CH(4, Chip_Address);
        if ((ShtVDDChF & OUT5) != 0) System_Handle_Short_to_VDD_CH(5, Chip_Address);
        if ((ShtVDDChF & OUT6) != 0) System_Handle_Short_to_VDD_CH(6, Chip_Address);
        if ((ShtVDDChF & OUT7) != 0) System_Handle_Short_to_VDD_CH(7, Chip_Address);
        if ((ShtVDDChF & OUT8) != 0) System_Handle_Short_to_VDD_CH(8, Chip_Address);
    }
}

uint8_t MAX14915_decode_channel_number(uint8_t CH_binary)
{
    if ((CH_binary & OUT1) != 0) return 1;
    if ((CH_binary & OUT2) != 0) return 2;
    if ((CH_binary & OUT3) != 0) return 3;
    if ((CH_binary & OUT4) != 0) return 4;
    if ((CH_binary & OUT5) != 0) return 5;
    if ((CH_binary & OUT6) != 0) return 6;
    if ((CH_binary & OUT7) != 0) return 7;
    if ((CH_binary & OUT8) != 0) return 8;

    return 0;
}

这些功能显示了MAX14915的诊断特性。在此示例中,仅打印错误条件。真正的应用程序可能必须采取进一步的操作:

 

void System_Handle_Overload_CH(uint8_t Channel, uint8_t Chip_Address)
{
    // "Channel" is overloaded
    // System needs to handle over-load on "Channel"
    // Print to the User?
    // Just switch off?
    printf("MAX14915 %i - Channel %i is overloaded\r\n", Chip_Address, Channel);

    // Application actions

    MAX14915_read_register (Chip_Address, REG_OvlChF);  // read to clear the flag
                                                        // if error persists, the flag
                                                        // will come back immediately
}

void System_Handle_Current_Limit_CH(uint8_t Channel, uint8_t Chip_Address)
{
    // "Channel" is in current limiting mode
    // Does the system have to do anything in this case?
    // Print to the User?
    // Just switch off?
    printf("MAX14915 %i - Channel %i is in Current Limiting mode\r\n", Chip_Address, Channel);

    // Application actions

    MAX14915_read_register (Chip_Address, REG_CurrLimF); // read to clear the flag
                                                         // if error persists, the flag
                                                         // will come back immediately
}

void System_Handle_OpenWire_CH(uint8_t Channel, uint8_t Chip_Address)
{
    // "Channel" is open wire
    // Does the system have to do anything in this case?
    // Print to the User?
    printf("MAX14915 %i - Channel %i is Open Wire\r\n", Chip_Address, Channel);

    // Application actions

    MAX14915_read_register (Chip_Address, REG_OwOnChF);
    MAX14915_read_register (Chip_Address, REG_OwOffChF); // read to clear the flag
                                                         // if error persists, the flag
                                                         // will come back immediately
}

void System_Handle_Short_to_VDD_CH(uint8_t Channel, uint8_t Chip_Address)
{
    // "Channel" is shorted to VDD
    // Does the system have to do anything in this case?
    // Print to the User?
    // Just switch off?
    printf("MAX14915 %i - Channel %i is shorted to VDD\r\n", Chip_Address, Channel);

    // Application actions

    MAX14915_read_register (Chip_Address, REG_ShtVDDChF); // read to clear the flag
                                                          // if error persists, the flag
                                                          // will come back immediately
}

void System_Handle_Global_fault(uint8_t Chip_Address)
{
	// read Global Error Register
    uint16_t global_error = MAX14915_read_register (Chip_Address, REG_GlobalErr);

    if ((global_error & 0x02) != 0) printf("MAX14915 %i Logic Undervoltage\r\n", Chip_Address);
    if ((global_error & 0x04) != 0) printf("MAX14915 %i VDD not good (below 16V)\r\n", Chip_Address);
    if ((global_error & 0x08) != 0) printf("MAX14915 %i VDD warning (below 13V)\r\n", Chip_Address);
    if ((global_error & 0x10) != 0) printf("MAX14915 %i VDD Undervoltage (below 8V)\r\n", Chip_Address);
    if ((global_error & 0x20) != 0) printf("MAX14915 %i Thermal Shutdown\r\n", Chip_Address);
    if ((global_error & 0x40) != 0) printf("MAX14915 %i SYNCH Error\r\n", Chip_Address);
    if ((global_error & 0x80) != 0) printf("MAX14915 %i Watchdog Error\r\n", Chip_Address);

    if ((global_error & 0x01) != 0)
	{
    	// After a power-on reset all registers are in reset state
    	// -> we need to re-initialize to our settings
    	MAX14915_Init(Chip_Address);
    	printf("MAX14915 %i Power-up Reset detected\r\n", Chip_Address);
	}
}


void System_Handle_CRC_Error(uint8_t Chip_Address)
{
    // There was a CRC error
    printf("MAX14915 %i - CRC Error!\r\n", Chip_Address);

    // The Application needs to react here

    MAX14915_read_register (Chip_Address, REG_GlobalErr); // read to clear the flag
                                                          // if error persists, the flag
                                                          // will come back immediately
}

结论

本应用笔记介绍了如何对MAX14915进行编程以驱动输出和诊断故障条件。该代码使用MAX14915EVKIT进行测试。工程师可以使用本应用笔记中提到的C代码示例,快速轻松地实现常用微控制器和MAX14915之间的接口。

审核编辑:郭婷

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分