|
|
|
|
今回購入![]() LMUWF電源タップCH341AプログラマーUSBからUARTIIC SPII2Cコンバーターパラレルポートコンバーター ASIN: B09M3JPF65 |
![]() Ren He CH341A プログラミング器 ROMライター FLASH 24 25 コピー器 EEPROMルーティングUSBプログラマ メインボード ルート ASIN: B07LGNTJ29 |
![]() VKLSVAN CH341Aライター SPI Flashプログラミング器 24 25シリーズ EEPROM BIOS プログラマー + SOP8 ICテストクリップ 8ピン ASIN: B08HCJW1F5 |
![]() Rasbee CH341A プログラミング器 FLASH 24 25 コピー器 EEPROMルーティング USBプログラマ メインボード 焼きます 並行輸入品 ASIN: B01FVUI3I4 |
CH341DLL.H CH341DLL.LIB
CH341DLL.DLL
// WCH CH341A I2C control sample program #include <iostream> #include <iomanip> #include <Windows.h> #include <tchar.h> #include "CH341DLL.H" #pragma comment(lib,"./CH341DLL.LIB") #define SSD1306_I2C_ADDR 0x3C #define SSD1306_COMMAND 0x00 #define SSD1306_DATA 0x40 #define SSD1306_WIDTH 128 #define SSD1306_HEIGHT 64 BOOL sendCommand(ULONG iIndex, UCHAR iDevice, UCHAR command) { // I2C Write UCHAR iAddr = SSD1306_COMMAND; // SSD1306 OLED Register Address UCHAR iByte = command; // SSD1306 OLED Write Data Byte BOOL b = CH341WriteI2C(iIndex, iDevice, iAddr, iByte); // Display OFF return b; } BOOL sendCommandArray(ULONG iIndex, UCHAR iDevice, UCHAR commandArray[], ULONG arraySize) { // I2C Write UCHAR iAddr = SSD1306_COMMAND; // SSD1306 OLED Register Address UCHAR iByte; // Write Data Byte BOOL b; // Result for (int i = 0; i < arraySize; ++i) { iByte = commandArray[i]; // SSD1306 OLED Write Data Byte b = CH341WriteI2C(iIndex, iDevice, iAddr, iByte); // SSD1306 OLED Write Command、 if (!b) break; } return b; } BOOL sendDataBuffer(ULONG iIndex, UCHAR iDevice, ULONG iWriteLength, PVOID iWriteBuffer) { // I2C Transfer ULONG iTmpWriteLength = iWriteLength + 2; PUCHAR iTmpWriteBuffer = new UCHAR[iTmpWriteLength]; memcpy(&iTmpWriteBuffer[2], iWriteBuffer, iWriteLength); iTmpWriteBuffer[0] = iDevice << 1; // SSD1306 I2C Address (But Need Shifted) iTmpWriteBuffer[1] = SSD1306_DATA; // SSD1306 OLED Write Data BOOL b = CH341StreamI2C(iIndex, iTmpWriteLength, iTmpWriteBuffer, 0UL, NULL); delete[] iTmpWriteBuffer; return b; } int main() { // Device Index Number ULONG iIndex = 0; // Open Device HANDLE h = CH341OpenDevice(iIndex); // DLL verison ULONG dllVersion = CH341GetVersion(); std::cout << "DLL verison " << dllVersion << "\n"; // Driver version ULONG driverVersion = CH341GetDrvVersion(); std::cout << "Driver verison " << driverVersion << std::endl; // Device Name PVOID p = CH341GetDeviceName(iIndex); std::cout << "Device Name " << (PCHAR)p << std::endl; // IC verison 0x10=CH341,0x20=CH341A,0x30=CH341A3 ULONG icVersion = CH341GetVerIC(iIndex); std::cout << "IC version " << std::hex << icVersion << std::endl; // Reset Device BOOL b = CH341ResetDevice(iIndex); std::cout << "Reset Device " << b << std::endl; // Set serial stream mode // B1-B0: I2C SCL freq. 00=20KHz,01=100KHz,10=400KHz,11=750KHz // B2: SPI I/O mode, 0=D3 CLK/D5 OUT/D7 IMP, 1=D3 CLK/D5&D4 OUT/D7&D6 INP) // B7: SPI MSB/LSB, 0=LSB, 1=MSB // ULONG iMode = 0; // SCL = 10KHz // ULONG iMode = 1; // SCL = 100KHz ULONG iMode = 2; // SCL = 400KHz // ULONG iMode = 3; // SCL = 750KHz b = CH341SetStream(iIndex, iMode); std::cout << "Set Stream " << b << std::endl; // I2C Transfer UCHAR iDevice = 0x3C; // SSD1306 OLED I2C Address UCHAR iAddr; // SSD1306 OLED Register Address UCHAR iByte; // SSD1306 OLED Write Data Byte UCHAR oByte; // SSD1306 OLED Read Data Byte // Initialise SSD1306 OLED iAddr = 0x00; // SSD1306 OLED Write Command // Adafruit // 4.4 Actual Application Example // https://cdn-shop.adafruit.com/datasheets/UG-2864HSWEG01.pdf UCHAR initialization_command_array_adafruit[] = { 0xAE, // Set Display Off 0xD5, 0x80, // Set Display Clock Divide Ratio/Oscillator Frequency 0xA8, SSD1306_HEIGHT - 1, // Set Multiplex Ratio 0xD3, 0x00, // Set Display Offset 0x40, // Set Display Start Line 0x8D, 0x14, // Set Charge Pump, VCC Generated by Internal DC/DC Circuit 0xA1, // Set Segment Re-Map 0xC8, // Set COM Output Scan Direction #if (SSD1306_HEIGHT == 32) 0xDA, 0x02, // Set COM Pins Hardware Configuration #else 0xDA, 0x12, // Set COM Pins Hardware Configuration #endif 0x81, 0xCF, // * Set Contrast Control, VCC Generated by Internal DC/DC Circuit 0xD9, 0xF1, // * Set Pre-Charge Period, VCC Generated by Internal DC/DC Circuit 0xDB, 0x40, // Set VCOMH Deselect Level 0xA4, // Set Entire Display On/Off 0xA6, // Set Normal/Inverse Display // omit // Clear Screen 0xAF, // Set Display On }; // Waveshare // 3 Software Configuration // https://www.waveshare.com/w/upload/a/af/SSD1306-Revision_1.1.pdf UCHAR initialization_command_array_waveshare[] = { 0xAE, // Set Display Off 0xA8, SSD1306_HEIGHT - 1, // Set Multiplex Ratio 0xD3, 0x00, // Set Display Offset 0x40, // Set Display Start Line 0xA1, // Set Segment Re-Map 0xC8, // Set COM Output Scan Direction #if (SSD1306_HEIGHT == 32) 0xDA, 0x02, // Set COM Pins Hardware Configuration #else 0xDA, 0x12, // Set COM Pins Hardware Configuration #endif 0x81, 0x7F, // * Set Contrast Control // 0xD9, 0xF1, // * Set Pre-Charge Period, VCC Generated by Internal DC/DC Circuit // 0xDB, 0x40, // Set VCOMH Deselect Level 0xA4, // Set Entire Display On/Off 0xA6, // Set Normal/Inverse Display 0xD5, 0x80, // Set Display Clock Divide Ratio/Oscillator Frequency 0x8D, 0x14, // Set Charge Pump, VCC Generated by Internal DC/DC Circuit 0xAF, // Set Display On }; b = sendCommandArray(iIndex, iDevice, initialization_command_array_adafruit, sizeof(initialization_command_array_adafruit)); // b = sendCommandArray(iIndex, iDevice, initialization_command_array_waveshare, sizeof(initialization_command_array_waveshare)); for (UCHAR k = 0; k < 100; ++k) { for (UCHAR i = 0; i < SSD1306_HEIGHT / 8; ++i) { b = sendCommand(iIndex, iDevice, 0xB0 | i); // Set the current RAM page address. b = sendCommand(iIndex, iDevice, 0x00); // b = sendCommand(iIndex, iDevice, 0x10); // // Write Stream ULONG iWriteLength = SSD1306_WIDTH; UCHAR iWriteBuffer[SSD1306_WIDTH]; for (UCHAR j = 0; j < SSD1306_WIDTH; ++j) { iWriteBuffer[j] = j + i + k; } b = sendDataBuffer(iIndex, iDevice, iWriteLength, iWriteBuffer); Sleep(1); // 1ms Need Waiting // ??? // ULONG iDelay = 100UL; // b = CH341SetDelaymS(iIndex, iDelay); } } // Close Device CH341CloseDevice(iIndex); }
INT16 word2int16(UCHAR h, UCHAR l) { INT16 t = h << 8 | l; if (h & 0x80 != 0) t = -((65535 - t) + 1); return t; }
// I2C Transfer UCHAR iDevice = 0x68; // MPU-6050 I2C Address UCHAR iAddr; // MPU-6050 Register Address UCHAR iByte; // MPU-6050 Write Data Byte UCHAR oByte; // MPU-6050 Read Data Byte // Read iAddr = 0x75; // MPU-6050 Register Address WHO_AM_I b = CH341ReadI2C(iIndex, iDevice, iAddr, &oByte); std::cout << "Read " << b << " " << std::hex << (INT)oByte << std::endl; std::cout << std::dec; // Read Value Equals MPU-6050 I2C Address (0x68) // Read iAddr = 0x6B; // MPU-6050 Register Address PWR_MGMT_1 b = CH341ReadI2C(iIndex, iDevice, iAddr, &oByte); std::cout << "Read " << b << " " << std::hex << (INT)oByte << std::endl; std::cout << std::dec; // Write iAddr = 0x6B; // MPU-6050 Register Address PWR_MGMT_1 iByte = 0x00; // MPU-6050 Write Data 0x00 = Release SLEEP mode ( = Device to Active) b = CH341WriteI2C(iIndex, iDevice, iAddr, iByte); std::cout << "Write " << b << std::endl; // Read Write Stream ULONG iWriteLength; UCHAR iWriteBuffer[256]; ULONG iReadLength; UCHAR oReadBuffer[256]; iWriteLength = 2UL; iWriteBuffer[0] = iDevice << 1; // MPU-6050 I2C Address (But Need Shifted) iWriteBuffer[1] = 0x3B; // MPU-6050 Register Address ACCEL_XOUT_H (Start address of sensor data) iReadLength = 14UL; // 0x3B ACCEL_XOUT_H - 0x48 GYRO_ZOUT_L for (int i = 0; i < 100; ++i) { b = CH341StreamI2C(iIndex, iWriteLength, iWriteBuffer, iReadLength, oReadBuffer); std::cout << "Stream " << b << ","; if (true) { std::cout << std::hex; for (ULONG index = 0; index < iReadLength; ++index) { std::cout << " " << std::setw(2) << std::setfill('0') << (INT)oReadBuffer[index]; } std::cout << std::dec; } else { // Accelerometer FLOAT ACCEL_DIV = 16384.0; FLOAT ACCEL_XOUT = word2int16(oReadBuffer[0], oReadBuffer[1]) / ACCEL_DIV; FLOAT ACCEL_YOUT = word2int16(oReadBuffer[2], oReadBuffer[3]) / ACCEL_DIV; FLOAT ACCEL_ZOUT = word2int16(oReadBuffer[4], oReadBuffer[5]) / ACCEL_DIV; // Temperature // Temperature in degrees C = (TEMP_OUT Register Value as a signed quantity)/340 + 36.53 FLOAT TEMP_OUT = word2int16(oReadBuffer[6], oReadBuffer[7]) / 340.0 + 36.53; // Gyroscope FLOAT GYRO_DIV = 131.0; FLOAT GYRO_XOUT = word2int16(oReadBuffer[8], oReadBuffer[9]) / GYRO_DIV; FLOAT GYRO_YOUT = word2int16(oReadBuffer[10], oReadBuffer[11]) / GYRO_DIV; FLOAT GYRO_ZOUT = word2int16(oReadBuffer[12], oReadBuffer[13]) / GYRO_DIV; std::cout << std::fixed; std::cout << std::setprecision(3) << std::setw(7) << ACCEL_XOUT << ","; std::cout << std::setprecision(3) << std::setw(7) << ACCEL_YOUT << ","; std::cout << std::setprecision(3) << std::setw(7) << ACCEL_ZOUT << ","; std::cout << std::setprecision(3) << std::setw(9) << TEMP_OUT << ","; std::cout << std::setprecision(3) << std::setw(7) << GYRO_XOUT << ","; std::cout << std::setprecision(3) << std::setw(7) << GYRO_YOUT << ","; std::cout << std::setprecision(3) << std::setw(7) << GYRO_ZOUT; } std::cout << std::endl; Sleep(100); }