C# 控制CH341進行SPI,I2C讀寫

以前看了別人是C++ MFC開發的CH341 I2C,SPI讀寫flash的軟件代碼,看上去有點頭暈,感受仍是使用C# winform開發更人性化些html

C#控制須要調用CH341提供的DLL庫,網上多數是ch341.dll,我這裏使用的是USBIOX.DLL(內容基本上是相同的),有須要的能夠到下面網盤地址下載數組

連接: https://pan.baidu.com/s/1-PafH2pX1A9DvEprGciXRw 提取碼: uqdh 併發

調用類函數:異步

 1 using System;  2 using System.Collections.Generic;  3 using System.Text;  4 using System.Runtime.InteropServices;  5 
 6 
 7 namespace Burner  8 {  9     /* mUSB_SETUP_PKT結構體C++定義以下  10  typedef struct _USB_SETUP_PKT { // USB控制傳輸的創建階段的數據請求包結構  11  UCHAR mUspReqType; // 00H 請求類型  12  UCHAR mUspRequest; // 01H 請求代碼  13  union {  14  struct {  15  UCHAR mUspValueLow; // 02H 值參數低字節  16  UCHAR mUspValueHigh; // 03H 值參數高字節  17  };  18  USHORT mUspValue; // 02H-03H 值參數  19  };  20  union {  21  struct {  22  UCHAR mUspIndexLow; // 04H 索引參數低字節  23  UCHAR mUspIndexHigh; // 05H 索引參數高字節  24  };  25  USHORT mUspIndex; // 04H-05H 索引參數  26  };  27  USHORT mLength; // 06H-07H 數據階段的數據長度  28  } mUSB_SETUP_PKT, *mPUSB_SETUP_PKT;  29     */
 30 
 31     [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Size = 8)]  32     public struct mUSB_SETUP_PKT  33     {               // USB控制傳輸的創建階段的數據請求包結構
 34         [FieldOffset(0)]  35         public byte mUspReqType;                // 00H 請求類型
 36         [FieldOffset(1)]  37         public byte mUspRequest;                // 01H 請求代碼
 38 
 39         [FieldOffset(2)]  40         public byte mUspValueLow;               // 02H 值參數低字節
 41         [FieldOffset(3)]  42         public byte mUspValueHigh;              // 03H 值參數高字節
 43         [FieldOffset(2)]  44         public UInt16 mUspValue;                    // 02H-03H 值參數
 45 
 46         [FieldOffset(4)]  47         public byte mUspIndexLow;               // 04H 索引參數低字節
 48         [FieldOffset(5)]  49         public byte mUspIndexHigh;              // 05H 索引參數高字節
 50         [FieldOffset(4)]  51         public UInt16 mUspIndex;                    // 04H-05H 索引參數
 52         [FieldOffset(6)]  53         public UInt16 mLength;                  // 06H-07H 數據階段的數據長度
 54  }  55 
 56 
 57     /*
 58  mWIN32_COMMAND結構體C++定義以下  59 
 60  typedef struct _WIN32_COMMAND { // 定義WIN32命令接口結構  61  union {  62  ULONG mFunction; // 輸入時指定功能代碼或者管道號  63  NTSTATUS mStatus; // 輸出時返回操做狀態  64  };  65  ULONG mLength; // 存取長度,返回後續數據的長度  66  union {  67  mUSB_SETUP_PKT mSetupPkt; // USB控制傳輸的創建階段的數據請求  68  UCHAR mBuffer[ mCH341_PACKET_LENGTH ]; // 數據緩衝區,長度爲0至255B  69  };  70  } mWIN32_COMMAND, *mPWIN32_COMMAND;  71 
 72  C#中union功能由FieldOffset()代替  73 
 74  因爲上述結構體中最後一個union可能引發錯誤「對象字段由一個非對象字段不正確地對齊或重疊」  75  所以將上述結構體拆分紅2個結構體mWIN32_COMMAND_USB_SETUP_PKT與mWIN32_COMMAND_mBuffer,選其一便可。  76  CH341DriverCommand函數將重載  77    */
 78 
 79     [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]  80     public struct mWIN32_COMMAND_USB_SETUP_PKT  81     {               // 定義WIN32命令接口結構
 82         [FieldOffset(0)]  83         public UInt32 mFunction;                    // 輸入時指定功能代碼或者管道號
 84         [FieldOffset(0)]  85         public Int32 mStatus;                   // 輸出時返回操做狀態
 86         [FieldOffset(4)]  87         public UInt32 mLength;                  // 存取長度,返回後續數據的長度
 88         [FieldOffset(8)]  89         public mUSB_SETUP_PKT mSetupPkt;                // USB控制傳輸的創建階段的數據請求
 90  }  91 
 92     [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]  93     public struct mWIN32_COMMAND_mBuffer  94     {               // 定義WIN32命令接口結構
 95         [FieldOffset(0)]  96         public UInt32 mFunction;                    // 輸入時指定功能代碼或者管道號
 97         [FieldOffset(0)]  98         public Int32 mStatus;                   // 輸出時返回操做狀態
 99         [FieldOffset(4)] 100         public UInt32 mLength;                  // 存取長度,返回後續數據的長度
101 
102         [MarshalAs(UnmanagedType.ByValArray, SizeConst = USBIOXdll.mCH341_PACKET_LENGTH), FieldOffset(8)] 103         public byte[] mBuffer;  // 數據緩衝區,長度爲0至255B
104 
105  } 106 
107 
108     class USBIOXdll 109  { 110         public const int mCH341_PACKET_LENGTH = 32;// CH341支持的數據包的長度
111         public const int mCH341_PKT_LEN_SHORT = 8;//CH341支持的短數據包的長度 112 
113         // WIN32應用層接口命令 114         //public const int IOCTL_CH341_COMMAND = ( FILE_DEVICE_UNKNOWN << 16 | FILE_ANY_ACCESS << 14 | 0x0f34 << 2 | METHOD_BUFFERED ) // 專用接口 115 
116         // public const int mWIN32_COMMAND_HEAD = mOFFSET( mWIN32_COMMAND, mBuffer ); // WIN32命令接口的頭長度
117 
118         public const int mCH341_MAX_NUMBER = 16;            // 最多同時鏈接的CH341數
119 
120         public const int mMAX_BUFFER_LENGTH = 0x1000;       // 數據緩衝區最大長度4096 121 
122         // public const int mMAX_COMMAND_LENGTH = ( mWIN32_COMMAND_HEAD + mMAX_BUFFER_LENGTH ); // 最大數據長度加上命令結構頭的長度
123 
124         public const int mDEFAULT_BUFFER_LEN = 0x0400;      // 數據緩衝區默認長度1024 125 
126         // public const int mDEFAULT_COMMAND_LEN= ( mWIN32_COMMAND_HEAD + mDEFAULT_BUFFER_LEN ); // 默認數據長度加上命令結構頭的長度 127 
128         // CH341端點地址
129         public const int mCH341_ENDP_INTER_UP = 0x81;        // CH341的中斷數據上傳端點的地址
130         public const int mCH341_ENDP_INTER_DOWN = 0x01;        // CH341的中斷數據下傳端點的地址
131         public const int mCH341_ENDP_DATA_UP = 0x82;        // CH341的數據塊上傳端點的地址
132         public const int mCH341_ENDP_DATA_DOWN = 0x02;        // CH341的數據塊下傳端點的地址 133 
134 
135         // 設備層接口提供的管道操做命令
136         public const int mPipeDeviceCtrl = 0x00000004;    // CH341的綜合控制管道
137         public const int mPipeInterUp = 0x00000005;    // CH341的中斷數據上傳管道
138         public const int mPipeDataUp = 0x00000006;    // CH341的數據塊上傳管道
139         public const int mPipeDataDown = 0x00000007;    // CH341的數據塊下傳管道 140 
141         // 應用層接口的功能代碼
142         public const int mFuncNoOperation = 0x00000000;    // 無操做
143         public const int mFuncGetVersion = 0x00000001;    // 獲取驅動程序版本號
144         public const int mFuncGetConfig = 0x00000002;    // 獲取USB設備配置描述符
145         public const int mFuncSetTimeout = 0x00000009;    // 設置USB通信超時
146         public const int mFuncSetExclusive = 0x0000000b;    // 設置獨佔使用
147         public const int mFuncResetDevice = 0x0000000c;    // 復位USB設備
148         public const int mFuncResetPipe = 0x0000000d;    // 復位USB管道
149         public const int mFuncAbortPipe = 0x0000000e;    // 取消USB管道的數據請求 150 
151         // CH341並口專用的功能代碼
152         public const int mFuncSetParaMode = 0x0000000f;    // 設置並口模式
153         public const int mFuncReadData0 = 0x00000010;    // 從並口讀取數據塊0
154         public const int mFuncReadData1 = 0x00000011;    // 從並口讀取數據塊1
155         public const int mFuncWriteData0 = 0x00000012;    // 向並口寫入數據塊0
156         public const int mFuncWriteData1 = 0x00000013;    // 向並口寫入數據塊1
157         public const int mFuncWriteRead = 0x00000014;    // 先輸出再輸入
158         public const int mFuncBufferMode = 0x00000020;    // 設定緩衝上傳模式及查詢緩衝區中的數據長度
159         public const int FuncBufferModeDn = 0x00000021;    // 設定緩衝下傳模式及查詢緩衝區中的數據長度 160 
161 
162         // USB設備標準請求代碼
163         public const int mUSB_CLR_FEATURE = 0x01; 164         public const int mUSB_SET_FEATURE = 0x03; 165         public const int mUSB_GET_STATUS = 0x00; 166         public const int mUSB_SET_ADDRESS = 0x05; 167         public const int mUSB_GET_DESCR = 0x06; 168         public const int mUSB_SET_DESCR = 0x07; 169         public const int mUSB_GET_CONFIG = 0x08; 170         public const int mUSB_SET_CONFIG = 0x09; 171         public const int mUSB_GET_INTERF = 0x0a; 172         public const int mUSB_SET_INTERF = 0x0b; 173         public const int mUSB_SYNC_FRAME = 0x0c; 174 
175         // CH341控制傳輸的廠商專用請求類型
176         public const int mCH341_VENDOR_READ = 0xC0;        // 經過控制傳輸實現的CH341廠商專用讀操做
177         public const int mCH341_VENDOR_WRITE = 0x40;        // 經過控制傳輸實現的CH341廠商專用寫操做 178 
179         // CH341控制傳輸的廠商專用請求代碼
180         public const int mCH341_PARA_INIT = 0xB1;    // 初始化並口
181         public const int mCH341_I2C_STATUS = 0x52;        // 獲取I2C接口的狀態
182         public const int mCH341_I2C_COMMAND = 0x53;        // 發出I2C接口的命令 183 
184         // CH341並口操做命令代碼
185         public const int mCH341_PARA_CMD_R0 = 0xAC;        // 從並口讀數據0,次字節爲長度
186         public const int mCH341_PARA_CMD_R1 = 0xAD;        // 從並口讀數據1,次字節爲長度
187         public const int mCH341_PARA_CMD_W0 = 0xA6;        // 向並口寫數據0,從次字節開始爲數據流
188         public const int mCH341_PARA_CMD_W1 = 0xA7;        // 向並口寫數據1,從次字節開始爲數據流
189         public const int mCH341_PARA_CMD_STS = 0xA0;        // 獲取並口狀態 190 
191         // CH341A並口操做命令代碼
192         public const int mCH341A_CMD_SET_OUTPUT = 0xA1;        // 設置並口輸出
193         public const int mCH341A_CMD_IO_ADDR = 0xA2;    // MEM帶地址讀寫/輸入輸出,從次字節開始爲命令流
194         public const int mCH341A_CMD_PRINT_OUT = 0xA3;        // PRINT兼容打印方式輸出,從次字節開始爲數據流
195         public const int mCH341A_CMD_PWM_OUT = 0xA4;        // PWM數據輸出的命令包,從次字節開始爲數據流
196         public const int mCH341A_CMD_SHORT_PKT = 0xA5;        // 短包,次字節是該命令包的真正長度,再次字節及以後的字節是原命令包
197         public const int mCH341A_CMD_SPI_STREAM = 0xA8;        // SPI接口的命令包,從次字節開始爲數據流 198         //public const int mCH341A_CMD_SIO_STREAM 0xA9 // SIO接口的命令包,從次字節開始爲數據流
199         public const int mCH341A_CMD_I2C_STREAM = 0xAA;        // I2C接口的命令包,從次字節開始爲I2C命令流
200         public const int mCH341A_CMD_UIO_STREAM = 0xAB;        // UIO接口的命令包,從次字節開始爲命令流
201         public const int mCH341A_CMD_PIO_STREAM = 0xAE;        // PIO接口的命令包,從次字節開始爲數據流 202 
203         // CH341A控制傳輸的廠商專用請求代碼
204         public const int mCH341A_BUF_CLEAR = 0xB2;        // 清除未完成的數據
205         public const int mCH341A_I2C_CMD_X = 0x54;        // 發出I2C接口的命令,當即執行
206         public const int mCH341A_DELAY_MS = 0x5E;        // 以亳秒爲單位延時指定時間
207         public const int mCH341A_GET_VER = 0x5F;        // 獲取芯片版本
208 
209         public const int mCH341_EPP_IO_MAX = (mCH341_PACKET_LENGTH - 1);    // CH341在EPP/MEM方式下單次讀寫數據塊的最大長度
210         public const int mCH341A_EPP_IO_MAX = 0xFF;        // CH341A在EPP/MEM方式下單次讀寫數據塊的最大長度
211 
212         public const int mCH341A_CMD_IO_ADDR_W = 0x00;        // MEM帶地址讀寫/輸入輸出的命令流:寫數據,位6-位0爲地址,下一個字節爲待寫數據
213         public const int mCH341A_CMD_IO_ADDR_R = 0x80;        // MEM帶地址讀寫/輸入輸出的命令流:讀數據,位6-位0爲地址,讀出數據一塊兒返回
214 
215         public const int mCH341A_CMD_I2C_STM_STA = 0x74;        // I2C接口的命令流:產生起始位
216         public const int mCH341A_CMD_I2C_STM_STO = 0x75;        // I2C接口的命令流:產生中止位
217         public const int mCH341A_CMD_I2C_STM_OUT = 0x80;        // I2C接口的命令流:輸出數據,位5-位0爲長度,後續字節爲數據,0長度則只發送一個字節並返回應答
218         public const int mCH341A_CMD_I2C_STM_IN = 0xC0;        // I2C接口的命令流:輸入數據,位5-位0爲長度,0長度則只接收一個字節併發送無應答
219         public const int mCH341A_CMD_I2C_STM_MAX = ((0x3F < mCH341_PACKET_LENGTH) ? 0x3F : mCH341_PACKET_LENGTH);    // I2C接口的命令流單個命令輸入輸出數據的最大長度
220         public const int mCH341A_CMD_I2C_STM_SET = 0x60;        // I2C接口的命令流:設置參數,位2=SPI的I/O數(0=單入單出,1=雙入雙出),位1位0=I2C速度(00=低速,01=標準,10=快速,11=高速)
221         public const int mCH341A_CMD_I2C_STM_US = 0x40;        // I2C接口的命令流:以微秒爲單位延時,位3-位0爲延時值
222         public const int mCH341A_CMD_I2C_STM_MS = 0x50;        // I2C接口的命令流:以亳秒爲單位延時,位3-位0爲延時值
223         public const int mCH341A_CMD_I2C_STM_DLY = 0x0F;        // I2C接口的命令流單個命令延時的最大值
224         public const int mCH341A_CMD_I2C_STM_END = 0x00;        // I2C接口的命令流:命令包提早結束
225 
226         public const int mCH341A_CMD_UIO_STM_IN = 0x00;        // UIO接口的命令流:輸入數據D7-D0
227         public const int mCH341A_CMD_UIO_STM_DIR = 0x40;        // UIO接口的命令流:設定I/O方向D5-D0,位5-位0爲方向數據
228         public const int mCH341A_CMD_UIO_STM_OUT = 0x80;    // UIO接口的命令流:輸出數據D5-D0,位5-位0爲數據
229         public const int mCH341A_CMD_UIO_STM_US = 0xC0;        // UIO接口的命令流:以微秒爲單位延時,位5-位0爲延時值
230         public const int mCH341A_CMD_UIO_STM_END = 0x20;        // UIO接口的命令流:命令包提早結束 231 
232 
233         // CH341並口工做模式
234         public const int mCH341_PARA_MODE_EPP = 0x00;        // CH341並口工做模式爲EPP方式
235         public const int mCH341_PARA_MODE_EPP17 = 0x00;        // CH341A並口工做模式爲EPP方式V1.7
236         public const int mCH341_PARA_MODE_EPP19 = 0x01;        // CH341A並口工做模式爲EPP方式V1.9
237         public const int mCH341_PARA_MODE_MEM = 0x02;        // CH341並口工做模式爲MEM方式
238         public const int mCH341_PARA_MODE_ECP = 0x03;        // CH341A並口工做模式爲ECP方式 239 
240 
241         // I/O方向設置位定義,直接輸入的狀態信號的位定義,直接輸出的位數據定義
242         public const int mStateBitERR = 0x00000100;    // 只讀可寫,ERR#引腳輸入狀態,1:高電平,0:低電平
243         public const int mStateBitPEMP = 0x00000200;    // 只讀可寫,PEMP引腳輸入狀態,1:高電平,0:低電平
244         public const int mStateBitINT = 0x00000400;    // 只讀可寫,INT#引腳輸入狀態,1:高電平,0:低電平
245         public const int mStateBitSLCT = 0x00000800;    // 只讀可寫,SLCT引腳輸入狀態,1:高電平,0:低電平
246         public const int mStateBitWAIT = 0x00002000;    // 只讀可寫,WAIT#引腳輸入狀態,1:高電平,0:低電平
247         public const int mStateBitDATAS = 0x00004000;    // 只寫可讀,DATAS#/READ#引腳輸入狀態,1:高電平,0:低電平
248         public const int mStateBitADDRS = 0x00008000;    // 只寫可讀,ADDRS#/ADDR/ALE引腳輸入狀態,1:高電平,0:低電平
249         public const int mStateBitRESET = 0x00010000;    // 只寫,RESET#引腳輸入狀態,1:高電平,0:低電平
250         public const int mStateBitWRITE = 0x00020000;    // 只寫,WRITE#引腳輸入狀態,1:高電平,0:低電平
251         public const int mStateBitSCL = 0x00400000;    // 只讀,SCL引腳輸入狀態,1:高電平,0:低電平
252         public const int mStateBitSDA = 0x00800000;    // 只讀,SDA引腳輸入狀態,1:高電平,0:低電平
253 
254 
255         public const int MAX_DEVICE_PATH_SIZE = 128;            // 設備名稱的最大字符數
256         public const int MAX_DEVICE_ID_SIZE = 64;            // 設備ID的最大字符數
257 
258         /*
259  typedef VOID ( CALLBACK * mPCH341_INT_ROUTINE ) ( // 中斷服務程序 260  ULONG iStatus ); // 中斷狀態數據,參考下面的位說明 261  // 位7-位0對應CH341的D7-D0引腳 262  // 位8對應CH341的ERR#引腳, 位9對應CH341的PEMP引腳, 位10對應CH341的INT#引腳, 位11對應CH341的SLCT引腳 263         */
264  [UnmanagedFunctionPointer(CallingConvention.StdCall)] 265         public delegate void mPCH341_INT_ROUTINE(// 中斷服務程序
266                                                 UInt32 iStatus);// 中斷狀態數據,參考下面的位說明 267         // 位7-位0對應CH341的D7-D0引腳 268         // 位8對應CH341的ERR#引腳, 位9對應CH341的PEMP引腳, 位10對應CH341的INT#引腳, 位11對應CH341的SLCT引腳
269 
270         public const int USBIO_DEVICE_ARRIVAL = 3;  // 設備插入事件,已經插入
271         public const int USBIO_DEVICE_REMOVE_PEND = 1;      // 設備將要拔出
272         public const int USBIO_DEVICE_REMOVE = 0;   // 設備拔出事件,已經拔出
273 
274         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_OpenDevice")] 275         public static extern IntPtr USBIO_OpenDevice(  // 打開CH341設備,返回句柄,出錯則無效
276                                      UInt32 iIndex);  // 指定CH341設備序號,0對應第一個設備
277 
278         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_CloseDevice")] 279         public static extern void USBIO_CloseDevice(  // 關閉CH341設備
280                                       UInt32 iIndex);  // 指定CH341設備序號
281 
282         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_GetVersion")] 283         public static extern UInt32 USBIO_GetVersion();  // 得到DLL版本號,返回版本號 284 
285         //函數重載
286         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_DriverCommand")] 287         public static extern UInt32 USBIO_DriverCommand(  // 直接傳遞命令給驅動程序,出錯則返回0,不然返回數據長度
288                                 UInt32 iIndex,  // 指定CH341設備序號,V1.6以上DLL也能夠是設備打開後的句柄
289                                  ref mWIN32_COMMAND_mBuffer ioCommand);  // 命令結構的指針
290 
291 
292 
293         [DllImport("USBIOX.DLL", EntryPoint= "USBIO_DriverCommand")] 294         public static extern UInt32 USBIO_DriverCommand(  // 直接傳遞命令給驅動程序,出錯則返回0,不然返回數據長度
295                                 UInt32 iIndex,  // 指定CH341設備序號,V1.6以上DLL也能夠是設備打開後的句柄
296                                  ref mWIN32_COMMAND_USB_SETUP_PKT ioCommand);  // 命令結構的指針 297         // 該程序在調用後返回數據長度,而且仍然返回命令結構,若是是讀操做,則數據返回在命令結構中, 298         // 返回的數據長度在操做失敗時爲0,操做成功時爲整個命令結構的長度,例如讀一個字節,則返回mWIN32_COMMAND_HEAD+1, 299         // 命令結構在調用前,分別提供:管道號或者命令功能代碼,存取數據的長度(可選),數據(可選) 300         // 命令結構在調用後,分別返回:操做狀態代碼,後續數據的長度(可選), 301         // 操做狀態代碼是由WINDOWS定義的代碼,能夠參考NTSTATUS.H, 302         // 後續數據的長度是指讀操做返回的數據長度,數據存放在隨後的緩衝區中,對於寫操做通常爲0
303 
304         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_GetDrvVersion")] 305         public static extern UInt32 USBIO_GetDrvVersion();  // 得到驅動程序版本號,返回版本號,出錯則返回0
306 
307         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_ResetDevice")] 308         public static extern bool USBIO_ResetDevice(  // 復位USB設備
309                              UInt32 iIndex);  // 指定CH341設備序號
310 
311         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_GetDeviceDescr")] 312         public static extern bool USBIO_GetDeviceDescr(  // 讀取設備描述符
313             UInt32 iIndex,  // 指定CH341設備序號
314             byte[] oBuffer,  // 指向一個足夠大的緩衝區,用於保存描述符
315             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備讀取的長度,返回後爲實際讀取的長度
316 
317         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_GetConfigDescr")] 318         public static extern bool USBIO_GetConfigDescr(  // 讀取配置描述符
319             UInt32 iIndex,  // 指定CH341設備序號
320             byte[] oBuffer,  // 指向一個足夠大的緩衝區,用於保存描述符
321             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備讀取的長度,返回後爲實際讀取的長度
322 
323         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetIntRoutine")] 324         public static extern bool USBIO_SetIntRoutine(  // 設定中斷服務程序
325             UInt32 iIndex,  // 指定CH341設備序號
326             mPCH341_INT_ROUTINE iIntRoutine);  // 指定中斷服務程序,爲NULL則取消中斷服務,不然在中斷時調用該程序
327 
328         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_ReadInter")] 329         public static extern bool USBIO_ReadInter(  // 讀取中斷數據
330             UInt32 iIndex,  // 指定CH341設備序號
331             ref UInt32 iStatus);  // 指向一個雙字單元,用於保存讀取的中斷狀態數據,見下行 332         // 位7-位0對應CH341的D7-D0引腳 333         // 位8對應CH341的ERR#引腳, 位9對應CH341的PEMP引腳, 位10對應CH341的INT#引腳, 位11對應CH341的SLCT引腳
334 
335 
336         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_AbortInter")] 337         public static extern bool USBIO_AbortInter(  // 放棄中斷數據讀操做
338             UInt32 iIndex);  // 指定CH341設備序號
339 
340         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetParaMode")] 341         public static extern bool USBIO_SetParaMode(  // 設置並口模式
342             UInt32 iIndex,  // 指定CH341設備序號
343             UInt32 iMode);  // 指定並口模式: 0爲EPP模式/EPP模式V1.7, 1爲EPP模式V1.9, 2爲MEM模式
344 
345         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_InitParallel")] 346         public static extern bool USBIO_InitParallel(  // 復位並初始化並口,RST#輸出低電平脈衝
347             UInt32 iIndex,  // 指定CH341設備序號
348             UInt32 iMode);  // 指定並口模式: 0爲EPP模式/EPP模式V1.7, 1爲EPP模式V1.9, 2爲MEM模式, >= 0x00000100 保持當前模式
349 
350         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_ReadData0")] 351         public static extern bool USBIO_ReadData0(  // 從0#端口讀取數據塊
352             UInt32 iIndex,  // 指定CH341設備序號
353             byte[] oBuffer,  // 指向一個足夠大的緩衝區,用於保存讀取的數據
354             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備讀取的長度,返回後爲實際讀取的長度
355 
356         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_ReadData1")] 357         public static extern bool USBIO_ReadData1(  // 從1#端口讀取數據塊
358             UInt32 iIndex,  // 指定CH341設備序號
359             byte[] oBuffer,  // 指向一個足夠大的緩衝區,用於保存讀取的數據
360             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備讀取的長度,返回後爲實際讀取的長度
361 
362         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_AbortRead")] 363         public static extern bool USBIO_AbortRead(  // 放棄數據塊讀操做
364             UInt32 iIndex);  // 指定CH341設備序號
365 
366         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_WriteData0")] 367         public static extern bool USBIO_WriteData0(  // 向0#端口寫出數據塊
368             UInt32 iIndex,  // 指定CH341設備序號
369             byte[] iBuffer,  // 指向一個緩衝區,放置準備寫出的數據
370             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備寫出的長度,返回後爲實際寫出的長度
371 
372         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_WriteData1")] 373         public static extern bool USBIO_WriteData1(  // 向1#端口寫出數據塊
374             UInt32 iIndex,  // 指定CH341設備序號
375             byte[] iBuffer,  // 指向一個緩衝區,放置準備寫出的數據
376             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備寫出的長度,返回後爲實際寫出的長度
377 
378         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_AbortWrite")] 379         public static extern bool USBIO_AbortWrite(  // 放棄數據塊寫操做
380             UInt32 iIndex);  // 指定CH341設備序號
381 
382         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_GetStatus")] 383         public static extern bool USBIO_GetStatus(  // 經過CH341直接輸入數據和狀態
384             UInt32 iIndex,  // 指定CH341設備序號
385             ref UInt32 iStatus);  // 指向一個雙字單元,用於保存狀態數據,參考下面的位說明 386         // 位7-位0對應CH341的D7-D0引腳 387         // 位8對應CH341的ERR#引腳, 位9對應CH341的PEMP引腳, 位10對應CH341的INT#引腳, 位11對應CH341的SLCT引腳, 位23對應CH341的SDA引腳 388         // 位13對應CH341的BUSY/WAIT#引腳, 位14對應CH341的AUTOFD#/DATAS#引腳,位15對應CH341的SLCTIN#/ADDRS#引腳
389 
390         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_ReadI2C")] 391         public static extern bool USBIO_ReadI2C(  // 從I2C接口讀取一個字節數據
392             UInt32 iIndex,  // 指定CH341設備序號
393             byte iDevice,  // 低7位指定I2C設備地址
394             byte iAddr,  // 指定數據單元的地址
395             ref byte oByte);  // 指向一個字節單元,用於保存讀取的字節數據
396 
397         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_WriteI2C")] 398         public static extern bool USBIO_WriteI2C(  // 向I2C接口寫入一個字節數據
399             UInt32 iIndex,  // 指定CH341設備序號
400             byte iDevice,  // 低7位指定I2C設備地址
401             byte iAddr,  // 指定數據單元的地址
402             byte iByte);  // 待寫入的字節數據
403 
404         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_EppReadData")] 405         public static extern bool USBIO_EppReadData(  // EPP方式讀數據: WR#=1, DS#=0, AS#=1, D0-D7=input
406             UInt32 iIndex,  // 指定CH341設備序號
407             byte[] oBuffer,  // 指向一個足夠大的緩衝區,用於保存讀取的數據
408             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備讀取的長度,返回後爲實際讀取的長度
409 
410         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_EppReadAddr")] 411         public static extern bool USBIO_EppReadAddr(  // EPP方式讀地址: WR#=1, DS#=1, AS#=0, D0-D7=input
412             UInt32 iIndex,  // 指定CH341設備序號
413             byte[] oBuffer,  // 指向一個足夠大的緩衝區,用於保存讀取的地址數據
414             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備讀取的長度,返回後爲實際讀取的長度
415 
416         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_EppWriteData")] 417         public static extern bool USBIO_EppWriteData(  // EPP方式寫數據: WR#=0, DS#=0, AS#=1, D0-D7=output
418             UInt32 iIndex,  // 指定CH341設備序號
419             byte[] iBuffer,  // 指向一個緩衝區,放置準備寫出的數據
420             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備寫出的長度,返回後爲實際寫出的長度
421 
422         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_EppWriteAddr")] 423         public static extern bool USBIO_EppWriteAddr(  // EPP方式寫地址: WR#=0, DS#=1, AS#=0, D0-D7=output
424             UInt32 iIndex,  // 指定CH341設備序號
425             byte[] iBuffer,  // 指向一個緩衝區,放置準備寫出的地址數據
426             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備寫出的長度,返回後爲實際寫出的長度
427 
428         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_EppSetAddr")] 429         public static extern bool USBIO_EppSetAddr(  // EPP方式設置地址: WR#=0, DS#=1, AS#=0, D0-D7=output
430             UInt32 iIndex,  // 指定CH341設備序號
431             byte iAddr);  // 指定EPP地址
432 
433         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_MemReadAddr0")] 434         public static extern bool USBIO_MemReadAddr0(  // MEM方式讀地址0: WR#=1, DS#/RD#=0, AS#/ADDR=0, D0-D7=input
435             UInt32 iIndex,  // 指定CH341設備序號
436             byte[] oBuffer,  // 指向一個足夠大的緩衝區,用於保存從地址0讀取的數據
437             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備讀取的長度,返回後爲實際讀取的長度
438 
439         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_MemReadAddr1")] 440         public static extern bool USBIO_MemReadAddr1(  // MEM方式讀地址1: WR#=1, DS#/RD#=0, AS#/ADDR=1, D0-D7=input
441             UInt32 iIndex,  // 指定CH341設備序號
442             byte[] oBuffer,  // 指向一個足夠大的緩衝區,用於保存從地址1讀取的數據
443             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備讀取的長度,返回後爲實際讀取的長度
444 
445         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_MemWriteAddr0")] 446         public static extern bool USBIO_MemWriteAddr0(  // MEM方式寫地址0: WR#=0, DS#/RD#=1, AS#/ADDR=0, D0-D7=output
447             UInt32 iIndex,  // 指定CH341設備序號
448             byte[] iBuffer,  // 指向一個緩衝區,放置準備向地址0寫出的數據
449             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備寫出的長度,返回後爲實際寫出的長度
450 
451         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_MemWriteAddr1")] 452         public static extern bool USBIO_MemWriteAddr1(  // MEM方式寫地址1: WR#=0, DS#/RD#=1, AS#/ADDR=1, D0-D7=output
453             UInt32 iIndex,  // 指定CH341設備序號
454             byte[] iBuffer,  // 指向一個緩衝區,放置準備向地址1寫出的數據
455             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備寫出的長度,返回後爲實際寫出的長度
456 
457         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetExclusive")] 458         public static extern bool USBIO_SetExclusive(  // 設置獨佔使用當前CH341設備
459             UInt32 iIndex,  // 指定CH341設備序號
460             UInt32 iExclusive);  // 爲0則設備能夠共享使用,非0則獨佔使用
461 
462         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetTimeout")] 463         public static extern bool USBIO_SetTimeout(  // 設置USB數據讀寫的超時
464             UInt32 iIndex,  // 指定CH341設備序號
465             UInt32 iWriteTimeout,  // 指定USB寫出數據塊的超時時間,以毫秒mS爲單位,0xFFFFFFFF指定不超時(默認值)
466             UInt32 iReadTimeout);  // 指定USB讀取數據塊的超時時間,以毫秒mS爲單位,0xFFFFFFFF指定不超時(默認值)
467 
468         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_ReadData")] 469         public static extern bool USBIO_ReadData(  // 讀取數據塊
470             UInt32 iIndex,  // 指定CH341設備序號
471             byte[] oBuffer,  // 指向一個足夠大的緩衝區,用於保存讀取的數據
472             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備讀取的長度,返回後爲實際讀取的長度
473 
474         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_WriteData")] 475         public static extern bool USBIO_WriteData(  // 寫出數據塊
476             UInt32 iIndex,  // 指定CH341設備序號
477             byte[] iBuffer,  // 指向一個緩衝區,放置準備寫出的數據
478             ref UInt32 ioLength);  // 指向長度單元,輸入時爲準備寫出的長度,返回後爲實際寫出的長度
479 
480         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_GetDeviceName")] 481         public static extern IntPtr USBIO_GetDeviceName(  // 返回指向CH341設備名稱的緩衝區,出錯則返回NULL
482             UInt32 iIndex);  // 指定CH341設備序號,0對應第一個設備
483 
484         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_GetVerIC")] 485         public static extern UInt32 USBIO_GetVerIC(  // 獲取CH341芯片的版本,返回:0=設備無效,0x10=CH341,0x20=CH341A
486             UInt32 iIndex);  // 指定CH341設備序號
487 
488         public const int IC_VER_CH341A = 0x20; 489         public const int IC_VER_CH341A3 = 0x30; 490 
491         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_FlushBuffer")] 492         public static extern bool USBIO_FlushBuffer(  // 清空CH341的緩衝區
493             UInt32 iIndex);  // 指定CH341設備序號
494 
495         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_WriteRead")] 496         public static extern bool USBIO_WriteRead(  // 執行數據流命令,先輸出再輸入
497             UInt32 iIndex,  // 指定CH341設備序號
498             UInt32 iWriteLength,  // 寫長度,準備寫出的長度
499             byte[] iWriteBuffer,  // 指向一個緩衝區,放置準備寫出的數據
500             UInt32 iReadStep,  // 準備讀取的單個塊的長度, 準備讀取的總長度爲(iReadStep*iReadTimes)
501             UInt32 iReadTimes,  // 準備讀取的次數
502             ref UInt32 oReadLength,  // 指向長度單元,返回後爲實際讀取的長度
503             byte[] oReadBuffer);  // 指向一個足夠大的緩衝區,用於保存讀取的數據
504 
505         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetStream")] 506         public static extern bool USBIO_SetStream(  // 設置串口流模式
507             UInt32 iIndex,  // 指定CH341設備序號
508             UInt32 iMode);  // 指定模式,見下行 509         // 位1-位0: I2C接口速度/SCL頻率, 00=低速/20KHz,01=標準/100KHz(默認值),10=快速/400KHz,11=高速/750KHz 510         // 位2: SPI的I/O數/IO引腳, 0=單入單出(D3時鐘/D5出/D7入)(默認值),1=雙入雙出(D3時鐘/D5出D4出/D7入D6入) 511         // 位7: SPI字節中的位順序, 0=低位在前, 1=高位在前 512         // 其它保留,必須爲0
513 
514         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetDelaymS")] 515         public static extern bool USBIO_SetDelaymS(  // 設置硬件異步延時,調用後很快返回,而在下一個流操做以前延時指定毫秒數
516             UInt32 iIndex,  // 指定CH341設備序號
517             UInt32 iDelay);  // 指定延時的毫秒數
518 
519         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_StreamI2C")] 520         public static extern bool USBIO_StreamI2C(  // 處理I2C數據流,2線接口,時鐘線爲SCL引腳,數據線爲SDA引腳(準雙向I/O),速度約56K字節
521             UInt32 iIndex,  // 指定CH341設備序號
522             UInt32 iWriteLength,  // 準備寫出的數據字節數
523             byte[] iWriteBuffer,  // 指向一個緩衝區,放置準備寫出的數據,首字節一般是I2C設備地址及讀寫方向位
524             UInt32 iReadLength,  // 準備讀取的數據字節數
525             byte[] oReadBuffer);  // 指向一個緩衝區,返回後是讀入的數據
526 
527         public enum EEPROM_TYPE         // EEPROM型號
528  { 529  ID_24C01, 530  ID_24C02, 531  ID_24C04, 532  ID_24C08, 533  ID_24C16, 534  ID_24C32, 535  ID_24C64, 536  ID_24C128, 537  ID_24C256, 538  ID_24C512, 539  ID_24C1024, 540  ID_24C2048, 541  ID_24C4096 542 
543  }; 544 
545         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_ReadEEPROM")] 546         public static extern bool USBIO_ReadEEPROM(  // 從EEPROM中讀取數據塊,速度約56K字節
547             UInt32 iIndex,  // 指定CH341設備序號
548             EEPROM_TYPE iEepromID,  // 指定EEPROM型號
549             UInt32 iAddr,  // 指定數據單元的地址
550             UInt32 iLength,  // 準備讀取的數據字節數
551             byte[] oBuffer);  // 指向一個緩衝區,返回後是讀入的數據
552 
553         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_WriteEEPROM")] 554         public static extern bool USBIO_WriteEEPROM(  // 向EEPROM中寫入數據塊
555             UInt32 iIndex,  // 指定CH341設備序號
556             EEPROM_TYPE iEepromID,  // 指定EEPROM型號
557             UInt32 iAddr,  // 指定數據單元的地址
558             UInt32 iLength,  // 準備寫出的數據字節數
559             byte[] iBuffer);  // 指向一個緩衝區,放置準備寫出的數據
560 
561         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_GetInput")] 562         public static extern bool USBIO_GetInput(  // 經過CH341直接輸入數據和狀態,效率比CH341GetStatus更高
563             UInt32 iIndex,  // 指定CH341設備序號
564             ref UInt32 iStatus);  // 指向一個雙字單元,用於保存狀態數據,參考下面的位說明 565         // 位7-位0對應CH341的D7-D0引腳 566         // 位8對應CH341的ERR#引腳, 位9對應CH341的PEMP引腳, 位10對應CH341的INT#引腳, 位11對應CH341的SLCT引腳, 位23對應CH341的SDA引腳 567         // 位13對應CH341的BUSY/WAIT#引腳, 位14對應CH341的AUTOFD#/DATAS#引腳,位15對應CH341的SLCTIN#/ADDRS#引腳
568 
569         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetOutput")] 570         public static extern bool USBIO_SetOutput(  // 設置CH341的I/O方向,並經過CH341直接輸出數據
571                                                    /* ***** 謹慎使用該API, 防止修改I/O方向使輸入引腳變爲輸出引腳致使與其它輸出引腳之間短路而損壞芯片 ***** */
572             UInt32 iIndex,  // 指定CH341設備序號
573             UInt32 iEnable,  // 數據有效標誌,參考下面的位說明 574                              // 位0爲1說明iSetDataOut的位15-位8有效,不然忽略 575                              // 位1爲1說明iSetDirOut的位15-位8有效,不然忽略 576                              // 位2爲1說明iSetDataOut的7-位0有效,不然忽略 577                              // 位3爲1說明iSetDirOut的位7-位0有效,不然忽略 578                              // 位4爲1說明iSetDataOut的位23-位16有效,不然忽略
579             UInt32 iSetDirOut,  // 設置I/O方向,某位清0則對應引腳爲輸入,某位置1則對應引腳爲輸出,並口方式下默認值爲0x000FC000,參考下面的位說明
580             UInt32 iSetDataOut);  // 輸出數據,若是I/O方向爲輸出,那麼某位清0時對應引腳輸出低電平,某位置1時對應引腳輸出高電平,參考下面的位說明 581         // 位7-位0對應CH341的D7-D0引腳 582         // 位8對應CH341的ERR#引腳, 位9對應CH341的PEMP引腳, 位10對應CH341的INT#引腳, 位11對應CH341的SLCT引腳 583         // 位13對應CH341的WAIT#引腳, 位14對應CH341的DATAS#/READ#引腳,位15對應CH341的ADDRS#/ADDR/ALE引腳 584         // 如下引腳只能輸出,不考慮I/O方向: 位16對應CH341的RESET#引腳, 位17對應CH341的WRITE#引腳, 位18對應CH341的SCL引腳, 位29對應CH341的SDA引腳
585 
586         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_Set_D5_D0")] 587         public static extern bool USBIO_Set_D5_D0(  // 設置CH341的D5-D0引腳的I/O方向,並經過CH341的D5-D0引腳直接輸出數據,效率比CH341SetOutput更高
588                                                    /* ***** 謹慎使用該API, 防止修改I/O方向使輸入引腳變爲輸出引腳致使與其它輸出引腳之間短路而損壞芯片 ***** */
589             UInt32 iIndex,  // 指定CH341設備序號
590             UInt32 iSetDirOut,  // 設置D5-D0各引腳的I/O方向,某位清0則對應引腳爲輸入,某位置1則對應引腳爲輸出,並口方式下默認值爲0x00所有輸入
591             UInt32 iSetDataOut);  // 設置D5-D0各引腳的輸出數據,若是I/O方向爲輸出,那麼某位清0時對應引腳輸出低電平,某位置1時對應引腳輸出高電平 592         // 以上數據的位5-位0分別對應CH341的D5-D0引腳
593 
594         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_StreamSPI3")] 595         public static extern bool USBIO_StreamSPI3(  // 該API已失效,請勿使用
596  UInt32 iIndex, 597  UInt32 iChipSelect, 598  UInt32 iLength, 599             byte[] ioBuffer); 600 
601         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_StreamSPI4")] 602         public static extern bool USBIO_StreamSPI4(  // 處理SPI數據流,4線接口,時鐘線爲DCK/D3引腳,輸出數據線爲DOUT/D5引腳,輸入數據線爲DIN/D7引腳,片選線爲D0/D1/D2,速度約68K字節
603                                                     /* SPI時序: DCK/D3引腳爲時鐘輸出, 默認爲低電平, DOUT/D5引腳在時鐘上升沿以前的低電平期間輸出, DIN/D7引腳在時鐘降低沿以前的高電平期間輸入 */
604             UInt32 iIndex,  // 指定CH341設備序號
605             UInt32 iChipSelect,  // 片選控制, 位7爲0則忽略片選控制, 位7爲1則參數有效: 位1位0爲00/01/10分別選擇D0/D1/D2引腳做爲低電平有效片選
606             UInt32 iLength,  // 準備傳輸的數據字節數
607             byte[] ioBuffer);  // 指向一個緩衝區,放置準備從DOUT寫出的數據,返回後是從DIN讀入的數據
608 
609         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_StreamSPI5")] 610         public static extern bool USBIO_StreamSPI5(  // 處理SPI數據流,5線接口,時鐘線爲DCK/D3引腳,輸出數據線爲DOUT/D5和DOUT2/D4引腳,輸入數據線爲DIN/D7和DIN2/D6引腳,片選線爲D0/D1/D2,速度約30K字節*2
611                                                     /* SPI時序: DCK/D3引腳爲時鐘輸出, 默認爲低電平, DOUT/D5和DOUT2/D4引腳在時鐘上升沿以前的低電平期間輸出, DIN/D7和DIN2/D6引腳在時鐘降低沿以前的高電平期間輸入 */
612             UInt32 iIndex,  // 指定CH341設備序號
613             UInt32 iChipSelect,  // 片選控制, 位7爲0則忽略片選控制, 位7爲1則參數有效: 位1位0爲00/01/10分別選擇D0/D1/D2引腳做爲低電平有效片選
614             UInt32 iLength,  // 準備傳輸的數據字節數
615             byte[] ioBuffer,  // 指向一個緩衝區,放置準備從DOUT寫出的數據,返回後是從DIN讀入的數據
616             byte[] ioBuffer2);  // 指向第二個緩衝區,放置準備從DOUT2寫出的數據,返回後是從DIN2讀入的數據
617 
618         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_BitStreamSPI")] 619         public static extern bool USBIO_BitStreamSPI(  // 處理SPI位數據流,4線/5線接口,時鐘線爲DCK/D3引腳,輸出數據線爲DOUT/DOUT2引腳,輸入數據線爲DIN/DIN2引腳,片選線爲D0/D1/D2,速度約8K位*2
620             UInt32 iIndex,  // 指定CH341設備序號
621             UInt32 iLength,  // 準備傳輸的數據位數,一次最多896,建議不超過256
622             byte[] ioBuffer);  // 指向一個緩衝區,放置準備從DOUT/DOUT2/D2-D0寫出的數據,返回後是從DIN/DIN2讀入的數據
623         /* SPI時序: DCK/D3引腳爲時鐘輸出, 默認爲低電平, DOUT/D5和DOUT2/D4引腳在時鐘上升沿以前的低電平期間輸出, DIN/D7和DIN2/D6引腳在時鐘降低沿以前的高電平期間輸入 */
624         /* ioBuffer中的一個字節共8位分別對應D7-D0引腳, 位5輸出到DOUT, 位4輸出到DOUT2, 位2-位0輸出到D2-D0, 位7從DIN輸入, 位6從DIN2輸入, 位3數據忽略 */
625         /* 在調用該API以前,應該先調用CH341Set_D5_D0設置CH341的D5-D0引腳的I/O方向,並設置引腳的默認電平 */
626 
627         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetBufUpload")] 628         public static extern bool USBIO_SetBufUpload(  // 設定內部緩衝上傳模式
629             UInt32 iIndex,  // 指定CH341設備序號,0對應第一個設備
630             UInt32 iEnableOrClear);  // 爲0則禁止內部緩衝上傳模式,使用直接上傳,非0則啓用內部緩衝上傳模式並清除緩衝區中的已有數據 631         // 若是啓用內部緩衝上傳模式,那麼CH341驅動程序建立線程自動接收USB上傳數據到內部緩衝區,同時清除緩衝區中的已有數據,當應用程序調用CH341ReadData後將當即返回緩衝區中的已有數據
632 
633         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_QueryBufUpload")] 634         public static extern Int32 USBIO_QueryBufUpload(  // 查詢內部上傳緩衝區中的已有數據包個數,成功返回數據包個數,出錯返回-1
635             UInt32 iIndex);  // 指定CH341設備序號,0對應第一個設備
636 
637         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetBufDownload")] 638         public static extern bool USBIO_SetBufDownload(  // 設定內部緩衝下傳模式
639             UInt32 iIndex,  // 指定CH341設備序號,0對應第一個設備
640             UInt32 iEnableOrClear);  // 爲0則禁止內部緩衝下傳模式,使用直接下傳,非0則啓用內部緩衝下傳模式並清除緩衝區中的已有數據 641         // 若是啓用內部緩衝下傳模式,那麼當應用程序調用CH341WriteData後將僅僅是將USB下傳數據放到內部緩衝區並當即返回,而由CH341驅動程序建立的線程自動發送直到完畢
642 
643         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_QueryBufDownload")] 644         public static extern Int32 USBIO_QueryBufDownload(  // 查詢內部下傳緩衝區中的剩餘數據包個數(還沒有發送),成功返回數據包個數,出錯返回-1
645             UInt32 iIndex);  // 指定CH341設備序號,0對應第一個設備
646 
647         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_ResetInter")] 648         public static extern bool USBIO_ResetInter(  // 復位中斷數據讀操做
649             UInt32 iIndex);  // 指定CH341設備序號
650 
651         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_ResetRead")] 652         public static extern bool USBIO_ResetRead(  // 復位數據塊讀操做
653             UInt32 iIndex);  // 指定CH341設備序號
654 
655         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_ResetWrite")] 656         public static extern bool USBIO_ResetWrite(  // 復位數據塊寫操做
657             UInt32 iIndex);  // 指定CH341設備序號
658 
659  [UnmanagedFunctionPointer(CallingConvention.StdCall)] 660 
661         public delegate void mPCH341_NOTIFY_ROUTINE(  // 設備事件通知回調程序
662                     UInt32 iEventStatus);  // 設備事件和當前狀態(在下行定義): 0=設備拔出事件, 3=設備插入事件
663 
664 
665         public const int CH341_DEVICE_ARRIVA = 3;    // 設備插入事件,已經插入
666         public const int CH341_DEVICE_REMOVE_PEND = 1;        // 設備將要拔出
667         public const int CH341_DEVICE_REMOVE = 0;        // 設備拔出事件,已經拔出
668 
669         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetDeviceNotify")] 670         public static extern bool USBIO_SetDeviceNotify(  // 設定設備事件通知程序
671             UInt32 iIndex,  // 指定CH341設備序號,0對應第一個設備
672             string iDeviceID,  // 可選參數,指向字符串,指定被監控的設備的ID,字符串以\0終止
673             mPCH341_NOTIFY_ROUTINE iNotifyRoutine);  // 指定設備事件回調程序,爲NULL則取消事件通知,不然在檢測到事件時調用該程序
674 
675         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetupSerial")] 676         public static extern bool USBIO_SetupSerial(  // 設定CH341的串口特性,該API只能用於工做於串口方式的CH341芯片
677             UInt32 iIndex,  // 指定CH341設備序號,0對應第一個設備
678             UInt32 iParityMode,  // 指定CH341串口的數據校驗模式: NOPARITY/ODDPARITY/EVENPARITY/MARKPARITY/SPACEPARITY
679             UInt32 iBaudRate);  // 指定CH341串口的通信波特率值,能夠是50至3000000之間的任意值
680 
681         /* 如下API能夠用於工做於串口方式的CH341芯片,除此以外的API通常只能用於並口方式的CH341芯片 682  CH341OpenDevice 683  CH341CloseDevice 684  CH341SetupSerial 685  CH341ReadData 686  CH341WriteData 687  CH341SetBufUpload 688  CH341QueryBufUpload 689  CH341SetBufDownload 690  CH341QueryBufDownload 691  CH341SetDeviceNotify 692  CH341GetStatus 693  // 以上是主要API,如下是次要API 694  CH341GetVersion 695  CH341DriverCommand 696  CH341GetDrvVersion 697  CH341ResetDevice 698  CH341GetDeviceDescr 699  CH341GetConfigDescr 700  CH341SetIntRoutine 701  CH341ReadInter 702  CH341AbortInter 703  CH341AbortRead 704  CH341AbortWrite 705  CH341ReadI2C 706  CH341WriteI2C 707  CH341SetExclusive 708  CH341SetTimeout 709  CH341GetDeviceName 710  CH341GetVerIC 711  CH341FlushBuffer 712  CH341WriteRead 713  CH341ResetInter 714  CH341ResetRead 715  CH341ResetWrite 716         */
717         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_OpenDeviceEx")] 718         public static extern IntPtr USBIO_OpenDeviceEx(   // 打開CH341設備,返回句柄,出錯則無效
719             UInt32 iIndex);        // 指定CH341設備序號,0對應插入的第一個設備,1對應插入的第二個設備,爲節約設備設備序號資源,用完後要關閉設備
720 
721         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_CloseDeviceEx")] 722         public static extern void USBIO_CloseDeviceEx(  // 關閉CH341設備
723             UInt32 iIndex);        // 指定CH341設備序號
724 
725         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_GetDeviceNameEx")] 726         public static extern IntPtr USBIO_GetDeviceNameEx(   // 返回指向CH341設備名稱的緩衝區,出錯則返回NULL
727             UInt32 iIndex);           // 指定CH341設備序號,0對應第一個設備
728 
729         [DllImport("USBIOX.DLL", EntryPoint = "USBIO_SetDeviceNotifyEx")] 730         public static extern bool USBIO_SetDeviceNotifyEx(       // 設定設備事件通知程序
731             UInt32 iIndex,           // 指定CH341設備序號,0對應第一個設備
732             string iDeviceID,        // 可選參數,指向字符串,指定被監控的設備的ID,字符串以\0終止
733             mPCH341_NOTIFY_ROUTINE iNotifyRoutine); // 指定設備事件回調程序,爲NULL則取消事件通知,不然在檢測到事件時調用該程序
734 
735  } 736 }
USBIOXdll.cs

