|
|
|
|
今回購入![]() 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);
}




