以前看了別人是C++ MFC開發的CH341 I2C,SPI讀寫flash的軟件代碼,看上去有點頭暈,感受仍是使用C# winform開發更人性化些html
C#控制須要調用CH341提供的DLL庫,網上多數是ch341.dll,我這裏使用的是USBIOX.DLL(內容基本上是相同的),有須要的能夠到下面網盤地址下載數組
連接: https://pan.baidu.com/s/1-PafH2pX1A9DvEprGciXRw 提取碼: uqdh 併發
調用類函數:異步
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
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 }
主要I2C和SPI 操做代碼:ide
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
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 }
連接:C# SPI 讀寫SD卡函數