主要I2C和SPI 操做代碼:ide

 1 //FLASH 配置狀態寄存器地址
 2         public static byte WRITE_ENABLE = 0X06; //寫使能
 3         public static byte WRITE_DISABLE = 0X04;    //寫禁止
 4         public static byte READ_STATUS_REG1 = 0X05; //讀狀態寄存器
 5         public static byte READ_STATUS_REG2 = 0X35; //讀狀態寄存器
 6         public static byte READ_DATA = 0X03;    //讀字節
 7         public static byte EWSR = 0X50;    //使能寫狀態寄存器
 8         public static byte FAST_READ = 0X0B;    //快讀指令
 9         public static byte PAGE_PROGRAM = 0X02; //Byte Prog Mode
 10         public static byte SECTOR_ERASE_4K = 0X20;  //Erase 4 KByte of memory array
 11         public static byte BLOCK_ERASE_32K = 0X52; //Erase 32 KByte block of memory array
 12         public static byte BLOCK_ERASE_64K = 0XD8;  //Erase 64 KByte block of memory array
 13         public static byte CHIP_ERASE = 0XC7;   //擦除整個FLASH芯片
 14 
 15 public static void memset(byte[] buf, byte val, int size)  16  {  17             int i;  18             for (i = 0; i < size; i++)  19                 buf[i] = val;  20  }  21 
 22         public static void memcpy(byte[] dst, int dst_offst, byte[] src, int src_offst, uint len)  23  {  24             for (int i = 0; i < len; i++)  25  {  26                 dst[dst_offst++] = src[src_offst++];  27  }  28 
 29  }  30 
 31         public static bool ReadI2C(uint mIndex, byte SlaveAddr, byte DataAddr, byte readData)    //連讀模式
 32  {  33             UInt32 writeLen = 0, readLen = 1;  34             byte[] writeData = new byte[4], rData = new byte[1];  35             memset(writeData, 0xFF, 4);  36             writeData[0] = SlaveAddr;  37             writeData[1] = DataAddr;  38             writeLen = 2;  39             bool bRet = USBIOXdll.USBIO_StreamI2C(mIndex, writeLen, writeData, readLen, rData);  40             readData = rData[0];  41             return bRet;  42  }  43         public static bool ReadI2C(uint mIndex, byte SlaveAddr, byte DataAddr, byte[] readData, UInt32 readLen)    //連讀模式
 44  {  45             UInt32 writeLen = 0;  46             byte[] writeData = new byte[4];  47             memset(writeData, 0xFF, 4);  48             writeData[0] = SlaveAddr;  49             writeData[1] = DataAddr;  50             writeLen = 2;  51             bool bRet = USBIOXdll.USBIO_StreamI2C(mIndex, writeLen, writeData, readLen, readData);  52             return bRet;  53  }  54 
 55         public static bool WriteI2C(uint mIndex, byte SlaveAddr, byte DataAddr, byte data)     //單寫模式
 56  {  57             UInt32 writeLen = 3;  58             UInt32 readLen = 0;  59             byte[] writeData = new byte[4];  60             byte[] readData = new byte[256];  61             memset(writeData, 0xFF, 4);  62             memset(readData, 0x00, 256);  63             writeData[0] = SlaveAddr;  64             writeData[1] = DataAddr;  65             writeData[2] = data;  66             bool bRet = USBIOXdll.USBIO_StreamI2C(mIndex, writeLen, writeData, readLen, readData);  67             return bRet;  68  }  69 
 70         public static bool WriteI2C(uint mIndex, byte SlaveAddr, byte DataAddr, byte[] data, UInt32 len)     //多寫模式
 71  {  72             UInt32 writeLen = len + 2;  73             UInt32 readLen = 0;  74             byte[] writeData = new byte[writeLen];  75             byte[] readData = new byte[256];  76             //memset(writeData, 0xFF, 4);
 77             memset(readData, 0x00, 256);  78 
 79             writeData[0] = SlaveAddr;  80             writeData[1] = DataAddr;  81             memcpy(writeData, 2, data, 0, len);  82             bool bRet = USBIOXdll.USBIO_StreamI2C(mIndex, writeLen, writeData, readLen, readData);  83             return bRet;  84  }  85         /// <summary>
 86         /// SPI擦除flash操做  87         /// </summary>
 88         /// <param name="mIndex">指定CH341設備序號</param>
 89         /// <param name="m_iChipSelect">片選控制, 位7爲0則忽略片選控制, 位7爲1則參數有效: 位1位0爲00/01/10分別選擇D0/D1/D2引腳做爲低電平有效片選</param>
 90         /// <param name="Erase_Select">擦除類型</param>
 91         /// <param name="sAdd">地址</param>
 92         public static void SPIErase(uint mIndex,uint m_iChipSelect,byte Erase_Select,uint sAdd)  93  {  94             byte[] data = new byte[4];  95             USBIOXdll.USBIO_SetStream(mIndex, 0x80);  96             memset(data, 0xFF, 4);  97             data[0] = WRITE_ENABLE;  98             USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, 1, data);  99 
