MAX14906為符合IEC 61131-2標(biāo)準(zhǔn)的高速、四通道工業(yè)數(shù)字輸出、數(shù)字輸入器件,可按通道配置為高邊(HS)開關(guān)、推挽(PP)驅(qū)動器、1、3型或2型數(shù)字輸入。SPI接口具有內(nèi)置芯片尋址解碼器,允許利用具有公共片選(CS)的共享SPI與多個MAX14906器件通信。SPI接口為全局和每通道配置和診斷提供了靈活性,包括電源過壓和欠壓檢測、斷線或開路檢測、熱過載和電流限制報告等。
本應(yīng)用筆記介紹了一系列功能,為MAX14906編程提供簡單且經(jīng)過驗證的解決方案(圖1)。它們是用C#編寫的,應(yīng)該很容易移植到任何常見的微控制器上。有關(guān)MAX14906引腳、工作模式、SPI命令和控制寄存器的詳細(xì)信息,請參考MAX14906數(shù)據(jù)資料。
圖1.MAX14906典型應(yīng)用電路
MAX14906 SPI
MAX14906具有高速SPI串行接口,最大時鐘速率為10MHz。SPI 接口遵循時鐘極性 CPOL = 0(SCLK 空閑 = 0)和時鐘相位 CPHA = 0(上升沿/第一沿對數(shù)據(jù)進(jìn)行采樣)。命令首先以最高有效位 (MSb) 計時。
MAX14906 SPI支持可尋址SPI,允許使用共享CS信號與多達(dá)14906個MAX1直接通信。地址引腳 A0 和 A1 用于配置器件地址。地址位 A0 和 A1 作為 SPI 讀寫命令的第一和第二位發(fā)送。器件監(jiān)視SPI命令,并在地址與A0和A<>引腳的狀態(tài)匹配時適當(dāng)?shù)仨憫?yīng)SDO。
MAX14906 SPI支持單周期模式和突發(fā)模式。單周期模式一次讀取或?qū)懭胍粋€寄存器,而突發(fā)模式允許在一個SPI周期內(nèi)讀取或?qū)懭攵鄠€連續(xù)寄存器。
單周期SPI命令的長度為16位(8位指令+ 8位數(shù)據(jù)),禁用CRC,如果啟用CRC,則會增加8位,包括5位CRC和3個前導(dǎo)零。命令字節(jié)的2 MSB為器件地址位(A1和A0),允許4個MAX14906共享相同的片選(CS)引腳。對于單周期模式,BRST 位設(shè)置為 0。設(shè)備在SDO上發(fā)送的數(shù)據(jù)報告設(shè)備故障情況,如果是寫入命令,則報告每個通道的狀態(tài),如果是讀取命令,則報告寄存器值。單周期讀寫圖如圖 2 至圖 5 所示。
圖2.SPI 單周期寫入命令,CRC 禁用。
圖3.SPI 單周期寫入命令,啟用 CRC。
圖4.SPI 單周期讀取命令,CRC 禁用。
圖5.SPI 單周期讀取命令,啟用 CRC。
突發(fā) SPI 命令使用一個 SPI 周期和一個寄存器地址寫入或讀取多個連續(xù)寄存器,并通過將 BRST 位設(shè)置為 1 來啟用。
突發(fā)寫入命令寫入 SetOUT 和 SetLED 寄存器,BRST = 1、R/W = 1 和 R[3:0] = 0。該命令包含兩個數(shù)據(jù)字節(jié),一個用于配置 SetOUT 寄存器,另一個用于配置 SetLED 寄存器。如果未啟用 CRC,則 SCLK 周期數(shù)為 24,如果啟用 CRC,則 SCLK 周期數(shù)為 32。SPI突發(fā)寫入圖如圖6和圖7所示。
突發(fā)讀取命令從地址0x02到0x07(DoiLevel、Interrupt、OvrLdChF、OpnWirChF、ShtVDDChF 和 GlobalErr 寄存器)檢索六個連續(xù)診斷寄存器的數(shù)據(jù),BRST = 1, R/W = 0, R[3:0] = 2。如果未啟用 CRC,則 SCLK 周期數(shù)為 56,如果啟用了 CRC,則 SCLK 周期數(shù)為 64。在突發(fā)讀取期間,SDI數(shù)據(jù)流中的數(shù)據(jù)位9至59可以是0或1,但如果啟用CRC,這些位用于計算CRC位。SPI突發(fā)讀取圖如圖8和圖9所示。
圖6.SPI 突發(fā)寫入命令,CRC 禁用。
圖7.SPI 突發(fā)寫入命令,已啟用 CRC。
圖8.SPI 突發(fā)讀取命令,CRC 已禁用。
圖9.SPI 突發(fā)讀取命令,已啟用 CRC。
有關(guān)SPI命令的更多詳細(xì)信息以及寄存器表和指令,請參考MAX14906數(shù)據(jù)資料。
MAX14906 - 代碼應(yīng)用示例
MAX14906設(shè)計用于支持終端設(shè)備的工業(yè)應(yīng)用,如可編程邏輯控制器(PLC),需要可配置的數(shù)字輸入(1/3型或2型)或數(shù)字輸出(高邊開關(guān)或推挽式驅(qū)動器)。典型應(yīng)用電路支持4通道組隔離,采用單個MAX14483數(shù)字隔離器,如圖1所示。
源代碼
本應(yīng)用筆記提供了C#源代碼示例,主要提供驅(qū)動器功能,用于訪問MAX14906中的多個寄存器,以實現(xiàn)配置、控制和診斷功能。所有軟件均使用MAX14906評估板進(jìn)行實現(xiàn)和測試。本應(yīng)用筆記中的功能用于MAX14906評估板軟件,用于處理MAX14906 SPI的基本讀寫命令。設(shè)計用于與MAX2232評估板硬件上的FT14906微控制器配合使用。本文檔不包括USB通信和低級FT2232功能。本文檔中也未包含圖形界面功能。
客戶應(yīng)僅將本文檔中的功能用作參考,并根據(jù)其應(yīng)用程序中的微控制器和硬件實現(xiàn)設(shè)計自己的固件/軟件。
單周期寫入
public void WriteRegister(int index) { if (index < 0 || index >= registers.Count) { return; } byte register = 0x00; byte[] txBuffer = new byte[2]; byte[] rxBuffer = new byte[2]; // Register Byte register = 0x01;// Write register |= (byte)(index << 1);// Register Address register |= (byte)(Address << 6);// Chip Address txBuffer[0] = register; // Data Byte txBuffer[1] = registers[index].Value; SPIWriteRead(txBuffer, ref rxBuffer, 2); // Store Fault Data SDOFaults.SHTVDD = ((rxBuffer[0] & 0x20) >> 5); SDOFaults.AbvVDD = ((rxBuffer[0] & 0x10) >> 4); SDOFaults.OWOffF = ((rxBuffer[0] & 0x08) >> 3); SDOFaults.OvrCurr = ((rxBuffer[0] & 0x04) >> 2); SDOFaults.OvldF = ((rxBuffer[0] & 0x02) >> 1); SDOFaults.GLOBLF = (rxBuffer[0] & 0x01); SDOFaults.ChannelFaults = rxBuffer[1]; // If successful, clean up registers[index].Modified = false; }
單周期讀取
public void ReadRegister(int index) { if (index < 0 || index >= registers.Count) { return; } FTDI.FT_STATUS ftStatus; byte register = 0x00; byte[] txBuffer = new byte[2]; byte[] rxBuffer = new byte[2]; // Register Byte register = 0x00;// Read register |= (byte)(index << 1);// Register Address register |= (byte)(Address << 6);// Chip Address txBuffer[0] = register; // Data Byte txBuffer[1] = 0x00; ftStatus = SPIWriteRead(txBuffer, ref rxBuffer, 2); if (ftStatus == FTDI.FT_STATUS.FT_OK) { registers[index].Value = rxBuffer[1]; } // Store Fault Data SDOFaults.SHTVDD = ((rxBuffer[0] & 0x20) >> 5); SDOFaults.AbvVDD = ((rxBuffer[0] & 0x10) >> 4); SDOFaults.OWOffF = ((rxBuffer[0] & 0x08) >> 3); SDOFaults.OvrCurr = ((rxBuffer[0] & 0x04) >> 2); SDOFaults.OvldF = ((rxBuffer[0] & 0x02) >> 1); SDOFaults.GLOBLF = (rxBuffer[0] & 0x01); //SDOFaults.ChannelFaults = rxBuffer[1];// Not Valid, bc on read this is register data // If successful, clean up registers[index].Modified = false; }
突發(fā)寫入
public void BurstWriteRegisters(int startIndex, int endIndex) { // Typically always 0 and 1 only if (endIndex < startIndex) { return; } if (startIndex < 0) { return; } if (endIndex >= registers.Count) { return; } int byteCount = (endIndex - startIndex) + 2; byte register = 0x00; byte[] txBuffer = new byte[byteCount]; byte[] rxBuffer = new byte[byteCount]; // Register Byte register = 0x01;// Write register |= (byte)(startIndex << 1);// Register Address register |= (byte)(Address << 6);// Chip Address register |= (byte)(0x01 << 5);// Burst txBuffer[0] = register; // Data Byte for (int x = 0; x < (byteCount - 1); x++) { txBuffer[1 + x] = registers[startIndex + x].Value; registers[startIndex + x].Modified = false; } SPIWriteRead(txBuffer, ref rxBuffer, byteCount); // Store Fault Data SDOFaults.SHTVDD = ((rxBuffer[0] & 0x20) >> 5); SDOFaults.AbvVDD = ((rxBuffer[0] & 0x10) >> 4); SDOFaults.OWOffF = ((rxBuffer[0] & 0x08) >> 3); SDOFaults.OvrCurr = ((rxBuffer[0] & 0x04) >> 2); SDOFaults.OvldF = ((rxBuffer[0] & 0x02) >> 1); SDOFaults.GLOBLF = (rxBuffer[0] & 0x01); SDOFaults.ChannelFaults = rxBuffer[1]; }
突發(fā)讀取
public void BurstReadRegisters(int startIndex, int endIndex) { if (endIndex < startIndex) { return; } if (startIndex < 0) { return; } if (endIndex >= registers.Count) { return; } FTDI.FT_STATUS ftStatus; int byteCount = (endIndex - startIndex) + 2; byte register = 0x00; byte[] txBuffer = new byte[byteCount]; byte[] rxBuffer = new byte[byteCount]; // Register Byte register = 0x00;// Read register |= (byte)(startIndex << 1);// Register Address register |= (byte)(Address << 6);// Chip Address register |= (byte)(0x01 << 5);// Burst txBuffer[0] = register; // Data Byte for (int x = 0; x < (byteCount - 1); x++) { txBuffer[1 + x] = 0x00; } ftStatus = SPIWriteRead(txBuffer, ref rxBuffer, byteCount); if (ftStatus == FTDI.FT_STATUS.FT_OK) { for (int x = 0; x < (byteCount - 1); x++) { registers[startIndex + x].Value = rxBuffer[1 + x]; registers[startIndex + x].Modified = false; } } // Store Fault Data SDOFaults.SHTVDD = ((rxBuffer[0] & 0x20) >> 5); SDOFaults.AbvVDD = ((rxBuffer[0] & 0x10) >> 4); SDOFaults.OWOffF = ((rxBuffer[0] & 0x08) >> 3); SDOFaults.OvrCurr = ((rxBuffer[0] & 0x04) >> 2); SDOFaults.OvldF = ((rxBuffer[0] & 0x02) >> 1); SDOFaults.GLOBLF = (rxBuffer[0] & 0x01); }
CRC 計算
private CRC8 crc8 = new CRC8(0x15, 0x1F); class CRC8 { private readonly byte POLY = 0x00; private readonly byte START_VALUE = 0x00; public CRC8(byte poly, byte startValue = 0x00) { this.POLY = poly; this.START_VALUE = startValue; } public byte ComputeChecksum3MSB(byte[] bytes) { byte remainder = START_VALUE; byte min = 0; for (int bite = 0; bite < bytes.Length; ++bite) { // For MAX14906 it does 8/16bits plus the 3 "0" MSBs of check byte if (bite == (bytes.Length - 1)) { min = 5; } for (byte bit = 8; bit > min; --bit) { remainder = (((bytes[bite] >> (bit - 1) & 0x01) ^ ((remainder >> 4) & 0x01)) > 0) ? (byte)((remainder << 1) ^ POLY) : (byte)(remainder << 1); } } return (byte)(remainder & 0x1F); } }
為每個通道配置操作模式的示例
public void SendModeAndSetting(int channel, int mode, int setting) { if (channel < 1 || channel > 4) { return; } if (mode < 0 || mode > 2) { return; } if (((mode == 1) && (setting < 0 || setting > 4)) || ((mode == 0) && (setting < 0 || setting > 2)) || (mode == 2 && setting != 0)) { return; } byte register = 0x00; byte data = 0x00; byte[] txBuffer = new byte[2]; byte[] rxBuffer = new byte[2]; if (mode == 0 || mode == 2)// Input or Low-leakage { //////////////////////////// // Reg 0x00: /////////////////////////// // Register Byte register = 0x01;// Write register |= (0x00 << 1);// Register Address register |= (byte)(Address << 6);// Chip Address txBuffer[0] = register; // Data Byte // Set current bit mode from FTDI byte temp = 0x00; // Remember bit logic for FTDI input/output inverted from MAX14906 Reg 0x00 temp = (byte)((~FTDI_ADBUS_MODE & 0x80) >> 7);// DIO1 data |= (byte)(temp << 4); temp = (byte)((~FTDI_ACBUS_MODE & 0x01));// DIO2 data |= (byte)(temp << 5); temp = (byte)((~FTDI_ACBUS_MODE & 0x02) >> 1);// DIO3 data |= (byte)(temp << 6); temp = (byte)((~FTDI_ACBUS_MODE & 0x04) >> 2);// DIO4 data |= (byte)(temp << 7); // New Mode to Set temp = (byte)(0x01 << (channel + 3)); data = (mode == 0 || mode == 2) ? (byte)(temp | data) : (byte)(~temp & data); txBuffer[1] = data; SPIWriteRead(txBuffer, ref rxBuffer, 2); //////////////////////////// // Reg 0x0C: /////////////////////////// // Register Byte register = 0x00;// Read register |= (0x0C << 1);// Register Address register |= (byte)(Address << 6);// Chip Address txBuffer[0] = register; // Get Current Data from Reg 0x0C SPIWriteRead(txBuffer, ref rxBuffer, 2); temp = rxBuffer[1]; // Register Byte register = 0x01;// Write register |= (0x0C << 1);// Register Address register |= (byte)(Address << 6);// Chip Address txBuffer[0] = register; // Data Byte data = (setting == 1) ? (byte)(temp | 0x80) : (byte)(temp & ~0x80);// Type 2 IEC Mode, Note this forces all DI to be in this mode txBuffer[1] = data; SPIWriteRead(txBuffer, ref rxBuffer, 2); //////////////////////////// // Reg 0x0D: /////////////////////////// // Register Byte register = 0x01;// Write register |= (0x0D << 1);// Register Address register |= (byte)(Address << 6);// Chip Address txBuffer[0] = register; // Data Byte data = (byte)(DO_Settings & ~(0x03 << (channel - 1) * 2));// Whether any setting (Normal, IEC 2, or Low-leakage) zero out both bits if (mode == 2)// Low-leakage { data |= (byte)(0x02 << (channel - 1) * 2);// For Low-leakage DI must set PP } DO_Settings = data; txBuffer[1] = data; SPIWriteRead(txBuffer, ref rxBuffer, 2); } else// Output { //////////////////////////// // Reg 0x00: /////////////////////////// // Register Byte register = 0x01;// Write register |= (0x00 << 1);// Register Address register |= (byte)(Address << 6);// Chip Address txBuffer[0] = register; // Data Byte // Set current bit mode from FTDI byte temp = 0x00; // Remember bit logic for FTDI input/output inverted from MAX14906 Reg 0x00 temp = (byte)((~FTDI_ADBUS_MODE & 0x80) >> 7);// DIO1 data |= (byte)(temp << 4); temp = (byte)((~FTDI_ACBUS_MODE & 0x01));// DIO2 data |= (byte)(temp << 5); temp = (byte)((~FTDI_ACBUS_MODE & 0x02) >> 1);// DIO3 data |= (byte)(temp << 6); temp = (byte)((~FTDI_ACBUS_MODE & 0x04) >> 2);// DIO4 data |= (byte)(temp << 7); // New Mode to Set temp = (byte)(0x01 << (channel + 3)); data = (mode == 0) ? (byte)(temp | data) : (byte)(~temp & data); txBuffer[1] = data; SPIWriteRead(txBuffer, ref rxBuffer, 2); //////////////////////////// // Reg 0x0D: /////////////////////////// // Register Byte register = 0x01;// Write register |= (0x0D << 1);// Register Address register |= (byte)(Address << 6);// Chip Address txBuffer[0] = register; // Data Byte data = (byte)(DO_Settings & ~(0x03 << (channel - 1) * 2));// Whether any setting (HS, HS 2x, PP clamp, PP low) zero out both bits data |= (byte)(setting << (channel - 1) * 2); DO_Settings = data;// Update settings txBuffer[1] = data; SPIWriteRead(txBuffer, ref rxBuffer, 2); } // Store Fault Data SDOFaults.SHTVDD = ((rxBuffer[0] & 0x20) >> 5); SDOFaults.AbvVDD = ((rxBuffer[0] & 0x10) >> 4); SDOFaults.OWOffF = ((rxBuffer[0] & 0x08) >> 3); SDOFaults.OvrCurr = ((rxBuffer[0] & 0x04) >> 2); SDOFaults.OvldF = ((rxBuffer[0] & 0x02) >> 1); SDOFaults.GLOBLF = (rxBuffer[0] & 0x01); SDOFaults.ChannelFaults = rxBuffer[1]; }
結(jié)論
本應(yīng)用筆記介紹了如何對MAX14906進(jìn)行編程,以監(jiān)測輸入、驅(qū)動輸出和診斷故障條件。該代碼使用MAX14906EVKIT#進(jìn)行測試。工程師可以使用本應(yīng)用筆記中提到的C代碼示例,快速輕松地實現(xiàn)常用微控制器和MAX14906之間的接口。
審核編輯:郭婷
-
微控制器
+關(guān)注
關(guān)注
48文章
7649瀏覽量
152103 -
驅(qū)動器
+關(guān)注
關(guān)注
53文章
8271瀏覽量
147056 -
SPI
+關(guān)注
關(guān)注
17文章
1721瀏覽量
92116
發(fā)布評論請先 登錄
相關(guān)推薦
四通道數(shù)字電源控制器
Maxim推出高精度四通道數(shù)字電源控制器MAX16064
MAX4940, MAX4940A 雙/四通道、單/雙極性、
MAX4940, MAX4940A 高度集成的四通道/雙通道
MAX9530 四通道NTSC/PAL解碼器和四通道音頻編碼
SSM2529: 小型、3.75 kVRMS、四通道數(shù)字隔離器數(shù)據(jù)手冊
![SSM2529: 小型、3.75 kVRMS、<b class='flag-5'>四通道</b><b class='flag-5'>數(shù)字</b>隔離器數(shù)據(jù)手冊](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
使用數(shù)字I/O IC簡化您的PLC設(shè)計
納芯微推出集成限流功能的四通道/八通道數(shù)字輸入(DI)隔離器NSi860x
MAX14906: Quad-Channel Industrial Digital Output, Digital Input Data Sheet MAX14906: Quad-Channel Industrial Digital Output, Digital Input D
![<b class='flag-5'>MAX14906</b>: Quad-Channel Industrial Digital Output, Digital Input Data Sheet <b class='flag-5'>MAX14906</b>: Quad-Channel Industrial Digital Output, Digital Input D](http://www.solar-ruike.com.cn/uploads/190218/2927106-1Z21P94211255.png)
MAX14906PMB: Evaluation Kit for the MAX14906 Data Sheet MAX14906PMB: Evaluation Kit for the MAX14906 Data Sheet
![<b class='flag-5'>MAX14906</b>PMB: Evaluation Kit for the <b class='flag-5'>MAX14906</b> Data Sheet <b class='flag-5'>MAX14906</b>PMB: Evaluation Kit for the <b class='flag-5'>MAX14906</b> Data Sheet](http://www.solar-ruike.com.cn/uploads/190218/2927106-1Z21P94211255.png)
MAX14906EVKIT: Evaluation Kit for the MAX14906 Data Sheet MAX14906EVKIT: Evaluation Kit for the MAX14906 Data Sheet
![<b class='flag-5'>MAX14906</b>EVKIT: Evaluation Kit for the <b class='flag-5'>MAX14906</b> Data Sheet <b class='flag-5'>MAX14906</b>EVKIT: Evaluation Kit for the <b class='flag-5'>MAX14906</b> Data Sheet](http://www.solar-ruike.com.cn/uploads/190218/2927106-1Z21P94211255.png)
新品 | 用于工業(yè)和汽車應(yīng)用的ISOFACE?四通道數(shù)字隔離器
![新品 | 用于<b class='flag-5'>工業(yè)</b>和汽車應(yīng)用的ISOFACE?<b class='flag-5'>四通道</b><b class='flag-5'>數(shù)字</b>隔離器](https://file.elecfans.com/web2/M00/3F/DB/pYYBAGJqOMiAUmBUAAAUKS9OY54015.jpg)
ISO67xx三通道和四通道數(shù)字隔離器評估模塊
![ISO67xx三<b class='flag-5'>通道</b>和<b class='flag-5'>四通道</b><b class='flag-5'>數(shù)字</b>隔離器評估模塊](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論