100             data[0] = Erase_Select; 101             data[1] = (byte)((sAdd & 0xFF0000) >> 16); 102             data[2] = (byte)((sAdd & 0x00FF00) >> 8); 103             data[3] = (byte)(sAdd & 0x0000FF); 104             USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, 4, data); 105 
106             data[0] = WRITE_DISABLE; 107             USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, 1, data); 108 
109  } 110         /// <summary>
111         /// SPI寫入flash數據 112         /// </summary>
113         /// <param name="mIndex">設備號</param>
114         /// <param name="m_iChipSelect">片選</param>
115         /// <param name="sAdd">起始地址</param>
116         /// <param name="WriteData">數據</param>
117         public static void WriteSPI(uint mIndex, uint m_iChipSelect,uint sAdd,byte[] WriteData) 118  { 119             byte[] status = new byte[1]; 120             byte[] data = new byte[260]; 121             int len = WriteData.Length; 122             int nPage = 0; 123             USBIOXdll.USBIO_SetStream(mIndex, 0x80); 124             while (len >256) 125  { 126                 
127                 status[0] = WRITE_ENABLE; 128                 USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, 1, status); 129                 data[0] = PAGE_PROGRAM; 130                 data[1] = (byte)((sAdd & 0xFF0000) >> 16); 131                 data[2] = (byte)((sAdd & 0x00FF00) >> 8); 132                 data[3] = (byte)(sAdd & 0x0000FF); 133                 memcpy(data, 4, WriteData, nPage * 256, 256); 134                 USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, 260, data); 135                 status[0] = WRITE_DISABLE; 136                 USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, 1, status); 137                 USBIOXdll.USBIO_SetDelaymS(mIndex, 2); 138                 len -= 256; 139                 nPage++; 140                 sAdd += 256; 141  } 142 
143             status[0] = WRITE_ENABLE; 144             USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, 1, status); 145             data[0] = PAGE_PROGRAM; 146             data[1] = (byte)((sAdd & 0xFF0000) >> 16); 147             data[2] = (byte)((sAdd & 0x00FF00) >> 8); 148             data[3] = (byte)(sAdd & 0x0000FF); 149             memcpy(data, 4, WriteData, nPage * 256, (uint)len); 150             USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, (uint)(len+4), data); 151             status[0] = WRITE_DISABLE; 152             USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, 1, status); 153  } 154         /// <summary>
155         /// SPI讀取flash數據 156         /// </summary>
157         /// <param name="mIndex">設備號</param>
158         /// <param name="m_iChipSelect">片選</param>
159         /// <param name="sAdd">起始地址</param>
160         /// <param name="ReadData">讀取數據返回數組</param>
161         /// <param name="ReadLen">讀取長度</param>
162         public static void ReadSPI(uint mIndex, uint m_iChipSelect, uint sAdd, byte[] ReadData,uint ReadLen) 163  { 164             byte[] status = new byte[2564]; 165             int i = 0; 166             
167             USBIOXdll.USBIO_SetStream(mIndex, 0x80); 168             //USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, 4, status);
169             while(ReadLen>2560) 170  { 171                 status[0] = READ_DATA; 172                 status[1] = (byte)((sAdd & 0xFF0000) >> 16); 173                 status[2] = (byte)((sAdd & 0x00FF00) >> 8); 174                 status[3] = (byte)(sAdd & 0x0000FF); 175                 USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, 2564, status); 176                 memcpy(ReadData, i * 2560, status, 4, 2560); 177                 ReadLen -= 2560; 178                 i++; 179                 sAdd += 2560; 180  } 181             status[0] = READ_DATA; 182             status[1] = (byte)((sAdd & 0xFF0000) >> 16); 183             status[2] = (byte)((sAdd & 0x00FF00) >> 8); 184             status[3] = (byte)(sAdd & 0x0000FF); 185             USBIOXdll.USBIO_StreamSPI4(mIndex, m_iChipSelect, ReadLen+4, status); 186             memcpy(ReadData, i * 2560, status, 4, ReadLen); 187         }
View Code

 

 

 

連接:C# SPI 讀寫SD卡函數

相關文章
相關標籤/搜索