Init
This commit is contained in:
commit
799590bc1d
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
build
|
||||||
48
SP713.pro
Executable file
48
SP713.pro
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
CONFIG += c++17
|
||||||
|
|
||||||
|
# You can make your code fail to compile if it uses deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
RC_ICONS = sp713.ico
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
apps/crc16/crc.cpp \
|
||||||
|
apps/icd/app_icd.cpp \
|
||||||
|
drivers/log/logHandler.cpp \
|
||||||
|
drivers/spi/drv_spi.cpp \
|
||||||
|
drivers/uart/drv_uart.cpp \
|
||||||
|
main.cpp \
|
||||||
|
mainwindow.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
apps/crc16/crc.h \
|
||||||
|
apps/icd/app_icd.h \
|
||||||
|
drivers/log/logHandler.h \
|
||||||
|
drivers/spi/drv_spi.h \
|
||||||
|
drivers/uart/drv_uart.h \
|
||||||
|
libs/CH347DLL.H \
|
||||||
|
libs/Common.h \
|
||||||
|
libs/SpiApi.h \
|
||||||
|
mainwindow.h
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
mainwindow.ui
|
||||||
|
|
||||||
|
#add libs
|
||||||
|
LIBS += -L$$PWD/libs -lCH347DLLA64
|
||||||
|
INCLUDEPATH += $$PWD/libs
|
||||||
|
win32:LIBS += $$PWD/libs/CH347DLLA64.LIB
|
||||||
|
|
||||||
|
LIBS += -L$$PWD/libs -lCH347Handler
|
||||||
|
INCLUDEPATH += $$PWD/libs
|
||||||
|
win32:LIBS += $$PWD/libs/CH347Handler.lib
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
42
apps/crc16/crc.cpp
Executable file
42
apps/crc16/crc.cpp
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#include "crc.h"
|
||||||
|
|
||||||
|
// 函数声明
|
||||||
|
// void generate_crc16_reverse_table(quint16 *table);
|
||||||
|
// QByteArray crc16Reverse(const QByteArray& data);
|
||||||
|
|
||||||
|
static void generate_crc16_reverse_table(quint16 table[256], quint16 poly = 0x8408)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 256; ++i) {
|
||||||
|
quint16 crc = static_cast<quint16>(i);
|
||||||
|
for (int j = 0; j < 8; ++j) {
|
||||||
|
if (crc & 0x0001)
|
||||||
|
crc = (crc >> 1) ^ poly;
|
||||||
|
else
|
||||||
|
crc >>= 1;
|
||||||
|
}
|
||||||
|
table[i] = crc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算反射型CRC16-CCITT
|
||||||
|
QByteArray crc16Reverse(const QByteArray& data)
|
||||||
|
{
|
||||||
|
static quint16 table[256];
|
||||||
|
static bool tableInited = false;
|
||||||
|
if (!tableInited) {
|
||||||
|
generate_crc16_reverse_table(table);
|
||||||
|
tableInited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 crc = 0x6363;
|
||||||
|
for (auto b : data)
|
||||||
|
crc = (crc >> 8) ^ table[(crc ^ static_cast<quint8>(b)) & 0xFF];
|
||||||
|
|
||||||
|
QByteArray result;
|
||||||
|
// 经过和python程序对比,说明CRC16的两个byte位置需调换
|
||||||
|
// result.append(static_cast<char>((crc >> 8) & 0xFF));
|
||||||
|
// result.append(static_cast<char>(crc & 0xFF));
|
||||||
|
result.append(static_cast<char>(crc & 0xFF));
|
||||||
|
result.append(static_cast<char>((crc >> 8) & 0xFF));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
10
apps/crc16/crc.h
Executable file
10
apps/crc16/crc.h
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef CRC_H
|
||||||
|
#define CRC_H
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
// 直接计算反射型CRC16-CCITT,输出低字节在前的QByteArray
|
||||||
|
QByteArray crc16Reverse(const QByteArray& data);
|
||||||
|
// void generate_crc16_reverse_table(quint16 table[256]);
|
||||||
|
|
||||||
|
#endif // CRC_H
|
||||||
315
apps/icd/app_icd.cpp
Executable file
315
apps/icd/app_icd.cpp
Executable file
@ -0,0 +1,315 @@
|
|||||||
|
#include "app_icd.h"
|
||||||
|
#include <QDebug> // 用于调试输出
|
||||||
|
#include "apps/crc16/crc.h"
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
APP_Icd::APP_Icd(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
// 创建驱动实例
|
||||||
|
this->m_spiDriver = new DRV_Spi(this);
|
||||||
|
this->m_uartDriver = new DRV_Uart(this);
|
||||||
|
// 初始化协议帧相关参数的大小
|
||||||
|
this->ICD_ctrlPara.resize(11);
|
||||||
|
this->ICD_volValuePara.resize(320);
|
||||||
|
this->ICD_allData.resize(340);
|
||||||
|
// 初始化协议帧相关参数的初值
|
||||||
|
this->ICD_allData.fill(0x00);
|
||||||
|
this->ICD_ctrlPara.fill(0x00);
|
||||||
|
this->ICD_volValuePara.fill(0x00);
|
||||||
|
// 设置包头
|
||||||
|
this->ICD_allData[0] = 0x9F;
|
||||||
|
this->ICD_allData[1] = 0xE4;
|
||||||
|
}
|
||||||
|
|
||||||
|
APP_Icd::~APP_Icd()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool APP_Icd::ICD_init()
|
||||||
|
{
|
||||||
|
if(!ICD_initSpi()) {
|
||||||
|
qWarning() << "SPI initialization failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ICD_initUart()) {
|
||||||
|
qWarning() << "UART initialization failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool APP_Icd::ICD_initSpi()
|
||||||
|
{
|
||||||
|
// 这里添加SPI初始化逻辑
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool APP_Icd::ICD_initUart()
|
||||||
|
{
|
||||||
|
// //枚举当前的uart设备号
|
||||||
|
// this->m_uartDriver->Uart_enumDevice();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 计算QByteArray的累加和校验
|
||||||
|
* @param data 输入数据
|
||||||
|
* @param endPos 截止位置(-1表示计算到末尾)
|
||||||
|
* @return 累加和(溢出自动截断为8位)
|
||||||
|
*/
|
||||||
|
quint8 APP_Icd::ICD_calcChecksum(const QByteArray &data, int endPos)
|
||||||
|
{
|
||||||
|
quint8 sum = 0;
|
||||||
|
if (data.isEmpty()) return sum;
|
||||||
|
|
||||||
|
// 计算有效长度
|
||||||
|
int length = (endPos < 0 || endPos >= data.size()) ?
|
||||||
|
data.size() : endPos + 1;
|
||||||
|
|
||||||
|
// 累加计算
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
sum += static_cast<quint8>(data.at(i)); // 自动处理溢出
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 电压命令编码
|
||||||
|
bool APP_Icd::ICD_volCMDProtoEncode(uint8_t CMD, uint8_t group, uint8_t subGroup)
|
||||||
|
{
|
||||||
|
//判断值是否超出范围
|
||||||
|
if((CMD > 0x03) || (group > 0xAA) || (subGroup > 0xAA))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 设置控制字参数
|
||||||
|
this->ICD_ctrlPara[0] = group;
|
||||||
|
this->ICD_ctrlPara[1] = subGroup;
|
||||||
|
|
||||||
|
// 调用主协议编码函数
|
||||||
|
return this->ICD_sumProtoEncode(CMD, this->ICD_ctrlPara);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写寄存器命令编码
|
||||||
|
bool APP_Icd::ICD_regWCMDProtoEncode(uint8_t dacID, uint8_t dacCH, uint8_t funcEN, uint8_t adcCurrConfig)
|
||||||
|
{
|
||||||
|
//判断值是否超出范围
|
||||||
|
// if((funcEN > 0x0F))
|
||||||
|
// return false;
|
||||||
|
|
||||||
|
// 填充默认值0
|
||||||
|
this->ICD_ctrlPara.fill(0x00);
|
||||||
|
|
||||||
|
// 设置控制字参数
|
||||||
|
this->ICD_ctrlPara[0] = dacID;
|
||||||
|
this->ICD_ctrlPara[1] = dacCH;
|
||||||
|
this->ICD_ctrlPara[2] = funcEN;
|
||||||
|
this->ICD_ctrlPara[3] = adcCurrConfig;
|
||||||
|
|
||||||
|
// 调用主协议编码函数
|
||||||
|
return this->ICD_sumProtoEncode(SP_CMD_REG_WR, this->ICD_ctrlPara);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写寄存器命令编码
|
||||||
|
bool APP_Icd::ICD_regRCMDProtoEncode(uint8_t dacID)
|
||||||
|
{
|
||||||
|
//判断值是否超出范围
|
||||||
|
if((dacID > 0x14))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 填充默认值0
|
||||||
|
this->ICD_ctrlPara.fill(0x00);
|
||||||
|
|
||||||
|
// 设置控制字参数
|
||||||
|
this->ICD_ctrlPara[0] = dacID;
|
||||||
|
|
||||||
|
// 调用主协议编码函数
|
||||||
|
return this->ICD_sumProtoEncode(SP_CMD_REG_RD, this->ICD_ctrlPara);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool APP_Icd::ICD_sumProtoEncode(uint8_t CMD, const QByteArray &ctrl_data)
|
||||||
|
{
|
||||||
|
// this->ICD_allData.resize(338);
|
||||||
|
// 设置控制字指令
|
||||||
|
this->ICD_allData[2] = CMD;
|
||||||
|
// 将控制字参数添加到主协议帧上
|
||||||
|
this->ICD_allData.replace(3, ctrl_data.size(), ctrl_data);
|
||||||
|
// 设置帧计数
|
||||||
|
this->ICD_allData[14] = this->ICD_allData[14] + 1;
|
||||||
|
// 设置校验和
|
||||||
|
this->ICD_allData[15] = this->ICD_calcChecksum(this->ICD_allData, 14);
|
||||||
|
// 设置电压类型:同值为0x01,异值为0x02
|
||||||
|
if((CMD == SP_CMD_SAME_VALUE) || (CMD == SP_CMD_DIF_VALUE)){
|
||||||
|
this->ICD_allData[16] = CMD - 1;
|
||||||
|
}else{
|
||||||
|
this->ICD_allData[16] = 0;
|
||||||
|
}
|
||||||
|
// 将256个10bit数据转化为320个字节的数据
|
||||||
|
this->ICD_pack10BitData(this->DAC256_10bit_data);
|
||||||
|
// 将电压参数赋值到allData中
|
||||||
|
this->ICD_allData.replace(17, ICD_volValuePara.size(), ICD_volValuePara);
|
||||||
|
// 计算320个字节的CRC16校验和
|
||||||
|
QByteArray crc16Result = crc16Reverse(this->ICD_volValuePara);
|
||||||
|
// 将CRC16校验和添加到ICD_allData中
|
||||||
|
this->ICD_allData.replace(337, crc16Result.size(), crc16Result);
|
||||||
|
// 设置校验和
|
||||||
|
this->ICD_allData[339] = this->ICD_calcChecksum(this->ICD_allData, 338);
|
||||||
|
// 调用串口/SPI发送函数
|
||||||
|
if(this->m_uartDriver->m_DRV_Uart_Infors.devIsOpened){
|
||||||
|
// 串口发送数据
|
||||||
|
this->m_uartDriver->Uart_Write(this->ICD_allData);
|
||||||
|
// 记录数据
|
||||||
|
this->ICD_addContextToDataRecordingFile(true, this->ICD_allData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置DAC256 10Bit参数
|
||||||
|
bool APP_Icd::ICD_setDAC256Data10bit(int row, int col, int value)
|
||||||
|
{
|
||||||
|
if((row > 15) || (col > 15) || (value > 1023))
|
||||||
|
return false;
|
||||||
|
this->DAC256_10bit_data[row][col] = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将256个10bit的数据转化为320个8bit数据
|
||||||
|
QByteArray APP_Icd::ICD_pack10BitData(int data[16][16]) {
|
||||||
|
|
||||||
|
quint32 bitBuffer = 0; // 32位缓冲区
|
||||||
|
int bitsInBuffer = 0; // 缓冲区中当前位数
|
||||||
|
|
||||||
|
this->ICD_volValuePara.clear();
|
||||||
|
|
||||||
|
for (int row = 0; row < 16; ++row) {
|
||||||
|
for (int col = 0; col < 16; ++col) {
|
||||||
|
// 确保数据是10位 (0-1023)
|
||||||
|
quint32 value = static_cast<quint32>(data[row][col]) & 0x3FF;
|
||||||
|
|
||||||
|
// 将10位值添加到缓冲区
|
||||||
|
bitBuffer = (bitBuffer << 10) | value;
|
||||||
|
bitsInBuffer += 10;
|
||||||
|
|
||||||
|
// 每当缓冲区有至少8位时,提取一个字节
|
||||||
|
while (bitsInBuffer >= 8) {
|
||||||
|
bitsInBuffer -= 8;
|
||||||
|
quint8 byte = static_cast<quint8>((bitBuffer >> bitsInBuffer) & 0xFF);
|
||||||
|
this->ICD_volValuePara.append(byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理缓冲区中剩余的位(如果有)
|
||||||
|
if (bitsInBuffer > 0) {
|
||||||
|
quint8 lastByte = static_cast<quint8>((bitBuffer << (8 - bitsInBuffer)) & 0xFF);
|
||||||
|
this->ICD_volValuePara.append(lastByte);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保输出正好是320字节(不足补零)
|
||||||
|
while (this->ICD_volValuePara.size() < 320) {
|
||||||
|
this->ICD_volValuePara.append('\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->ICD_volValuePara;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建数据记录文件
|
||||||
|
bool APP_Icd::ICD_newDataRecordingFile(void)
|
||||||
|
{
|
||||||
|
// 生成带时间戳的文件名
|
||||||
|
QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
|
||||||
|
QString fileName = QString("%1_%2.txt").arg("SP713_UART_SPI_Data_Recording").arg(timestamp);
|
||||||
|
|
||||||
|
// 创建文件并检查是否成功
|
||||||
|
QFile file(fileName);
|
||||||
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 关闭文件
|
||||||
|
file.close();
|
||||||
|
// 设置数据记录文件名
|
||||||
|
this->dataRecordingFile = fileName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加记录至txt文件
|
||||||
|
bool APP_Icd::ICD_addContextToDataRecordingFile(bool isWrite, QByteArray &Data)
|
||||||
|
{
|
||||||
|
if (this->dataRecordingFile.isEmpty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开文件(追加模式)
|
||||||
|
QFile file(this->dataRecordingFile);
|
||||||
|
if (!file.open(QIODevice::Append | QIODevice::Text))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextStream out(&file);
|
||||||
|
|
||||||
|
// 写入时间戳和特定字符串
|
||||||
|
QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
|
||||||
|
if(isWrite){
|
||||||
|
out << timestamp << " tx data: "; // 时间戳和特定字符串
|
||||||
|
}else{
|
||||||
|
out << timestamp << " rx data: "; // 时间戳和特定字符串
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将QByteArray转换为16进制字符串,用空格分隔
|
||||||
|
QString hexData = Data.toHex(' ').toUpper();
|
||||||
|
out << hexData << "\n"; // 写入16进制数据并换行
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析函数
|
||||||
|
ParsedData APP_Icd::ICD_parseRegisterData(const QByteArray &revData) {
|
||||||
|
ParsedData result = {};
|
||||||
|
|
||||||
|
// 检查数据长度 (至少需要7个字节: REG7-REG1)
|
||||||
|
if(revData.size() < 7) {
|
||||||
|
qWarning() << "Invalid data length, expected at least 7 bytes";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从REG7到REG1解析 (数据顺序是REG7在前)
|
||||||
|
const uchar *data = reinterpret_cast<const uchar*>(revData.constData());
|
||||||
|
|
||||||
|
// REG2 (索引5,因为数据顺序是REG7(0),REG6(1),...,REG1(6))
|
||||||
|
result.EN_TADC = (data[5] >> 7) & 0x01;
|
||||||
|
result.N_CLKDIV18 = ((data[5] >> 5) & 0x03); // 取B6和B5
|
||||||
|
result.VCON = ((data[5] >> 2) & 0x03); // 取B4和B3
|
||||||
|
result.CH_TEST = ((data[5] >> 1) & 0x01) << 8; // CH_TEST[8]
|
||||||
|
result.FBK_EN = (data[5]) & 0x01;
|
||||||
|
|
||||||
|
// REG3 (索引4)
|
||||||
|
result.TEMPTEST_EN = (data[4] >> 7) & 0x01;
|
||||||
|
result.TRIG_TADC = (data[4] >> 6) & 0x01;
|
||||||
|
result.TEST_TADC = (data[4] >> 5) & 0x01;
|
||||||
|
result.ICON18 = (data[4]) & 0x0F; // 取B4-B1
|
||||||
|
|
||||||
|
// REG4 (索引3)
|
||||||
|
result.CH_TEST |= data[3]; // CH_TEST[7:0]
|
||||||
|
|
||||||
|
// REG5 (索引2)
|
||||||
|
result.ADC_OUT = data[2]; // ADC_OUT[7:0]
|
||||||
|
|
||||||
|
// REG6 (索引1)
|
||||||
|
result.EOC = (data[1] >> 7) & 0x01;
|
||||||
|
result.ADC_OUT |= ((data[1] & 0x03) << 8); // ADC_OUT[9:8]
|
||||||
|
|
||||||
|
result.D_FB = ((data[1] >> 2) & 0x03); // D_FB[9:8]
|
||||||
|
|
||||||
|
// REG7 (索引0)
|
||||||
|
result.D_FB = (result.D_FB << 8) | data[0]; // D_FB[7:0]
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
142
apps/icd/app_icd.h
Executable file
142
apps/icd/app_icd.h
Executable file
@ -0,0 +1,142 @@
|
|||||||
|
#ifndef _APP_ICD_H__
|
||||||
|
#define _APP_ICD_H__
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "drivers/spi/drv_spi.h"
|
||||||
|
#include "drivers/uart/drv_uart.h"
|
||||||
|
|
||||||
|
// typedef struct _USB_DEVICE_DESCRIPTOR {
|
||||||
|
// UCHAR bLength;
|
||||||
|
// UCHAR bDescriptorType;
|
||||||
|
// USHORT bcdUSB;
|
||||||
|
// UCHAR bDeviceClass;
|
||||||
|
// UCHAR bDeviceSubClass;
|
||||||
|
// UCHAR bDeviceProtocol;
|
||||||
|
// UCHAR bMaxPacketSize0;
|
||||||
|
// USHORT idVendor;
|
||||||
|
// USHORT idProduct;
|
||||||
|
// USHORT bcdDevice;
|
||||||
|
// UCHAR iManufacturer;
|
||||||
|
// UCHAR iProduct;
|
||||||
|
// UCHAR iSerialNumber;
|
||||||
|
// UCHAR bNumConfigurations;
|
||||||
|
// } USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
|
||||||
|
|
||||||
|
// typedef struct _DRV_SPI_INFO
|
||||||
|
// {
|
||||||
|
// CHAR bDeviceName[256]; //设备名称
|
||||||
|
// mDeviceInforS SpiI2cDevInfor[16]; //spiI2c设备信息
|
||||||
|
// ULONG ulDevCnt; //设备数量
|
||||||
|
// BOOL devIsOpened; //设备开启标志位
|
||||||
|
// ULONG opendDevIndex; //当前设备索引号
|
||||||
|
// }mDRV_Spi_Infors;
|
||||||
|
|
||||||
|
// 使用结构体存储更复杂的数据
|
||||||
|
// struct ComboBoxSubGroupItem {
|
||||||
|
// QString displayText;
|
||||||
|
// int value;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// 解析结果结构体
|
||||||
|
struct ParsedData {
|
||||||
|
quint8 EN_TADC;
|
||||||
|
quint8 N_CLKDIV18; // 2位组合值
|
||||||
|
quint8 VCON; // 2位组合值
|
||||||
|
quint16 CH_TEST; // 9位组合值 (CH_TEST[8:0])
|
||||||
|
quint8 FBK_EN;
|
||||||
|
quint8 TEMPTEST_EN;
|
||||||
|
quint8 TRIG_TADC;
|
||||||
|
quint8 TEST_TADC;
|
||||||
|
quint8 ICON18; // 4位组合值
|
||||||
|
quint16 ADC_OUT; // 10位组合值 (ADC_OUT[9:0])
|
||||||
|
quint8 EOC;
|
||||||
|
quint16 D_FB; // 10位组合值 (D_FB[9:0])
|
||||||
|
};
|
||||||
|
|
||||||
|
// 命令枚举值
|
||||||
|
enum {
|
||||||
|
SP_CMD_NA = 0x00, // 无效命令
|
||||||
|
SP_CMD_ZERO = 0x01, // 参数归零命令
|
||||||
|
SP_CMD_SAME_VALUE = 0x02, // 同值配置命令
|
||||||
|
SP_CMD_DIF_VALUE = 0x03, // 异值配置命令
|
||||||
|
SP_CMD_REG_WR = 0x04, // 寄存器配置命令
|
||||||
|
SP_CMD_REG_RD = 0x05, // 寄存器读取命令
|
||||||
|
};
|
||||||
|
|
||||||
|
class APP_Icd : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT // 如果需要使用QT的信号槽机制
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief 构造函数
|
||||||
|
* @param parent 父对象指针
|
||||||
|
*/
|
||||||
|
explicit APP_Icd(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 析构函数
|
||||||
|
*/
|
||||||
|
virtual ~APP_Icd();
|
||||||
|
|
||||||
|
/*************函数定义*************/
|
||||||
|
bool ICD_init(); // ICD初始化
|
||||||
|
bool ICD_setDAC256Data10bit(int row, int col, int value); // 设置DAC256 10bit数组的值大小
|
||||||
|
bool ICD_volCMDProtoEncode(uint8_t CMD, uint8_t group, uint8_t subGroup);
|
||||||
|
quint8 ICD_calcChecksum(const QByteArray &data, int endPos);
|
||||||
|
bool ICD_sumProtoEncode(uint8_t CMD, const QByteArray &ctrl_data);
|
||||||
|
QByteArray ICD_pack10BitData(int data[16][16]);
|
||||||
|
bool ICD_regWCMDProtoEncode(uint8_t dacID, uint8_t dacCH, uint8_t funcEN, uint8_t adcCurrConfig);
|
||||||
|
bool ICD_regRCMDProtoEncode(uint8_t dacID);
|
||||||
|
bool ICD_newDataRecordingFile(void);
|
||||||
|
bool ICD_addContextToDataRecordingFile(bool isWrite, QByteArray &Data);
|
||||||
|
ParsedData ICD_parseRegisterData(const QByteArray &revData);
|
||||||
|
|
||||||
|
/*************变量定义*************/
|
||||||
|
// mDRV_Spi_Infors m_DRV_Spi_Infors; //Spi驱动相关信息
|
||||||
|
DRV_Spi *m_spiDriver; // SPI驱动实例
|
||||||
|
DRV_Uart *m_uartDriver; // UART驱动实例
|
||||||
|
|
||||||
|
// 定义子分组的所有名称数据集
|
||||||
|
QMap<int, QStringList> comboBox_subGroupInfo = {
|
||||||
|
{0, {"所有DAC"}}, // 对应选项1
|
||||||
|
{1, {"A分组所有DAC", "B分组所有DAC"}}, // 对应选项2
|
||||||
|
{2, {"OPA分组0", "OPA分组1", "OPA分组2", "OPA分组3", "OPA分组4"}}, // 对应选项3
|
||||||
|
{3, {"编号1", "编号2", "编号3", "编号4", "编号5", // 对应选项3
|
||||||
|
"编号6", "编号7", "编号8", "编号9", "编号10",
|
||||||
|
"编号11", "编号12", "编号13", "编号14", "编号15",
|
||||||
|
"编号16", "编号17", "编号18", "编号19", "编号20"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 256个10bit数据
|
||||||
|
int DAC256_10bit_data[16][16] = {{0}};
|
||||||
|
// 控制字参数
|
||||||
|
QByteArray ICD_ctrlPara;
|
||||||
|
// 电压值参数
|
||||||
|
QByteArray ICD_volValuePara;
|
||||||
|
// 整体帧
|
||||||
|
QByteArray ICD_allData;
|
||||||
|
QString dataRecordingFile;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// 可以添加DAC特定的信号
|
||||||
|
// void outputChanged(int channel, double value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 私有成员变量
|
||||||
|
// double m_currentValues[]; // 当前各通道输出值(假设有多个通道)
|
||||||
|
|
||||||
|
// 私有方法
|
||||||
|
bool ICD_initSpi();
|
||||||
|
bool ICD_initUart();
|
||||||
|
|
||||||
|
// 私有方法
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
56
drivers/log/logHandler.cpp
Executable file
56
drivers/log/logHandler.cpp
Executable file
@ -0,0 +1,56 @@
|
|||||||
|
#include "LogHandler.h"
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QMetaObject>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// 初始化静态成员
|
||||||
|
LogHandler* LogHandler::s_instance = nullptr;
|
||||||
|
QMutex LogHandler::s_mutex;
|
||||||
|
|
||||||
|
LogHandler::LogHandler(QObject *parent) : QObject(parent), m_logWidget(nullptr) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取单例实例(线程安全)
|
||||||
|
LogHandler* LogHandler::log_instance() {
|
||||||
|
if (!s_instance) {
|
||||||
|
QMutexLocker locker(&s_mutex);
|
||||||
|
if (!s_instance) {
|
||||||
|
s_instance = new LogHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化日志输出目标
|
||||||
|
void LogHandler::log_init(QPlainTextEdit *logWidget) {
|
||||||
|
LogHandler *handler = log_instance();
|
||||||
|
handler->m_logWidget = logWidget;
|
||||||
|
qInstallMessageHandler(log_handleMessage); // 注册消息处理器
|
||||||
|
}
|
||||||
|
|
||||||
|
// 静态消息处理函数
|
||||||
|
void LogHandler::log_handleMessage(QtMsgType type, const QMessageLogContext &, const QString &msg) {
|
||||||
|
LogHandler *handler = log_instance();
|
||||||
|
if (!handler) return;
|
||||||
|
|
||||||
|
// 格式化日志消息(添加时间和日志级别)
|
||||||
|
QString timestamp = QDateTime::currentDateTime().toString("[hh:mm:ss.zzz] ");
|
||||||
|
QString level;
|
||||||
|
switch (type) {
|
||||||
|
case QtDebugMsg: level = "DEBUG"; break;
|
||||||
|
case QtInfoMsg: level = "INFO"; break;
|
||||||
|
case QtWarningMsg: level = "WARN"; break;
|
||||||
|
case QtCriticalMsg: level = "ERROR"; break;
|
||||||
|
case QtFatalMsg: level = "FATAL"; break;
|
||||||
|
}
|
||||||
|
QString formattedMsg = QString("%1[%2] %3").arg(timestamp, level, msg);
|
||||||
|
|
||||||
|
// 如果有UI组件,通过信号槽更新(线程安全)
|
||||||
|
if (handler->m_logWidget) {
|
||||||
|
emit handler->log_messageLogged(formattedMsg);
|
||||||
|
} else {
|
||||||
|
// 无UI时输出到控制台
|
||||||
|
std::cerr << formattedMsg.toStdString() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
drivers/log/logHandler.h
Executable file
31
drivers/log/logHandler.h
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef __LOG_HANDLER_H__
|
||||||
|
#define __LOG_HANDLER_H__
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
class LogHandler : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
// 获取单例实例
|
||||||
|
static LogHandler* log_instance();
|
||||||
|
|
||||||
|
// 初始化日志输出目标(UI控件)
|
||||||
|
static void log_init(QPlainTextEdit *logWidget = nullptr);
|
||||||
|
|
||||||
|
// Qt 消息处理函数(静态)
|
||||||
|
static void log_handleMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// 日志信号(用于跨线程传递)
|
||||||
|
void log_messageLogged(const QString &formattedMsg);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit LogHandler(QObject *parent = nullptr);
|
||||||
|
static LogHandler *s_instance; // 单例实例
|
||||||
|
static QMutex s_mutex; // 线程安全锁
|
||||||
|
QPlainTextEdit *m_logWidget; // 日志输出UI组件
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
102
drivers/spi/drv_spi.cpp
Executable file
102
drivers/spi/drv_spi.cpp
Executable file
@ -0,0 +1,102 @@
|
|||||||
|
#include "drv_spi.h"
|
||||||
|
#include <QDebug> // 用于调试输出
|
||||||
|
|
||||||
|
DRV_Spi::DRV_Spi(QObject *parent)
|
||||||
|
: QObject(parent) // 假设有8个通道
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DRV_Spi::~DRV_Spi()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//枚举当前的所有SPI设备:返回搜索到的设备数目
|
||||||
|
ULONG DRV_Spi::spi_enumDevice()
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
mDeviceInforS DevInfor = {0};
|
||||||
|
|
||||||
|
UCHAR iDriverVer = 0;
|
||||||
|
UCHAR iDLLVer = 0;
|
||||||
|
UCHAR ibcdDevice = 0;
|
||||||
|
UCHAR iChipType = 0;
|
||||||
|
|
||||||
|
// 当前设备数目清零
|
||||||
|
this->m_DRV_Spi_Infors.ulDevCnt = 0;
|
||||||
|
|
||||||
|
// 依次搜索设备
|
||||||
|
for(i=0;i<16;i++)
|
||||||
|
{
|
||||||
|
// 打开设备
|
||||||
|
if(CH347OpenDevice(i) != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
// 获取设备信息
|
||||||
|
CH347GetDeviceInfor(i,&DevInfor);
|
||||||
|
// 输出设备信息
|
||||||
|
DbgPrint("Manufacturer:%s Product:%s.", DevInfor.ManufacturerString, DevInfor.ProductString);
|
||||||
|
|
||||||
|
if(DevInfor.ChipMode == 3) //模式3此接口为JTAG/I2C
|
||||||
|
continue;
|
||||||
|
// 格式化设备名称
|
||||||
|
sprintf(this->m_DRV_Spi_Infors.bDeviceName, "%d# %s",i,DevInfor.FuncDescStr);
|
||||||
|
// 输出设备名称
|
||||||
|
DbgPrint("Dev Name:%s.", this->m_DRV_Spi_Infors.bDeviceName);
|
||||||
|
// copy设备信息至SpiI2cDevInfor结构体
|
||||||
|
memcpy(&this->m_DRV_Spi_Infors.SpiI2cDevInfor[this->m_DRV_Spi_Infors.ulDevCnt], &DevInfor,sizeof(DevInfor));
|
||||||
|
// 设备数量自增
|
||||||
|
this->m_DRV_Spi_Infors.ulDevCnt++;
|
||||||
|
// 获取版本号
|
||||||
|
CH347GetVersion(i, &iDriverVer, &iDLLVer, &ibcdDevice, &iChipType);
|
||||||
|
// 输出版本号
|
||||||
|
DbgPrint("Version: DV:%02x DLLV:%02x BCD:%02x CT:%02x.", iDriverVer, iDLLVer, ibcdDevice, iChipType);
|
||||||
|
}
|
||||||
|
// 关闭设备
|
||||||
|
CH347CloseDevice(i);
|
||||||
|
}
|
||||||
|
return this->m_DRV_Spi_Infors.ulDevCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//打开设备
|
||||||
|
bool DRV_Spi::spi_openDevice(ULONG SpiI2cGpioDevIndex)
|
||||||
|
{
|
||||||
|
// 获取所选的设备序号
|
||||||
|
if((SpiI2cGpioDevIndex < 0) || (SpiI2cGpioDevIndex > this->m_DRV_Spi_Infors.ulDevCnt))
|
||||||
|
{
|
||||||
|
DbgPrint("device index error!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 打开设备
|
||||||
|
this->m_DRV_Spi_Infors.devIsOpened = (CH347OpenDevice(SpiI2cGpioDevIndex) != INVALID_HANDLE_VALUE);
|
||||||
|
// 设置USB数据读写超时时间
|
||||||
|
CH347SetTimeout(SpiI2cGpioDevIndex,500,500);
|
||||||
|
// 输出调试信息
|
||||||
|
DbgPrint("Open the device...%s",this->m_DRV_Spi_Infors.devIsOpened?"Success":"Failed");
|
||||||
|
if(!this->m_DRV_Spi_Infors.devIsOpened)
|
||||||
|
return false;
|
||||||
|
// 设置当前打开设备的索引号
|
||||||
|
this->m_DRV_Spi_Infors.opendDevIndex = SpiI2cGpioDevIndex;
|
||||||
|
return true;
|
||||||
|
// CH347InitSpi();
|
||||||
|
}
|
||||||
|
|
||||||
|
//关闭设备
|
||||||
|
bool DRV_Spi::spi_closeDevice()
|
||||||
|
{
|
||||||
|
// 判断当前设备是否开启
|
||||||
|
if(!this->m_DRV_Spi_Infors.devIsOpened)
|
||||||
|
{
|
||||||
|
DbgPrint("The Device not open!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 关闭当前正在开启的设备
|
||||||
|
CH347CloseDevice(this->m_DRV_Spi_Infors.opendDevIndex);
|
||||||
|
// 设置设备打开标志位为FALSE
|
||||||
|
this->m_DRV_Spi_Infors.devIsOpened = FALSE;
|
||||||
|
// 输出信息
|
||||||
|
DbgPrint("Close the Device!");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
72
drivers/spi/drv_spi.h
Executable file
72
drivers/spi/drv_spi.h
Executable file
@ -0,0 +1,72 @@
|
|||||||
|
#ifndef _DRV_SPI_H__
|
||||||
|
#define _DRV_SPI_H__
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
#include "libs/CH347DLL.H"
|
||||||
|
|
||||||
|
#define DbgPrint(format, ...) qDebug().nospace() << QString::asprintf(format, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
typedef struct _USB_DEVICE_DESCRIPTOR {
|
||||||
|
UCHAR bLength;
|
||||||
|
UCHAR bDescriptorType;
|
||||||
|
USHORT bcdUSB;
|
||||||
|
UCHAR bDeviceClass;
|
||||||
|
UCHAR bDeviceSubClass;
|
||||||
|
UCHAR bDeviceProtocol;
|
||||||
|
UCHAR bMaxPacketSize0;
|
||||||
|
USHORT idVendor;
|
||||||
|
USHORT idProduct;
|
||||||
|
USHORT bcdDevice;
|
||||||
|
UCHAR iManufacturer;
|
||||||
|
UCHAR iProduct;
|
||||||
|
UCHAR iSerialNumber;
|
||||||
|
UCHAR bNumConfigurations;
|
||||||
|
} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
|
||||||
|
|
||||||
|
typedef struct _DRV_SPI_INFO
|
||||||
|
{
|
||||||
|
CHAR bDeviceName[256]; //设备名称
|
||||||
|
mDeviceInforS SpiI2cDevInfor[16]; //spiI2c设备信息
|
||||||
|
ULONG ulDevCnt; //设备数量
|
||||||
|
BOOL devIsOpened; //设备开启标志位
|
||||||
|
ULONG opendDevIndex; //当前设备索引号
|
||||||
|
}mDRV_Spi_Infors;
|
||||||
|
|
||||||
|
class DRV_Spi : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT // 如果需要使用QT的信号槽机制
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief 构造函数
|
||||||
|
* @param parent 父对象指针
|
||||||
|
*/
|
||||||
|
explicit DRV_Spi(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 析构函数
|
||||||
|
*/
|
||||||
|
virtual ~DRV_Spi();
|
||||||
|
|
||||||
|
/*************函数定义*************/
|
||||||
|
ULONG spi_enumDevice(); // 枚举SPI设备
|
||||||
|
bool spi_openDevice(ULONG SpiI2cGpioDevIndex); // 打开设备
|
||||||
|
bool spi_closeDevice(); // 关闭设备
|
||||||
|
|
||||||
|
/*************变量定义*************/
|
||||||
|
mDRV_Spi_Infors m_DRV_Spi_Infors; //Spi驱动相关信息
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// 可以添加DAC特定的信号
|
||||||
|
// void outputChanged(int channel, double value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 私有成员变量
|
||||||
|
// double m_currentValues[]; // 当前各通道输出值(假设有多个通道)
|
||||||
|
|
||||||
|
// 私有方法
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
155
drivers/uart/drv_uart.cpp
Executable file
155
drivers/uart/drv_uart.cpp
Executable file
@ -0,0 +1,155 @@
|
|||||||
|
#include "drv_uart.h"
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDebug> // 用于调试输出
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
DRV_Uart::DRV_Uart(QObject *parent)
|
||||||
|
: QObject(parent) // 假设有8个通道
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DRV_Uart::~DRV_Uart()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 枚举当前的所有UART设备:返回搜索到的设备数目
|
||||||
|
ULONG DRV_Uart::Uart_enumDevice()
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
mDeviceInforS DevInfor = {0};
|
||||||
|
|
||||||
|
// 当前设备数目清零
|
||||||
|
this->m_DRV_Uart_Infors.ulDevCnt = 0;
|
||||||
|
|
||||||
|
// 依次搜索设备
|
||||||
|
for(i=0;i<16;i++)
|
||||||
|
{
|
||||||
|
// 打开设备
|
||||||
|
if(CH347Uart_Open(i) != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
// 获取设备信息
|
||||||
|
CH347Uart_GetDeviceInfor(i,&DevInfor);
|
||||||
|
// 格式化设备名称
|
||||||
|
sprintf(this->m_DRV_Uart_Infors.bDeviceName[this->m_DRV_Uart_Infors.ulDevCnt], "%d# %s", i,DevInfor.FuncDescStr);
|
||||||
|
// 输出设备名称
|
||||||
|
DbgPrint("UART:%s.", this->m_DRV_Uart_Infors.bDeviceName[this->m_DRV_Uart_Infors.ulDevCnt]);
|
||||||
|
|
||||||
|
// copy设备信息至SpiI2cDevInfor结构体
|
||||||
|
memcpy(&this->m_DRV_Uart_Infors.UartDevInfor[this->m_DRV_Uart_Infors.ulDevCnt], &DevInfor,sizeof(DevInfor));
|
||||||
|
// 设备数量自增
|
||||||
|
this->m_DRV_Uart_Infors.ulDevCnt++;
|
||||||
|
}
|
||||||
|
// 关闭设备
|
||||||
|
CH347CloseDevice(i);
|
||||||
|
}
|
||||||
|
return this->m_DRV_Uart_Infors.ulDevCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//打开设备
|
||||||
|
BOOL DRV_Uart::Uart_openDevice(ULONG UartIndex)
|
||||||
|
{
|
||||||
|
// 判断设备的索引是否在正确的范围内,否则直接跳出
|
||||||
|
if((this->m_DRV_Uart_Infors.ulDevCnt == 0) || (UartIndex >= this->m_DRV_Uart_Infors.ulDevCnt))
|
||||||
|
{
|
||||||
|
DbgPrint("Failed to open the device. Please refresh device first!");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// 打开串口设备
|
||||||
|
this->m_DRV_Uart_Infors.devIsOpened = (CH347Uart_Open(UartIndex) != INVALID_HANDLE_VALUE);
|
||||||
|
// 判断是否打开成功
|
||||||
|
if(this->m_DRV_Uart_Infors.devIsOpened){
|
||||||
|
// 设置当前的设备索引号
|
||||||
|
this->m_DRV_Uart_Infors.opendDevIndex = UartIndex;
|
||||||
|
// 设置默认的延迟时间
|
||||||
|
CH347Uart_SetTimeout(UartIndex,500,500);
|
||||||
|
// 设置接收和发送线程
|
||||||
|
// StopTxThread = FALSE;
|
||||||
|
// StopRxThread = FALSE;
|
||||||
|
}
|
||||||
|
// 显示日志信息
|
||||||
|
DbgPrint(">>%d#Open Device...%s",UartIndex,this->m_DRV_Uart_Infors.devIsOpened?"Success":"Failed");
|
||||||
|
return this->m_DRV_Uart_Infors.devIsOpened;
|
||||||
|
}
|
||||||
|
|
||||||
|
//关闭设备
|
||||||
|
BOOL DRV_Uart::Uart_closeDevice()
|
||||||
|
{
|
||||||
|
// 设置接收和发送线程
|
||||||
|
// StopTxThread = TRUE;
|
||||||
|
// StopRxThread = TRUE;
|
||||||
|
// 判断是否打开成功
|
||||||
|
if(this->m_DRV_Uart_Infors.devIsOpened){
|
||||||
|
Sleep(300);
|
||||||
|
CH347Uart_Close(this->m_DRV_Uart_Infors.opendDevIndex);
|
||||||
|
this->m_DRV_Uart_Infors.devIsOpened = FALSE;
|
||||||
|
DbgPrint(">>%d#Close device",this->m_DRV_Uart_Infors.opendDevIndex);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置串口参数
|
||||||
|
BOOL DRV_Uart::Uart_setPara(ULONG Baudrate, UCHAR StopBits, UCHAR Parity, UCHAR DataSize, UCHAR Timeout)
|
||||||
|
{
|
||||||
|
BOOL RetVal = FALSE;
|
||||||
|
|
||||||
|
if(this->m_DRV_Uart_Infors.devIsOpened){
|
||||||
|
RetVal = CH347Uart_Init(this->m_DRV_Uart_Infors.opendDevIndex,Baudrate,DataSize,Parity,StopBits,Timeout);
|
||||||
|
DbgPrint("Uart_Set %s,Baudrate:%d,DataSize:%d,Parity:%d,StopBits:%d,Timeout:%d",RetVal?"succ":"failure",
|
||||||
|
Baudrate,DataSize,Parity,StopBits,Timeout);
|
||||||
|
}
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
//串口发送数据
|
||||||
|
BOOL DRV_Uart::Uart_Write(QByteArray &sendData)
|
||||||
|
{
|
||||||
|
// 获取数据包的长度
|
||||||
|
ULONG OutLen = sendData.length();
|
||||||
|
// 将QByteArray转化为UCHAR
|
||||||
|
const UCHAR *OutBuf = reinterpret_cast<const unsigned char*>(sendData.constData());
|
||||||
|
|
||||||
|
BOOL RetVal = FALSE;
|
||||||
|
// 调用底层串口发送函数发送数据
|
||||||
|
RetVal = CH347Uart_Write(this->m_DRV_Uart_Infors.opendDevIndex, (UCHAR *)OutBuf, &OutLen);
|
||||||
|
// 日志窗口输出调试信息
|
||||||
|
DbgPrint("frame:%d,Uart_Write %dBytes %s.",sendData.at(14), OutLen,RetVal?"succ":"failure");
|
||||||
|
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
//读取串口缓冲区数据大小
|
||||||
|
LONGLONG DRV_Uart::Uart_readRxBufcnt(void)
|
||||||
|
{
|
||||||
|
LONGLONG rxBufSize = 0;
|
||||||
|
|
||||||
|
BOOL RetVal = FALSE;
|
||||||
|
// 调用底层串口接收数据缓冲区的大小
|
||||||
|
RetVal = CH347Uart_QueryBufUpload(this->m_DRV_Uart_Infors.opendDevIndex, &rxBufSize);
|
||||||
|
// 日志窗口输出调试信息
|
||||||
|
DbgPrint("read uart rx buf count:%d.", rxBufSize, RetVal?"succ":"failure");
|
||||||
|
|
||||||
|
return rxBufSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL DRV_Uart::Uart_Read(QByteArray &revData)
|
||||||
|
{
|
||||||
|
ULONG InLen = 4096; // 设置读取的长度,读取完后会将该值赋值为真实的长度
|
||||||
|
UCHAR InBuf[4096] = {0x00};
|
||||||
|
|
||||||
|
BOOL RetVal = FALSE;
|
||||||
|
|
||||||
|
// 读取串口数据
|
||||||
|
RetVal = CH347Uart_Read(this->m_DRV_Uart_Infors.opendDevIndex,InBuf,&InLen);
|
||||||
|
|
||||||
|
DbgPrint("CH347Uart_Read %dB %s.",InLen,RetVal?"succ":"failure");
|
||||||
|
|
||||||
|
if(RetVal)
|
||||||
|
{
|
||||||
|
//将数据存入revData变量中,返回给调用的函数
|
||||||
|
revData = QByteArray::fromRawData(reinterpret_cast<const char*>(InBuf), InLen);
|
||||||
|
}
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
75
drivers/uart/drv_uart.h
Executable file
75
drivers/uart/drv_uart.h
Executable file
@ -0,0 +1,75 @@
|
|||||||
|
#ifndef _DRV_UART_H__
|
||||||
|
#define _DRV_UART_H__
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
#include "libs/CH347DLL.H"
|
||||||
|
|
||||||
|
#define DbgPrint(format, ...) qDebug().nospace() << QString::asprintf(format, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
// typedef struct _USB_DEVICE_DESCRIPTOR {
|
||||||
|
// UCHAR bLength;
|
||||||
|
// UCHAR bDescriptorType;
|
||||||
|
// USHORT bcdUSB;
|
||||||
|
// UCHAR bDeviceClass;
|
||||||
|
// UCHAR bDeviceSubClass;
|
||||||
|
// UCHAR bDeviceProtocol;
|
||||||
|
// UCHAR bMaxPacketSize0;
|
||||||
|
// USHORT idVendor;
|
||||||
|
// USHORT idProduct;
|
||||||
|
// USHORT bcdDevice;
|
||||||
|
// UCHAR iManufacturer;
|
||||||
|
// UCHAR iProduct;
|
||||||
|
// UCHAR iSerialNumber;
|
||||||
|
// UCHAR bNumConfigurations;
|
||||||
|
// } USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
|
||||||
|
|
||||||
|
typedef struct _DRV_UART_INFO
|
||||||
|
{
|
||||||
|
CHAR bDeviceName[2][256]; //设备名称
|
||||||
|
mDeviceInforS UartDevInfor[16]; //spiI2c设备信息
|
||||||
|
ULONG ulDevCnt; //设备数量
|
||||||
|
BOOL devIsOpened; //设备开启标志位
|
||||||
|
ULONG opendDevIndex; //当前设备索引号
|
||||||
|
}mDRV_Uart_Infors;
|
||||||
|
|
||||||
|
class DRV_Uart : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT // 如果需要使用QT的信号槽机制
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief 构造函数
|
||||||
|
* @param parent 父对象指针
|
||||||
|
*/
|
||||||
|
explicit DRV_Uart(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 析构函数
|
||||||
|
*/
|
||||||
|
virtual ~DRV_Uart();
|
||||||
|
|
||||||
|
/*************函数定义*************/
|
||||||
|
ULONG Uart_enumDevice(); // 枚举UART设备
|
||||||
|
BOOL Uart_openDevice(ULONG UartIndex); // 打开设备
|
||||||
|
BOOL Uart_closeDevice(); // 关闭设备
|
||||||
|
BOOL Uart_setPara(ULONG Baudrate, UCHAR StopBits, UCHAR Parity, UCHAR DataSize, UCHAR Timeout);// 设置参数
|
||||||
|
BOOL Uart_Write(QByteArray &sendData);
|
||||||
|
LONGLONG Uart_readRxBufcnt(void);
|
||||||
|
BOOL Uart_Read(QByteArray &revData);
|
||||||
|
/*************变量定义*************/
|
||||||
|
mDRV_Uart_Infors m_DRV_Uart_Infors; //Spi驱动相关信息
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// 可以添加DAC特定的信号
|
||||||
|
// void outputChanged(int channel, double value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 私有成员变量
|
||||||
|
// double m_currentValues[]; // 当前各通道输出值(假设有多个通道)
|
||||||
|
|
||||||
|
// 私有方法
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
645
libs/CH347DLL.H
Executable file
645
libs/CH347DLL.H
Executable file
@ -0,0 +1,645 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** Copyright (C) WCH 2001-2025 **
|
||||||
|
** Web: http://wch.cn **
|
||||||
|
******************************************************************************/
|
||||||
|
// USB总线接口芯片CH341/7并口应用层接口库,CH347/9基于480Mbps高速USB总线扩展UART/SPI/I2C/JTAG/SWD
|
||||||
|
// CH346基于480Mbps高速USB总线扩展UART/SPI SLAVE,UART/PARALLEL SLAVE
|
||||||
|
// CH347-DLL V1.4
|
||||||
|
// 运行环境: Windows 98/ME, Windows 2000/XP, WIN7/8/10/11,and later.
|
||||||
|
// support USB chip: CH341, CH341A,CH347,CH339W
|
||||||
|
// USB => Parallel, I2C, SPI, JTAG, SWD, PARALLEL,UART ...
|
||||||
|
//Notes:
|
||||||
|
//Copyright (C) 2025 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _CH347_DLL_H
|
||||||
|
#define _CH347_DLL_H
|
||||||
|
|
||||||
|
#include <windows.h> // 确保 LONG 类型定义
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define mOFFSET( s, m ) ( (ULONG_PTR) & ( ( ( s * ) 0 ) -> m ) ) // 定义获取结构成员相对偏移地址的宏
|
||||||
|
#else
|
||||||
|
#define mOFFSET( s, m ) ( (ULONG) & ( ( ( s * ) 0 ) -> m ) ) // 定义获取结构成员相对偏移地址的宏
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef max
|
||||||
|
#define max( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) // 较大值
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) // 较小值
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ExAllocatePool
|
||||||
|
#undef ExAllocatePool // 删除带TAG的内存分配
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NTSTATUS
|
||||||
|
typedef LONG NTSTATUS; // 返回状态
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//与CH31DLL合用CH341WDM驱动
|
||||||
|
#ifndef _CH341_DLL_H
|
||||||
|
typedef struct _USB_SETUP_PKT { // USB控制传输的建立阶段的数据请求包结构
|
||||||
|
UCHAR mUspReqType; // 00H 请求类型
|
||||||
|
UCHAR mUspRequest; // 01H 请求代码
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR mUspValueLow; // 02H 值参数低字节
|
||||||
|
UCHAR mUspValueHigh; // 03H 值参数高字节
|
||||||
|
};
|
||||||
|
USHORT mUspValue; // 02H-03H 值参数
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR mUspIndexLow; // 04H 索引参数低字节
|
||||||
|
UCHAR mUspIndexHigh; // 05H 索引参数高字节
|
||||||
|
};
|
||||||
|
USHORT mUspIndex; // 04H-05H 索引参数
|
||||||
|
};
|
||||||
|
USHORT mLength; // 06H-07H 数据阶段的数据长度
|
||||||
|
} mUSB_SETUP_PKT, *mPUSB_SETUP_PKT;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _WIN32_COMMAND { // 定义WIN32命令接口结构
|
||||||
|
union {
|
||||||
|
ULONG mFunction; // 输入时指定功能代码或者管道号
|
||||||
|
NTSTATUS mStatus; // 输出时返回操作状态
|
||||||
|
};
|
||||||
|
ULONG mLength; // 存取长度,返回后续数据的长度
|
||||||
|
union {
|
||||||
|
mUSB_SETUP_PKT mSetupPkt; // USB控制传输的建立阶段的数据请求
|
||||||
|
UCHAR mBuffer[ 512]; // 数据缓冲区,长度为0至255B
|
||||||
|
};
|
||||||
|
} mWIN32_COMMAND, *mPWIN32_COMMAND;
|
||||||
|
// WIN32应用层接口命令
|
||||||
|
#define IOCTL_CH341_COMMAND ( FILE_DEVICE_UNKNOWN << 16 | FILE_ANY_ACCESS << 14 | 0x0f34 << 2 | METHOD_BUFFERED ) // 专用接口
|
||||||
|
|
||||||
|
#define mWIN32_COMMAND_HEAD mOFFSET( mWIN32_COMMAND, mBuffer ) // WIN32命令接口的头长度
|
||||||
|
|
||||||
|
#define mCH341_MAX_NUMBER 32 // 最多同时连接的CH341/7设备数量
|
||||||
|
|
||||||
|
#define mMAX_BUFFER_LENGTH 0x1000 // 数据缓冲区最大长度4096
|
||||||
|
|
||||||
|
#define mMAX_COMMAND_LENGTH ( mWIN32_COMMAND_HEAD + mMAX_BUFFER_LENGTH ) // 最大数据长度加上命令结构头的长度
|
||||||
|
|
||||||
|
#define mDEFAULT_BUFFER_LEN 0x0400 // 数据缓冲区默认长度1024
|
||||||
|
|
||||||
|
#define mDEFAULT_COMMAND_LEN ( mWIN32_COMMAND_HEAD + mDEFAULT_BUFFER_LEN ) // 默认数据长度加上命令结构头的长度
|
||||||
|
|
||||||
|
// CH341端点地址
|
||||||
|
#define mCH347_ENDP_DATA_UP 0x86 // CH347的数据块上传端点的地址
|
||||||
|
#define mCH347_ENDP_DATA_DOWN 0x06 // CH347的数据块下传端点的地址
|
||||||
|
|
||||||
|
// 设备层接口提供的管道操作命令
|
||||||
|
#define mPipeDeviceCtrl 0x00000004 // CH347的综合控制管道
|
||||||
|
#define mPipeDataUp 0x00000006 // CH347的数据块上传管道
|
||||||
|
#define mPipeDataDown 0x00000007 // CH347的数据块下传管道
|
||||||
|
|
||||||
|
// 应用层接口的功能代码
|
||||||
|
#define mFuncNoOperation 0x00000000 // 无操作
|
||||||
|
#define mFuncGetVersion 0x00000001 // 获取驱动程序版本号
|
||||||
|
#define mFuncGetConfig 0x00000002 // 获取USB设备配置描述符
|
||||||
|
#define mFuncSetTimeout 0x00000009 // 设置USB通讯超时
|
||||||
|
#define mFuncSetExclusive 0x0000000b // 设置独占使用
|
||||||
|
#define mFuncResetDevice 0x0000000c // 复位USB设备
|
||||||
|
#define mFuncResetPipe 0x0000000d // 复位USB管道
|
||||||
|
#define mFuncAbortPipe 0x0000000e // 取消USB管道的数据请求
|
||||||
|
#define mFuncBufferMode 0x00000020 // 设定缓冲上传模式及查询缓冲区中的数据长度
|
||||||
|
#define mFuncBufferModeDn 0x00000021 // 设定缓冲下传模式及查询缓冲区中的数据长度
|
||||||
|
#define mFuncGetVersionEx 0x00000022 // 获取驱动程序版本号及芯片型号
|
||||||
|
// USB设备标准请求代码
|
||||||
|
#define mUSB_CLR_FEATURE 0x01
|
||||||
|
#define mUSB_SET_FEATURE 0x03
|
||||||
|
#define mUSB_GET_STATUS 0x00
|
||||||
|
#define mUSB_SET_ADDRESS 0x05
|
||||||
|
#define mUSB_GET_DESCR 0x06
|
||||||
|
#define mUSB_SET_DESCR 0x07
|
||||||
|
#define mUSB_GET_CONFIG 0x08
|
||||||
|
#define mUSB_SET_CONFIG 0x09
|
||||||
|
#define mUSB_GET_INTERF 0x0a
|
||||||
|
#define mUSB_SET_INTERF 0x0b
|
||||||
|
#define mUSB_SYNC_FRAME 0x0c
|
||||||
|
|
||||||
|
// CH341控制传输的厂商专用请求类型
|
||||||
|
#define mCH341_VENDOR_READ 0xC0 // 通过控制传输实现的CH341厂商专用读操作
|
||||||
|
#define mCH341_VENDOR_WRITE 0x40 // 通过控制传输实现的CH341厂商专用写操作
|
||||||
|
|
||||||
|
#define mCH341A_CMD_I2C_STREAM 0xAA // I2C接口的命令包,从次字节开始为I2C命令流
|
||||||
|
#define mCH341A_CMD_UIO_STREAM 0xAB // UIO接口的命令包,从次字节开始为命令流
|
||||||
|
#define mCH341A_CMD_PIO_STREAM 0xAE // PIO接口的命令包,从次字节开始为数据流
|
||||||
|
// CH341A控制传输的厂商专用请求代码
|
||||||
|
#define mCH341A_BUF_CLEAR 0xB2 // 清除未完成的数据
|
||||||
|
#define mCH341A_I2C_CMD_X 0x54 // 发出I2C接口的命令,立即执行
|
||||||
|
#define mCH341A_DELAY_MS 0x5E // 以亳秒为单位延时指定时间
|
||||||
|
#define mCH341A_GET_VER 0x5F // 获取芯片版本
|
||||||
|
|
||||||
|
#define mCH341A_CMD_I2C_STM_STA 0x74 // I2C接口的命令流:产生起始位
|
||||||
|
#define mCH341A_CMD_I2C_STM_STO 0x75 // I2C接口的命令流:产生停止位
|
||||||
|
#define mCH341A_CMD_I2C_STM_OUT 0x80 // I2C接口的命令流:输出数据,位5-位0为长度,后续字节为数据,0长度则只发送一个字节并返回应答
|
||||||
|
#define mCH341A_CMD_I2C_STM_IN 0xC0 // I2C接口的命令流:输入数据,位5-位0为长度,0长度则只接收一个字节并发送无应答
|
||||||
|
#define mCH341A_CMD_I2C_STM_MAX ( min( 0x3F, mCH341_PACKET_LENGTH ) ) // I2C接口的命令流单个命令输入输出数据的最大长度
|
||||||
|
#define mCH341A_CMD_I2C_STM_SET 0x60 // I2C接口的命令流:设置参数,位2=SPI的I/O数(0=单入单出,1=双入双出),位1位0=I2C速度(00=低速,01=标准,10=快速,11=高速)
|
||||||
|
#define mCH341A_CMD_I2C_STM_US 0x40 // I2C接口的命令流:以微秒为单位延时,位3-位0为延时值
|
||||||
|
#define mCH341A_CMD_I2C_STM_MS 0x50 // I2C接口的命令流:以亳秒为单位延时,位3-位0为延时值
|
||||||
|
#define mCH341A_CMD_I2C_STM_DLY 0x0F // I2C接口的命令流单个命令延时的最大值
|
||||||
|
#define mCH341A_CMD_I2C_STM_END 0x00 // I2C接口的命令流:命令包提前结束
|
||||||
|
|
||||||
|
#define mCH341A_CMD_UIO_STM_IN 0x00 // UIO接口的命令流:输入数据D7-D0
|
||||||
|
#define mCH341A_CMD_UIO_STM_DIR 0x40 // UIO接口的命令流:设定I/O方向D5-D0,位5-位0为方向数据
|
||||||
|
#define mCH341A_CMD_UIO_STM_OUT 0x80 // UIO接口的命令流:输出数据D5-D0,位5-位0为数据
|
||||||
|
#define mCH341A_CMD_UIO_STM_US 0xC0 // UIO接口的命令流:以微秒为单位延时,位5-位0为延时值
|
||||||
|
#define mCH341A_CMD_UIO_STM_END 0x20 // UIO接口的命令流:命令包提前结束
|
||||||
|
|
||||||
|
#define MAX_DEVICE_PATH_SIZE 128 // 设备名称的最大字符数
|
||||||
|
#define MAX_DEVICE_ID_SIZE 64 // 设备ID的最大字符数
|
||||||
|
#endif _CH341_DLL_H
|
||||||
|
|
||||||
|
// 驱动接口
|
||||||
|
#define CH347_USB_VENDOR 0
|
||||||
|
#define CH347_USB_HID 2
|
||||||
|
#define CH347_USB_VCP 3
|
||||||
|
|
||||||
|
// CH347_USB_VENDOR支持CH341/CH347T/CH347F/CH339W
|
||||||
|
#define CHIP_TYPE_CH341 0
|
||||||
|
#define CHIP_TYPE_CH347 1
|
||||||
|
#define CHIP_TYPE_CH347F 2
|
||||||
|
#define CHIP_TYPE_CH339W 3
|
||||||
|
#define CHIP_TYPE_CH347T CHIP_TYPE_CH347
|
||||||
|
|
||||||
|
// 芯片功能接口类型
|
||||||
|
#define CH347_FUNC_UART 0
|
||||||
|
#define CH347_FUNC_SPI_IIC 1
|
||||||
|
#define CH347_FUNC_JTAG_IIC 2
|
||||||
|
#define CH347_FUNC_JTAG_IIC_SPI 3 // CH347F同时支持SPI\I2C\JTAG接口
|
||||||
|
|
||||||
|
#define DEFAULT_READ_TIMEOUT 500 // 默认读超时毫秒数
|
||||||
|
#define DEFAULT_WRITE_TIMEOUT 500 // 默认写超时毫秒数
|
||||||
|
|
||||||
|
#define mCH347_PACKET_LENGTH 512 // CH347支持的数据包的长度
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
//SPI控制器配置
|
||||||
|
typedef struct _SPI_CONFIG{
|
||||||
|
UCHAR iMode; // 0-3:SPI Mode0/1/2/3
|
||||||
|
UCHAR iClock; // 0=60MHz, 1=30MHz, 2=15MHz, 3=7.5MHz, 4=3.75MHz, 5=1.875MHz, 6=937.5KHz,7=468.75KHz
|
||||||
|
UCHAR iByteOrder; // 0=低位在前(LSB), 1=高位在前(MSB)
|
||||||
|
USHORT iSpiWriteReadInterval; // SPI接口常规读取写入数据命令,单位为uS
|
||||||
|
UCHAR iSpiOutDefaultData; // SPI读数据时默认输出数据
|
||||||
|
ULONG iChipSelect; // 片选控制, 位7为0则忽略片选控制, 位7为1则参数有效: 位1位0为00/01分别选择CS1/CS2引脚作为低电平有效片选
|
||||||
|
UCHAR CS1Polarity; // 位0:片选CS1极性控制:0:低电平有效;1:高电平有效;
|
||||||
|
UCHAR CS2Polarity; // 位0:片选CS2极性控制:0:低电平有效;1:高电平有效;
|
||||||
|
USHORT iIsAutoDeativeCS; // 操作完成后是否自动撤消片选
|
||||||
|
USHORT iActiveDelay; // 设置片选后执行读写操作的延时时间,单位us
|
||||||
|
ULONG iDelayDeactive; // 撤消片选后执行读写操作的延时时间,单位us
|
||||||
|
}mSpiCfgS,*mPSpiCfgS;
|
||||||
|
|
||||||
|
//设备信息
|
||||||
|
typedef struct _DEV_INFOR{
|
||||||
|
UCHAR iIndex; // 当前打开序号
|
||||||
|
UCHAR DevicePath[MAX_PATH]; // 设备链接名,用于CreateFile
|
||||||
|
UCHAR UsbClass; // 驱动类别 0:CH347_USB_CH341, 2:CH347_USB_HID, 3:CH347_USB_VCP
|
||||||
|
UCHAR FuncType; // 功能类别 0:CH347_FUNC_UART, 1:CH347_FUNC_SPI_I2C, 2:CH347_FUNC_JTAG_I2C, 3:CH347_FUNC_JTAG_IIC_SPI
|
||||||
|
CHAR DeviceID[64]; // USB\VID_xxxx&PID_xxxx
|
||||||
|
UCHAR ChipMode; // 芯片工作模式,0:Mode0(UART0/1); 1:Mode1(Uart1+SPI+I2C); 2:Mode2(HID Uart1+SPI+I2C) 3:Mode3(Uart1+Jtag) 4:CH347F(Uart*2+Jtag/SPI/IIC)
|
||||||
|
HANDLE DevHandle; // 设备句柄
|
||||||
|
USHORT BulkOutEndpMaxSize; // 批量上传端点大小
|
||||||
|
USHORT BulkInEndpMaxSize; // 批量下传端点大小
|
||||||
|
UCHAR UsbSpeedType; // USB速度类型,0:FS,1:HS,2:SS
|
||||||
|
UCHAR CH347IfNum; // USB接口号: CH347T: IF0:UART; IF1:SPI/IIC/JTAG/GPIO
|
||||||
|
// CH347F: IF0:UART0; IF1:UART1; IF 2:SPI/IIC/JTAG/GPIO
|
||||||
|
UCHAR DataUpEndp; // 批量上传端点地址
|
||||||
|
UCHAR DataDnEndp; // 批量下传端点地址
|
||||||
|
CHAR ProductString[64]; // USB产品字符串
|
||||||
|
CHAR ManufacturerString[64]; // USB厂商字符串
|
||||||
|
ULONG WriteTimeout; // USB写超时
|
||||||
|
ULONG ReadTimeout; // USB读超时
|
||||||
|
CHAR FuncDescStr[64]; // 接口功能描述符
|
||||||
|
UCHAR FirewareVer; // 固件版本,十六进制值
|
||||||
|
}mDeviceInforS,*mPDeviceInforS;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
// CH347各模式公用函数,支持CH347所有模式下的打开、关闭、USB读、USB写,包含HID
|
||||||
|
//打开USB设备
|
||||||
|
HANDLE WINAPI CH347OpenDevice(ULONG DevI); // 指定设备序号
|
||||||
|
|
||||||
|
//关闭USB设备
|
||||||
|
BOOL WINAPI CH347CloseDevice(ULONG iIndex); // 指定设备序号
|
||||||
|
|
||||||
|
// 获取设备USB序列号
|
||||||
|
BOOL WINAPI CH347GetSerialNumber(ULONG iIndex, // 指定设备序号
|
||||||
|
PUCHAR iSerialNumberStr); // 指向获取到的设备序列号
|
||||||
|
|
||||||
|
// 获取设备信息
|
||||||
|
BOOL WINAPI CH347GetDeviceInfor(ULONG iIndex, // 指定设备序号
|
||||||
|
mDeviceInforS *DevInformation); // 指向获取到的设备信息
|
||||||
|
|
||||||
|
// 获取CH347芯片类型:0:CHIP_TYPE_CH341;1:CHIP_TYPE_CH347/CHIP_TYPE_CH347T,2:CHIP_TYPE_CH347F;3:CHIP_TYPE_CH339W
|
||||||
|
UCHAR WINAPI CH347GetChipType(ULONG iIndex ); // 指定设备序号
|
||||||
|
|
||||||
|
// 获取驱动版本、库版本、设备版本、芯片类型(CH341(FS)/CH347HS)
|
||||||
|
BOOL WINAPI CH347GetVersion(ULONG iIndex,
|
||||||
|
PUCHAR iDriverVer,
|
||||||
|
PUCHAR iDLLVer,
|
||||||
|
PUCHAR ibcdDevice,
|
||||||
|
PUCHAR iChipType); //CHIP_TYPE_CH341/7
|
||||||
|
|
||||||
|
typedef VOID ( CALLBACK * mPCH347_NOTIFY_ROUTINE ) ( // 设备插拔通知事件回调程序
|
||||||
|
ULONG iEventStatus ); // 设备插拔事件和当前状态(在下行定义): 0=设备拔出事件, 3=设备插入事件
|
||||||
|
|
||||||
|
#define CH347_DEVICE_ARRIVAL 3 // 设备插入事件,已经插入
|
||||||
|
#define CH347_DEVICE_REMOVE_PEND 1 // 设备将要拔出
|
||||||
|
#define CH347_DEVICE_REMOVE 0 // 设备拔出事件,已经拔出
|
||||||
|
|
||||||
|
// 设定设备事件通知程序
|
||||||
|
BOOL WINAPI CH347SetDeviceNotify(ULONG iIndex, // 指定设备序号,0对应第一个设备
|
||||||
|
PCHAR iDeviceID, // 可选参数,指向字符串,指定被监控的设备的ID,字符串以\0终止
|
||||||
|
mPCH347_NOTIFY_ROUTINE iNotifyRoutine ); // 指定设备事件回调程序,为NULL则取消事件通知,否则在检测到事件时调用该程序
|
||||||
|
|
||||||
|
// 读取USB数据块
|
||||||
|
BOOL WINAPI CH347ReadData( ULONG iIndex, // 指定设备序号
|
||||||
|
PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
|
||||||
|
|
||||||
|
// 写取USB数据块
|
||||||
|
BOOL WINAPI CH347WriteData(ULONG iIndex, // 指定设备序号
|
||||||
|
PVOID iBuffer, // 指向一个缓冲区,放置准备写出的数据
|
||||||
|
PULONG ioLength ); // 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
|
||||||
|
|
||||||
|
// 设置USB数据读写的超时
|
||||||
|
BOOL WINAPI CH347SetTimeout(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iWriteTimeout, // 指定USB写出数据块的超时时间,以毫秒mS为单位,0xFFFFFFFF指定不超时(默认值)
|
||||||
|
ULONG iReadTimeout ); // 指定USB读取数据块的超时时间,以毫秒mS为单位,0xFFFFFFFF指定不超时(默认值)
|
||||||
|
|
||||||
|
/***************SPI********************/
|
||||||
|
// SPI控制器初始化
|
||||||
|
BOOL WINAPI CH347SPI_Init(ULONG iIndex, // 指定设备序号
|
||||||
|
mSpiCfgS *SpiCfg); // 指向SPI配置结构体
|
||||||
|
|
||||||
|
// 设置SPI时钟频率,调用该接口后需重新调用CH347SPI_Init进行初始化
|
||||||
|
BOOL WINAPI CH347SPI_SetFrequency(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iSpiSpeedHz);// 设置SPI时钟,单位为HZ
|
||||||
|
|
||||||
|
// 设置SPI数据位数
|
||||||
|
BOOL WINAPI CH347SPI_SetDataBits(ULONG iIndex, // 指定设备序号
|
||||||
|
UCHAR iDataBits); // 0=8bit,1=16bit
|
||||||
|
|
||||||
|
// 获取SPI控制器配置信息
|
||||||
|
BOOL WINAPI CH347SPI_GetCfg(ULONG iIndex,mSpiCfgS *SpiCfg);
|
||||||
|
|
||||||
|
// 设置片选状态,使用前需先调用CH347SPI_Init对CS进行设置
|
||||||
|
BOOL WINAPI CH347SPI_ChangeCS(ULONG iIndex, // 指定设备序号
|
||||||
|
UCHAR iStatus); // 0=撤消片选,1=设置片选
|
||||||
|
|
||||||
|
// 设置SPI片选
|
||||||
|
BOOL WINAPI CH347SPI_SetChipSelect(ULONG iIndex, // 指定设备序号
|
||||||
|
USHORT iEnableSelect, // 低八位为CS1,高八位为CS2; 字节值为1=设置CS,为0=忽略此CS设置
|
||||||
|
USHORT iChipSelect, // 低八位为CS1,高八位为CS2;片选输出,0=撤消片选,1=设置片选
|
||||||
|
ULONG iIsAutoDeativeCS, // 低16位为CS1,高16位为CS2;操作完成后是否自动撤消片选
|
||||||
|
ULONG iActiveDelay, // 低16位为CS1,高16位为CS2;设置片选后执行读写操作的延时时间,单位us
|
||||||
|
ULONG iDelayDeactive); // 低16位为CS1,高16位为CS2;撤消片选后执行读写操作的延时时间,单位us
|
||||||
|
|
||||||
|
// SPI4写数据
|
||||||
|
BOOL WINAPI CH347SPI_Write(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iChipSelect, // 片选控制, 位7为0则忽略片选控制, 位7为1进行片选操作
|
||||||
|
ULONG iLength, // 准备传输的数据字节数
|
||||||
|
ULONG iWriteStep, // 准备读取的单个块的长度
|
||||||
|
PVOID ioBuffer); // 指向一个缓冲区,放置准备从MOSI写出的数据
|
||||||
|
|
||||||
|
// SPI4读数据.无需先写数据,效率较CH347SPI_WriteRead高很多
|
||||||
|
BOOL WINAPI CH347SPI_Read(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iChipSelect, // 片选控制, 位7为0则忽略片选控制, 位7为1进行片选操作
|
||||||
|
ULONG oLength, // 准备发出的字节数
|
||||||
|
PULONG iLength, // 准备读入的数据字节数
|
||||||
|
PVOID ioBuffer); // 指向一个缓冲区,放置准备从DOUT写出的数据,返回后是从DIN读入的数据
|
||||||
|
|
||||||
|
// 处理SPI数据流,4线接口
|
||||||
|
BOOL WINAPI CH347SPI_WriteRead(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iChipSelect, // 片选控制, 位7为0则忽略片选控制, 位7为1则操作片选
|
||||||
|
ULONG iLength, // 准备传输的数据字节数
|
||||||
|
PVOID ioBuffer ); // 指向一个缓冲区,放置准备从DOUT写出的数据,返回后是从DIN读入的数据
|
||||||
|
|
||||||
|
// 处理SPI数据流,4线接口
|
||||||
|
BOOL WINAPI CH347StreamSPI4(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iChipSelect, // 片选控制, 位7为0则忽略片选控制, 位7为1则参数有效
|
||||||
|
ULONG iLength, // 准备传输的数据字节数
|
||||||
|
PVOID ioBuffer ); // 指向一个缓冲区,放置准备从DOUT写出的数据,返回后是从DIN读入的数据
|
||||||
|
|
||||||
|
/***************JTAG********************/
|
||||||
|
// JTAG接口初始化,设置JTAG通信速度
|
||||||
|
BOOL WINAPI CH347Jtag_INIT(ULONG iIndex, // 指定设备序号
|
||||||
|
UCHAR iClockRate); // 通信速度;0=468.75KHz,1=937.5KHz,2=1.875MHz,3=3.75MHz,4=7.5MHz,5=15MHz,6=30MHz,7=60MHz
|
||||||
|
|
||||||
|
// 获取Jtag速度设置
|
||||||
|
BOOL WINAPI CH347Jtag_GetCfg(ULONG iIndex, // 指定设备序号
|
||||||
|
UCHAR *ClockRate); // 通信速度;有效值为0-7,值越大通信速度越快
|
||||||
|
|
||||||
|
|
||||||
|
// 改变TMS的值来进行状态切换
|
||||||
|
BOOL WINAPI CH347Jtag_TmsChange(ULONG iIndex, // 设备序号
|
||||||
|
PUCHAR tmsValue, // 进行切换的TMS位值,以字节为单位
|
||||||
|
ULONG Step, // tmsValue内存储的TMS有效位数
|
||||||
|
ULONG Skip); // 有效起始位
|
||||||
|
|
||||||
|
// 在Shift-DR/IR状态进行读写,执行完切至Exit DR/IR
|
||||||
|
// 状态机:Shift-DR/IR.RW.->Exit DR/IR
|
||||||
|
BOOL WINAPI CH347Jtag_IoScan(ULONG iIndex,
|
||||||
|
PUCHAR DataBits, //需要进行传输的数据位
|
||||||
|
ULONG DataBitsNb, //需要传输数据的位数
|
||||||
|
BOOL IsRead); //是否需要读取数据
|
||||||
|
|
||||||
|
// 切至Shift-DR/IR状态进行读写,执行完成后,如是最后一包,则切换状态至Exit DR/IR;如果不是,则停在Shift-DR/IR状态
|
||||||
|
// 状态机:Shift-DR/IR.RW..->[Exit DR/IR]
|
||||||
|
BOOL WINAPI CH347Jtag_IoScanT(ULONG iIndex, // 指定设备序号
|
||||||
|
PUCHAR DataBits, // 需要进行传输的数据位
|
||||||
|
ULONG DataBitsNb, // 需要传输数据的位数
|
||||||
|
BOOL IsRead, // 是否需要读取数据
|
||||||
|
BOOL IsLastPkt); // 是否为最后一包
|
||||||
|
|
||||||
|
// JTAG复位Tap状态函数.连续六个以上TCK且TMS为高将可将状态机置为Test-Logic Reset状态
|
||||||
|
ULONG WINAPI CH347Jtag_Reset(ULONG iIndex); // 指定设备序号
|
||||||
|
|
||||||
|
// 操作TRST完成硬件复位
|
||||||
|
BOOL WINAPI CH347Jtag_ResetTrst(ULONG iIndex, // 指定设备序号
|
||||||
|
BOOL iLevel); // 0=设置为低,1=设置为高
|
||||||
|
|
||||||
|
// 位带方式JTAG IR/DR数据读写.适用于少量数据的读写。如指令操作、状态机切换等控制类传输。如批量数据传输,建议使用CH347Jtag_WriteRead_Fast
|
||||||
|
// 命令包以4096字节为单位批量读写
|
||||||
|
// 状态机:Run-Test->Shift-IR/DR..->Exit IR/DR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_WriteRead(ULONG iIndex, // 指定设备序号
|
||||||
|
BOOL IsDR, // =TRUE: DR数据读写,=FALSE:IR数据读写
|
||||||
|
ULONG iWriteBitLength, // 写长度,准备写出的长度
|
||||||
|
PVOID iWriteBitBuffer, // 指向一个缓冲区,放置准备写出的数据
|
||||||
|
PULONG oReadBitLength, // 指向长度单元,返回后为实际读取的长度
|
||||||
|
PVOID oReadBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
|
||||||
|
// JTAG IR/DR数据批量读写,用于多字节连续读写。如JTAG固件下载操作。因硬件有4K缓冲区,如先写后读,长度不超过4096字节。缓冲区大小可自行调整
|
||||||
|
// 状态机:Run-Test->Shift-IR/DR..->Exit IR/DR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_WriteRead_Fast(ULONG iIndex, // 指定设备序号
|
||||||
|
BOOL IsDR, // =TRUE: DR数据读写,=FALSE:IR数据读写
|
||||||
|
ULONG iWriteBitLength, // 写长度,准备写出的长度
|
||||||
|
PVOID iWriteBitBuffer, // 指向一个缓冲区,放置准备写出的数据
|
||||||
|
PULONG oReadBitLength, // 指向长度单元,返回后为实际读取的长度
|
||||||
|
PVOID oReadBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
|
||||||
|
// 位带方式JTAG IR/DR数据读写.适用于少量数据的读写。如指令操作、状态机切换等控制类传输。如批量数据传输,建议使用CH347Jtag_WriteRead_Fast
|
||||||
|
// 命令包以4096字节为单位批量读写
|
||||||
|
// 状态机:Run-Test-> Shift-IR/DR..->Exit IR/DR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_WriteReadEx(ULONG iIndex, // 指定设备序号
|
||||||
|
BOOL IsInDrOrIr, // =TRUE: 在SHIFT-DR/IR状态进行数据交互 ==FALSE: Run-Test->Shift-IR/DR.进行数据交互.->Exit IR/DR -> Run-Test
|
||||||
|
BOOL IsDR, // =TRUE: DR数据读写,=FALSE:IR数据读写
|
||||||
|
ULONG iWriteBitLength, // 写长度,准备写出的长度
|
||||||
|
PVOID iWriteBitBuffer, // 指向一个缓冲区,放置准备写出的数据
|
||||||
|
PULONG oReadBitLength, // 指向长度单元,返回后为实际读取的长度
|
||||||
|
PVOID oReadBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
|
||||||
|
// JTAG IR/DR数据批量读写,用于多字节连续读写。如JTAG固件下载操作。因硬件有4K缓冲区,如先写后读,长度不超过4096字节。缓冲区大小可自行调整
|
||||||
|
// 状态机:Run-Test->Shift-IR/DR..->Exit IR/DR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_WriteRead_FastEx(ULONG iIndex, // 指定设备序号
|
||||||
|
BOOL IsInDrOrIr, // =TRUE: 在SHIFT-DR/IR状态进行数据交互 ==FALSE: Run-Test->Shift-IR/DR.进行数据交互.->Exit IR/DR -> Run-Test
|
||||||
|
BOOL IsDR, // =TRUE: DR数据读写,=FALSE:IR数据读写
|
||||||
|
ULONG iWriteBitLength, // 写长度,准备写出的长度
|
||||||
|
PVOID iWriteBitBuffer, // 指向一个缓冲区,放置准备写出的数据
|
||||||
|
PULONG oReadBitLength, // 指向长度单元,返回后为实际读取的长度
|
||||||
|
PVOID oReadBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
|
||||||
|
// 单步切换JTAG状态机,需按照顺序执行
|
||||||
|
BOOL WINAPI CH347Jtag_SwitchTapState(UCHAR TapState); // 指定切换到的状态
|
||||||
|
// 0:Test-Logic Reset,1:Run-Test/Idle,2:Run-Test/Idle -> Shift-DR,3:Shift-DR -> Run-Test/Idle
|
||||||
|
// 4:Run-Test/Idle -> Shift-IR, 5:Shift-IR -> Run-Test/Idle, 6:Exit1-DR/IR -> Update-DR/IR -> Run-Test/Idle
|
||||||
|
|
||||||
|
// 单步切换JTAG状态机,可指定操作设备iIndex
|
||||||
|
BOOL WINAPI CH347Jtag_SwitchTapStateEx(ULONG iIndex, // 指定设备序号
|
||||||
|
UCHAR TapState); // 指定切换到的状态
|
||||||
|
|
||||||
|
// JTAG DR写,以字节为单位,用于多字节连续读写。如JTAG固件下载操作。
|
||||||
|
// 状态机:Run-Test->Shift-DR..->Exit DR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_ByteWriteDR(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iWriteLength, // 写长度,准备写出的字节长度
|
||||||
|
PVOID iWriteBuffer); // 指向一个缓冲区,放置准备写出的数据
|
||||||
|
|
||||||
|
// JTAG DR读,以字节为单位,多字节连续读。
|
||||||
|
// 状态机:Run-Test->Shift-DR..->Exit DR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_ByteReadDR(ULONG iIndex, // 指定设备序号
|
||||||
|
PULONG oReadLength, // 指向长度单元,返回后为实际读取的字节长度
|
||||||
|
PVOID oReadBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
|
||||||
|
// JTAG IR写,以字节为单位,多字节连续写。
|
||||||
|
// 状态机:Run-Test->Shift-IR..->Exit IR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_ByteWriteIR(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iWriteLength, // 写长度,准备写出的字节长度
|
||||||
|
PVOID iWriteBuffer); // 指向一个缓冲区,放置准备写出的数据
|
||||||
|
|
||||||
|
// JTAG IR读,以字节为单位,多字节连续读写。
|
||||||
|
// 状态机:Run-Test->Shift-IR..->Exit IR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_ByteReadIR(ULONG iIndex, // 指定设备序号
|
||||||
|
PULONG oReadLength, // 指向长度单元,返回后为实际读取的字节长度
|
||||||
|
PVOID oReadBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
|
||||||
|
// 位带方式JTAG DR数据写.适用于少量数据的读写。如指令操作、状态机切换等控制类传输。如批量数据传输,建议使用USB20Jtag_ByeWriteDR
|
||||||
|
// 状态机:Run-Test->Shift-DR..->Exit DR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_BitWriteDR(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iWriteBitLength, // 指向长度单元,返回后为实际读取的字节长度
|
||||||
|
PVOID iWriteBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
|
||||||
|
// 位带方式JTAG IR数据写.适用于少量数据的读写。如指令操作、状态机切换等控制类传输。如批量数据传输,建议使用USB20Jtag_ByteWriteIR
|
||||||
|
// 状态机:Run-Test->Shift-IR..->Exit IR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_BitWriteIR(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iWriteBitLength, // 指向长度单元,返回后为实际读取的字节长度
|
||||||
|
PVOID iWriteBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
|
||||||
|
// 位带方式JTAG IR数据读.适用于少量数据的读写。如指令操作、状态机切换等。如批量数据传输,建议使用USB20Jtag_ByteReadIR
|
||||||
|
// 状态机:Run-Test->Shift-IR..->Exit IR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_BitReadIR(ULONG iIndex, // 指定设备序号
|
||||||
|
PULONG oReadBitLength, // 指向长度单元,返回后为实际读取的字节长度
|
||||||
|
PVOID oReadBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
|
||||||
|
// 位带方式JTAG DR数据读.适用于少量数据的读写。如批量和高速数据传输,建议使用USB20Jtag_ByteReadDR
|
||||||
|
// 状态机:Run-Test->Shift-DR..->Exit DR -> Run-Test
|
||||||
|
BOOL WINAPI CH347Jtag_BitReadDR(ULONG iIndex, // 指定设备序号
|
||||||
|
PULONG oReadBitLength, // 指向长度单元,返回后为实际读取的字节长度
|
||||||
|
PVOID oReadBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
|
||||||
|
/***************GPIO********************/
|
||||||
|
// 获取CH347的GPIO方向和引脚电平值
|
||||||
|
BOOL WINAPI CH347GPIO_Get(ULONG iIndex, // 指定设备序号
|
||||||
|
UCHAR *iDir, // 引脚方向:GPIO0-7对应位0-7, 0=输入;1=输出
|
||||||
|
UCHAR *iData); // GPIO0电平:GPIO0-7对应位0-7,0=低电平;1=高电平)
|
||||||
|
|
||||||
|
// 设置CH347的GPIO方向和引脚电平值
|
||||||
|
BOOL WINAPI CH347GPIO_Set(ULONG iIndex, // 指定设备序号
|
||||||
|
UCHAR iEnable, // 数据有效标志:对应位0-7,对应GPIO0-7.
|
||||||
|
UCHAR iSetDirOut, // 设置I/O方向,某位清0则对应引脚为输入,某位置1则对应引脚为输出.GPIO0-7对应位0-7.
|
||||||
|
UCHAR iSetDataOut); // 输出数据,如果I/O方向为输出,那么某位清0时对应引脚输出低电平,某位置1时对应引脚输出高电平
|
||||||
|
|
||||||
|
|
||||||
|
typedef VOID ( CALLBACK * mPCH347_INT_ROUTINE ) ( // 中断服务程序
|
||||||
|
PUCHAR iStatus ); // 中断状态数据,参考下面的位说明
|
||||||
|
// 8个字节GPIO0-7引脚状态.每字节位定义如下:
|
||||||
|
// 位7:当前的GPIO0方向,0:输入;1:输出;
|
||||||
|
// 位6:当前的GPIO0电平,0:低电平;1:高电平;
|
||||||
|
// 位5:当前的GPIO0是否设置为中断,0:查询模式;1:中断模式;
|
||||||
|
// 位4-3:设置GPIO0的中断模式,00:下降沿触发;01:上升沿触发;10:双边沿触发;11: 保留;
|
||||||
|
// 位2-0:保留;
|
||||||
|
|
||||||
|
// 设定GPIO中断服务程序
|
||||||
|
BOOL WINAPI CH347SetIntRoutine(ULONG iIndex, // 指定设备序号
|
||||||
|
UCHAR Int0PinN, // 中断0 GPIO引脚号,大于7:不启用此中断源; 为0-7对应gpio0-7
|
||||||
|
UCHAR Int0TripMode, // 中断0类型: 00:下降沿触发; 01:上升沿触发; 02:双边沿触发; 03:保留;
|
||||||
|
UCHAR Int1PinN, // 中断1 GPIO引脚号,大于7则不启用此中断源,为0-7对应gpio0-7
|
||||||
|
UCHAR Int1TripMode, // 中断1类型: 00:下降沿触发; 01:上升沿触发; 02:双边沿触发; 03:保留;
|
||||||
|
mPCH347_INT_ROUTINE iIntRoutine );// 指定中断服务程序,为NULL则取消中断服务,否则在中断时调用该程序
|
||||||
|
|
||||||
|
// 读取中断数据
|
||||||
|
BOOL WINAPI CH347ReadInter(ULONG iIndex, // 指定设备序号
|
||||||
|
PUCHAR iStatus ); // 指向8字节单元,分别为GPIO0-7引脚状态,每个字节位说明参考中断服务程序iStatus位说明
|
||||||
|
|
||||||
|
// 放弃中断数据读操作
|
||||||
|
BOOL WINAPI CH347AbortInter(ULONG iIndex ); // 指定设备序号
|
||||||
|
|
||||||
|
// 进入IAP固件升级模式
|
||||||
|
BOOL WINAPI CH347StartIapFwUpate(ULONG iIndex,
|
||||||
|
ULONG FwSize); // 固件长度
|
||||||
|
|
||||||
|
/**************HID/VCP串口**********************/
|
||||||
|
// 打开串口
|
||||||
|
HANDLE WINAPI CH347Uart_Open(ULONG iIndex); // 指定设备序号
|
||||||
|
|
||||||
|
// 关闭串口
|
||||||
|
BOOL WINAPI CH347Uart_Close(ULONG iIndex); // 指定设备序号
|
||||||
|
|
||||||
|
BOOL WINAPI CH347Uart_SetDeviceNotify( // 设定设备事件通知程序
|
||||||
|
ULONG iIndex, // 指定设备序号,0对应第一个设备
|
||||||
|
PCHAR iDeviceID, // 可选参数,指向字符串,指定被监控的设备的ID,字符串以\0终止
|
||||||
|
mPCH347_NOTIFY_ROUTINE iNotifyRoutine ); // 指定设备事件回调程序,为NULL则取消事件通知,否则在检测到事件时调用该程序
|
||||||
|
|
||||||
|
// 获取UART硬件配置
|
||||||
|
BOOL WINAPI CH347Uart_GetCfg(ULONG iIndex, // 指定设备序号
|
||||||
|
PULONG BaudRate, // 波特率
|
||||||
|
PUCHAR ByteSize, // 数据位数(5,6,7,8,16)
|
||||||
|
PUCHAR Parity, // 校验位(0:None; 1:Odd; 2:Even; 3:Mark; 4:Space)
|
||||||
|
PUCHAR StopBits, // 停止位数(0:1停止位; 1:1.5停止位; 2:2停止位);
|
||||||
|
PUCHAR ByteTimeout); // 字节超时
|
||||||
|
|
||||||
|
// 设置UART配置
|
||||||
|
BOOL WINAPI CH347Uart_Init(ULONG iIndex, // 指定设备序号
|
||||||
|
DWORD BaudRate, // 波特率
|
||||||
|
UCHAR ByteSize, // 数据位数(5,6,7,8,16)
|
||||||
|
UCHAR Parity, // 校验位(0:None; 1:Odd; 2:Even; 3:Mark; 4:Space)
|
||||||
|
UCHAR StopBits, // 停止位数(0:1停止位; 1:1.5停止位; 2:2停止位);
|
||||||
|
UCHAR ByteTimeout);// 字节超时时间,单位100uS
|
||||||
|
|
||||||
|
// 设置USB数据读写的超时
|
||||||
|
BOOL WINAPI CH347Uart_SetTimeout(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iWriteTimeout, // 指定USB写出数据块的超时时间,以毫秒mS为单位,0xFFFFFFFF指定不超时(默认值)
|
||||||
|
ULONG iReadTimeout ); // 指定USB读取数据块的超时时间,以毫秒mS为单位,0xFFFFFFFF指定不超时(默认值)
|
||||||
|
|
||||||
|
// 串口读
|
||||||
|
BOOL WINAPI CH347Uart_Read(ULONG iIndex, // 指定设备序号
|
||||||
|
PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存读取的数据
|
||||||
|
PULONG ioLength );// 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
|
||||||
|
// 串口写
|
||||||
|
BOOL WINAPI CH347Uart_Write(ULONG iIndex, // 指定设备序号
|
||||||
|
PVOID iBuffer, // 指向一个缓冲区,放置准备写出的数据
|
||||||
|
PULONG ioLength );// 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
|
||||||
|
|
||||||
|
// 查询读缓冲区有多少字节未取(适用于HID模式串口)
|
||||||
|
BOOL WINAPI CH347Uart_QueryBufUpload(ULONG iIndex, // 指定设备序号
|
||||||
|
LONGLONG *RemainBytes); // 读缓冲区未取字节数
|
||||||
|
|
||||||
|
// 获取设备信息
|
||||||
|
BOOL WINAPI CH347Uart_GetDeviceInfor(ULONG iIndex,mDeviceInforS *DevInformation);
|
||||||
|
|
||||||
|
/********I2C***********/
|
||||||
|
// I2C设置
|
||||||
|
BOOL WINAPI CH347I2C_Set(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iMode ); // 指定模式,见下行
|
||||||
|
// 位0-位2: I2C接口速度/SCL频率, 000=低速/20KHz,001=标准/100KHz(默认值),010=快速/400KHz,011=高速/750KHz,100=低速/50KHz,101=标准/200KHz,110=快速/1MHz
|
||||||
|
// 其它保留,必须为0
|
||||||
|
|
||||||
|
// 设置I2C时钟延展功能
|
||||||
|
BOOL WINAPI CH347I2C_SetStretch(ULONG iIndex, // 指定设备序号
|
||||||
|
BOOL iEnable); // 0=关闭时钟延展功能(默认关闭);1=开启时钟延展功能
|
||||||
|
|
||||||
|
// 设置硬件异步延时,调用后很快返回,而在下一个流操作之前延时指定毫秒数
|
||||||
|
BOOL WINAPI CH347I2C_SetDelaymS(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iDelay ) ; // 指定延时的毫秒数
|
||||||
|
|
||||||
|
// 设置I2C引脚驱动模式
|
||||||
|
BOOL WINAPI CH347I2C_SetDriverMode(ULONG iIndex, // 指定设备序号
|
||||||
|
UCHAR iMode); // 0=开漏模式;1=推挽模式
|
||||||
|
|
||||||
|
// 处理I2C数据流,2线接口,时钟线为SCL引脚,数据线为SDA引脚
|
||||||
|
BOOL WINAPI CH347StreamI2C( ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iWriteLength, // 准备写出的数据字节数
|
||||||
|
PVOID iWriteBuffer, // 指向一个缓冲区,放置准备写出的数据,首字节通常是I2C设备地址及读写方向位
|
||||||
|
ULONG iReadLength, // 准备读取的数据字节数
|
||||||
|
PVOID oReadBuffer ); // 指向一个缓冲区,返回后是读入的数据
|
||||||
|
|
||||||
|
// 处理I2C数据流,2线接口,时钟线为SCL引脚,数据线为SDA引脚
|
||||||
|
BOOL WINAPI CH347StreamI2C_RetACK( // 处理I2C数据流,2线接口,时钟线为SCL引脚,数据线为SDA引脚(准双向I/O),速度约56K字节,并返回主机端获取到的ACK数量
|
||||||
|
ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iWriteLength, // 准备写出的数据字节数
|
||||||
|
PVOID iWriteBuffer, // 指向一个缓冲区,放置准备写出的数据,首字节通常是I2C设备地址及读写方向位
|
||||||
|
ULONG iReadLength, // 准备读取的数据字节数
|
||||||
|
PVOID oReadBuffer, // 指向一个缓冲区,返回后是读入的数据
|
||||||
|
PULONG rAckCount); // 指向读写返回的ACK值
|
||||||
|
|
||||||
|
#ifndef _CH341_DLL_H
|
||||||
|
typedef enum _EEPROM_TYPE {// EEPROM型号
|
||||||
|
ID_24C01,
|
||||||
|
ID_24C02,
|
||||||
|
ID_24C04,
|
||||||
|
ID_24C08,
|
||||||
|
ID_24C16,
|
||||||
|
ID_24C32,
|
||||||
|
ID_24C64,
|
||||||
|
ID_24C128,
|
||||||
|
ID_24C256,
|
||||||
|
ID_24C512,
|
||||||
|
ID_24C1024,
|
||||||
|
ID_24C2048,
|
||||||
|
ID_24C4096
|
||||||
|
} EEPROM_TYPE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 从EEPROM中读取数据块
|
||||||
|
BOOL WINAPI CH347ReadEEPROM(ULONG iIndex, // 指定设备序号
|
||||||
|
EEPROM_TYPE iEepromID, // 指定EEPROM型号
|
||||||
|
ULONG iAddr, // 指定数据单元的地址
|
||||||
|
ULONG iLength, // 准备读取的数据字节数
|
||||||
|
PUCHAR oBuffer ); // 指向一个缓冲区,返回后是读入的数据
|
||||||
|
// 向EEPROM中写入数据块
|
||||||
|
BOOL WINAPI CH347WriteEEPROM(ULONG iIndex, // 指定设备序号
|
||||||
|
EEPROM_TYPE iEepromID, // 指定EEPROM型号
|
||||||
|
ULONG iAddr, // 指定数据单元的地址
|
||||||
|
ULONG iLength, // 准备写出的数据字节数
|
||||||
|
PUCHAR iBuffer ); // 指向一个缓冲区,放置准备写出的数据
|
||||||
|
|
||||||
|
//设置第8位时钟低周期延时时间,仅适用于CH347T
|
||||||
|
BOOL WINAPI CH347I2C_SetAckClk_DelayuS(ULONG iIndex, // 指定设备序号
|
||||||
|
ULONG iDelay); // 指定延时的微秒数
|
||||||
|
|
||||||
|
// 该函数用于查询指定索引的CH339W芯片当前各个接口功能的启用状态。
|
||||||
|
// 返回值位定义:
|
||||||
|
// 位7 (0x80): USB转JTAG使能状态(1=使能,0=禁用)
|
||||||
|
// 位6 (0x40): USB转SPI使能状态(1=使能,0=禁用)
|
||||||
|
// 位5 (0x20): USB转UART使能(不带流控)(1=使能,0=禁用)
|
||||||
|
// 位4 (0x10): USB转UART流控使能(1=使能,0=禁用)
|
||||||
|
// 位3 (0x08): USB转I2C使能状态(1=使能,0=禁用)
|
||||||
|
// 位2-位0: 保留位
|
||||||
|
UCHAR WINAPI CH339GetChipFuncState( ULONG iIndex ); // 指定设备序号
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _CH347_DLL_H
|
||||||
BIN
libs/CH347DLLA64.LIB
Executable file
BIN
libs/CH347DLLA64.LIB
Executable file
Binary file not shown.
BIN
libs/CH347Handler.dll
Executable file
BIN
libs/CH347Handler.dll
Executable file
Binary file not shown.
BIN
libs/CH347Handler.lib
Executable file
BIN
libs/CH347Handler.lib
Executable file
Binary file not shown.
37
libs/Common.h
Executable file
37
libs/Common.h
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <minwindef.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct DevSimple {
|
||||||
|
unsigned char iIndex;
|
||||||
|
unsigned char DevicePath[MAX_PATH];
|
||||||
|
char DeviceID[64];
|
||||||
|
unsigned char CH347IfNum;
|
||||||
|
char ProductString[64];
|
||||||
|
char ManufacturerString[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SetCommandArg {
|
||||||
|
enum Command {
|
||||||
|
SP_CMD_NA = 0, // 无效命令
|
||||||
|
SP_CMD_ZERO = 1, // 参数归零
|
||||||
|
SP_CMD_SAME_VALUE = 2, // 同值配置
|
||||||
|
SP_CMD_DIF_VALUE = 3 // 异值配置
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Group {
|
||||||
|
ALL = 0xAA, // 整体归零
|
||||||
|
AB = 0x00, // A/B组归零
|
||||||
|
OPA = 0x01, // OPA组归零
|
||||||
|
DAC = 0x02 // DAC组归零
|
||||||
|
};
|
||||||
|
|
||||||
|
Command cmd_; // cmd 控制命令
|
||||||
|
Group group_; // group 分组
|
||||||
|
int childGroup_; // groupDet 子分组 group为0时,0/1代表对A/B操作;group为2时,代表操作编号为0~20的DAC
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SetVotegeArg {
|
||||||
|
std::vector<uint16_t> votes_; // 同值设定只需要一个元素,异值设定需要256个元素
|
||||||
|
};
|
||||||
46
libs/SpiApi.h
Executable file
46
libs/SpiApi.h
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
#ifdef SPI_API_LIB
|
||||||
|
#define SPI_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define SPI_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class SpiHandler;
|
||||||
|
|
||||||
|
class SPI_API SpiApi {
|
||||||
|
public:
|
||||||
|
SpiApi();
|
||||||
|
~SpiApi();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @breaf 初始化所有CH347并返回列表
|
||||||
|
*
|
||||||
|
* @return 已知的CH347设备列表
|
||||||
|
*/
|
||||||
|
std::vector<DevSimple> initUsbDevice();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @breaf 向设备下发参数
|
||||||
|
*
|
||||||
|
* @param devs 指定接收参数的设备
|
||||||
|
* @param cmdarg 控制字参数,具体定义见Common.h
|
||||||
|
* @param varg 电压参数,具体定义见Common.h
|
||||||
|
*
|
||||||
|
* @return 成功返回true
|
||||||
|
*/
|
||||||
|
bool applyArg(DevSimple devs, SetCommandArg cmdarg, SetVotegeArg varg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @breaf 设为true可以在exe的工作目录的debug.log中输出打包后要下发的十六进制参数
|
||||||
|
*/
|
||||||
|
void debug(bool on = true);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<SpiHandler> sh_;
|
||||||
|
std::string lastError_;
|
||||||
|
};
|
||||||
11
main.cpp
Executable file
11
main.cpp
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
MainWindow w;
|
||||||
|
w.show();
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
422
mainwindow.cpp
Executable file
422
mainwindow.cpp
Executable file
@ -0,0 +1,422 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
#include <QDebug.h>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <drivers/log/logHandler.h>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1600
|
||||||
|
#pragma execution_character_set("utf-8")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MainWindow::mw_tableInit(void)
|
||||||
|
{
|
||||||
|
// 初始化组和子组的下拉框
|
||||||
|
this->ui->comboBox_icdSubGroup->addItems(this->m_APP_Icd->comboBox_subGroupInfo.value(this->ui->comboBox_icdGroup->currentIndex()));
|
||||||
|
// 填充数据
|
||||||
|
for (int row = 0; row < 16; ++row) {
|
||||||
|
for (int col = 0; col < 16; ++col) {
|
||||||
|
// int index = row * 16 + col; // 计算一维数组索引
|
||||||
|
QTableWidgetItem *item = new QTableWidgetItem(QString::number(this->m_APP_Icd->DAC256_10bit_data[row][col]));
|
||||||
|
this->ui->tableWidget_volInput->setItem(row, col, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 在窗口构造函数中连接信号:当输入数据发生变化时,自动链接
|
||||||
|
connect(this->ui->tableWidget_volInput, &QTableWidget::cellChanged, this, &MainWindow::mw_onCellChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表格中的数据有变化时,触发该函数
|
||||||
|
void MainWindow::mw_onCellChanged(int row, int column) {
|
||||||
|
uint8_t i = 0;
|
||||||
|
uint8_t j = 0;
|
||||||
|
|
||||||
|
QTableWidgetItem *item = this->ui->tableWidget_volInput->item(row, column);
|
||||||
|
if (item) {
|
||||||
|
bool ok;
|
||||||
|
// 转换数据
|
||||||
|
int newValue = item->text().toInt(&ok);
|
||||||
|
if(!ok || (newValue > 1023)){
|
||||||
|
/* 错误输入,设置为原来的值 */
|
||||||
|
// 设置为原来的值
|
||||||
|
QTableWidgetItem *item = new QTableWidgetItem(QString::number(this->m_APP_Icd->DAC256_10bit_data[row][column]));
|
||||||
|
this->ui->tableWidget_volInput->setItem(row, column, item);
|
||||||
|
// 提示警告
|
||||||
|
QMessageBox::question(this,"ERROR","plase input 0-1023 digit!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << "Cell at (" << row << "," << column << ") changed to:" << newValue;
|
||||||
|
// 设置DAC256 10bit数组的值
|
||||||
|
if(!this->m_APP_Icd->ICD_setDAC256Data10bit(row, column, newValue)){
|
||||||
|
qDebug() << "set newvalue:" << newValue << "failed!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* 如果是同值配置,则让页面和DAC256Data10bit数组的值赋值为同一个值*/
|
||||||
|
if(this->ui->comboBox_icdCmd->currentIndex() == 1){
|
||||||
|
for(i = 0; i < 16; i++){
|
||||||
|
for(j = 0; j < 16; j++){
|
||||||
|
// 防止多次进入该程序
|
||||||
|
if(this->ui->tableWidget_volInput->item(i, j)->text().toInt() != newValue){
|
||||||
|
// 表格中显示输入的值
|
||||||
|
this->ui->tableWidget_volInput->item(i, j)->setText(QString::number(newValue));
|
||||||
|
// 设置DAC256_10bit_data数组中的值为输入的值
|
||||||
|
this->m_APP_Icd->ICD_setDAC256Data10bit(i, j, newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::mw_showVersionInfo() {
|
||||||
|
QMessageBox::information(
|
||||||
|
this,
|
||||||
|
tr("版本信息"),
|
||||||
|
tr("上位机版本:%1\n").arg(VERSION) +
|
||||||
|
tr("修改时间:%1\n").arg(MOD_TIME) +
|
||||||
|
tr("ICD协议版本:%1\n").arg(ICD_VERSION)+
|
||||||
|
tr("作者:罗林赖生\n")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::mw_showUserManual() {
|
||||||
|
QMessageBox::information(
|
||||||
|
this,
|
||||||
|
tr("使用说明"),
|
||||||
|
tr("1. 打开设备:点击刷新设备列表,搜索串口/SPI设备,选择设备后,点击打开设备\n") +
|
||||||
|
tr("2. 配置通信:配置串口/SPI通信协议相关的参数,点击初始化SPI/串口参数配置\n") +
|
||||||
|
tr("3. 寄存器配置和电压配置(以下操作并非都需操作,视情况配置):\n") +
|
||||||
|
tr("3.1 寄存器配置:\n") +
|
||||||
|
tr("在寄存器配置以及回读区配置相关的属性后,点击寄存器配置按钮进行配置,如需查看是否配置成功,配置完后等待一秒,点击寄存器回读按钮,寄存器值将显示至文本框\n") +
|
||||||
|
tr("3.2 电压配置:\n") +
|
||||||
|
tr("3.2.1 命令选择:选择需要配置的方式 \n") +
|
||||||
|
tr("3.2.2 分组和子分组选择:选择需要配置的分组和子分组,注:当命令选择异值配置时,分组只能选择单个DAC! \n") +
|
||||||
|
tr("3.2.3 输入电压:在16X16的表格内输入所需要配置的电压对应的数字量,范围为0-1023,通道数按照从左到右,从上到下依次排布,注:当命令选择同值配置时,只需输入一个电压值,按回车后自动填充所有的数据 \n")+
|
||||||
|
tr("3.2.4 设置电压:点击发送电压命令按钮,将把电压相关数据发送至下位机,此时日志输出窗口将输出相关日志信息 \n")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 菜单栏初始化
|
||||||
|
void MainWindow::mw_menuBarInit(void) {
|
||||||
|
|
||||||
|
// 获取主窗口的菜单栏
|
||||||
|
QMenuBar *menuBar = this->menuBar();
|
||||||
|
|
||||||
|
// 1. 添加"主菜单"菜单
|
||||||
|
QMenu *mainMenu = menuBar->addMenu(tr("菜单(&M)")); // &H 表示快捷键 Alt+H
|
||||||
|
|
||||||
|
// 2. 添加"帮助"菜单(包含"版本信息"和"使用说明")
|
||||||
|
QMenu *helpMenu = menuBar->addMenu(tr("帮助(&H)")); // &H 表示快捷键 Alt+H
|
||||||
|
|
||||||
|
// 1.1 添加"版本信息"动作
|
||||||
|
QAction *versionAction = new QAction(tr("版本信息(&V)"), this);
|
||||||
|
helpMenu->addAction(versionAction);
|
||||||
|
connect(versionAction, &QAction::triggered, this, &MainWindow::mw_showVersionInfo);
|
||||||
|
|
||||||
|
// 1.2 添加"使用说明"动作
|
||||||
|
QAction *manualAction = new QAction(tr("使用说明(&M)"), this);
|
||||||
|
helpMenu->addAction(manualAction);
|
||||||
|
connect(manualAction, &QAction::triggered, this, &MainWindow::mw_showUserManual);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
|
: QMainWindow(parent)
|
||||||
|
, ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
// 设置程序标题
|
||||||
|
this->setWindowTitle(QString(tr("SP713控制软件 使用说明打开帮助->使用说明")).arg(VERSION).arg(MOD_TIME));
|
||||||
|
// // 初始化日志处理器并绑定UI
|
||||||
|
LogHandler::log_init(ui->plainTextEdit_logOutput);
|
||||||
|
|
||||||
|
// 连接日志信号到UI更新
|
||||||
|
connect(LogHandler::log_instance(), &LogHandler::log_messageLogged,
|
||||||
|
ui->plainTextEdit_logOutput, &QPlainTextEdit::appendPlainText,
|
||||||
|
Qt::QueuedConnection); // 确保跨线程安全
|
||||||
|
// // // 例化DRV_Spi对象
|
||||||
|
// this->m_DRV_Spi = new DRV_Spi(this);
|
||||||
|
// // // 查找Spi设备
|
||||||
|
// this->mw_findSpiDev();
|
||||||
|
|
||||||
|
// 例化APP_ICD类
|
||||||
|
this->m_APP_Icd = new APP_Icd(this);
|
||||||
|
// 初始化
|
||||||
|
this->m_APP_Icd->ICD_init();
|
||||||
|
// 表格初始化:一定要在APP_ICD类初始化后!!!!
|
||||||
|
this->mw_tableInit();
|
||||||
|
// 初始化寄存器配置中DAC通道值
|
||||||
|
for(int i = 1; i <= 256; i++)
|
||||||
|
{
|
||||||
|
this->ui->comboBox_icdDacCh->addItem(QString::number(i));
|
||||||
|
}
|
||||||
|
// 菜单栏初始化
|
||||||
|
this->mw_menuBarInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::mw_findSpiDev(void)
|
||||||
|
{
|
||||||
|
// 清空设备列表
|
||||||
|
this->ui->comboBox_spiDevList->clear();
|
||||||
|
// 枚举Spi设备
|
||||||
|
if(this->m_DRV_Spi->spi_enumDevice()){
|
||||||
|
this->ui->comboBox_spiDevList->addItem(this->m_DRV_Spi->m_DRV_Spi_Infors.bDeviceName);
|
||||||
|
}else{
|
||||||
|
//QMessageBox::question(NULL,"警告","未发现设备",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// void MainWindow::mw_findSpiDev(void)
|
||||||
|
// {
|
||||||
|
// // 清除相关的变量
|
||||||
|
// this->devices.clear();
|
||||||
|
// this->ui->comboBox_spiDevList->clear();
|
||||||
|
// // 获取 CH347 设备列表
|
||||||
|
// try {
|
||||||
|
// auto devList = this->spiApi.initUsbDevice();
|
||||||
|
// this->devices = QVector<DevSimple>::fromStdVector(devList);
|
||||||
|
// } catch (const std::exception &e) {
|
||||||
|
// DbgPrint("init USB device failed!");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (devices.isEmpty()) {
|
||||||
|
// DbgPrint("not find CH347 device!");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /***********************输出设备信息****************************/
|
||||||
|
|
||||||
|
// if(devices.length() != 0) {
|
||||||
|
// DbgPrint("Find %d CH347 devices!", devices.length());
|
||||||
|
|
||||||
|
// for(int i = 0; i < devices.length(); i++){
|
||||||
|
// DbgPrint("Manufacturer:%s Product:%s.", devices[i].ManufacturerString, devices[i].ProductString);
|
||||||
|
// this->ui->comboBox_spiDevList->addItem(devices[i].ProductString);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void MainWindow::mw_sendTestData(void)
|
||||||
|
// {
|
||||||
|
// /***********************配置参数(示例:设置 DAC 组的异值电压)****************************/
|
||||||
|
// SetCommandArg cmdArg;
|
||||||
|
// cmdArg.cmd_ = SetCommandArg::SP_CMD_DIF_VALUE;
|
||||||
|
// cmdArg.group_ = SetCommandArg::DAC;
|
||||||
|
// cmdArg.childGroup_ = 1; // 操作编号为 1 的 DAC
|
||||||
|
|
||||||
|
// SetVotegeArg voltageArg;
|
||||||
|
// for (int i = 0; i < 256; ++i) {
|
||||||
|
// // voltageArg.votes_.push_back(i); // 填充 256 个电压值(0-255)
|
||||||
|
// voltageArg.votes_.push_back(1); // 填充 256 个电压值(0-255)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// this->spiApi.debug();
|
||||||
|
|
||||||
|
// // 下发参数到第一个设备
|
||||||
|
// bool success = spiApi.applyArg(devices[0], cmdArg, voltageArg);
|
||||||
|
// if (success) {
|
||||||
|
// DbgPrint("Parameters applied successfully!");
|
||||||
|
// } else {
|
||||||
|
// DbgPrint("Failed to apply parameters!");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 刷新设备回调函数
|
||||||
|
void MainWindow::on_pushButton_refreshDev_clicked()
|
||||||
|
{
|
||||||
|
// 查找Spi设备
|
||||||
|
this->mw_findSpiDev();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭设备回调函数
|
||||||
|
void MainWindow::on_pushButton_closeDev_clicked()
|
||||||
|
{
|
||||||
|
// // 关闭设备
|
||||||
|
// if(!this->m_DRV_Spi->spi_closeDevice()){
|
||||||
|
// // QMessageBox::question(NULL,"错误","关闭设备失败!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
|
||||||
|
// }
|
||||||
|
// this->mw_sendTestData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开设备回调函数
|
||||||
|
void MainWindow::on_pushButton_openDev_clicked()
|
||||||
|
{
|
||||||
|
// // 打开设备
|
||||||
|
// if(!this->m_DRV_Spi->spi_openDevice(this->ui->comboBox_spiDevList->currentIndex())){
|
||||||
|
// // QMessageBox::question(NULL,"错误","打开设备失败!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查找串口设备
|
||||||
|
void MainWindow::on_pushButton_uartRefreshDev_clicked()
|
||||||
|
{
|
||||||
|
// 清空comboBox_uartDevList
|
||||||
|
if(this->ui->comboBox_uartDevList->count())
|
||||||
|
this->ui->comboBox_uartDevList->clear();
|
||||||
|
// 刷新UART设备
|
||||||
|
if(this->m_APP_Icd->m_uartDriver->Uart_enumDevice()){
|
||||||
|
// 将串口设备的名称添加至列表中
|
||||||
|
for(int i = 0; i < this->m_APP_Icd->m_uartDriver->m_DRV_Uart_Infors.ulDevCnt; i++)
|
||||||
|
this->ui->comboBox_uartDevList->addItem(this->m_APP_Icd->m_uartDriver->m_DRV_Uart_Infors.bDeviceName[i]);
|
||||||
|
}else{
|
||||||
|
QMessageBox::question(this,"ERROR","not find uart device!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开串口设备
|
||||||
|
void MainWindow::on_pushButton_uartOpenDev_clicked()
|
||||||
|
{
|
||||||
|
// 读取当前的设备索引号
|
||||||
|
ULONG index = this->ui->comboBox_uartDevList->currentIndex();
|
||||||
|
// 调用串口打开函数
|
||||||
|
BOOL status = this->m_APP_Icd->m_uartDriver->Uart_openDevice(index);
|
||||||
|
|
||||||
|
// 判断打开串口设备是否成功
|
||||||
|
if(status == TRUE){
|
||||||
|
// 打开成功. 则关闭或开启一些组件
|
||||||
|
this->ui->comboBox_uartDevList->setDisabled(true);
|
||||||
|
this->ui->pushButton_uartCloseDev->setEnabled(true);
|
||||||
|
this->ui->pushButton_uartOpenDev->setDisabled(true);
|
||||||
|
this->ui->pushButton_uartSetPara->setEnabled(true);
|
||||||
|
// 新建数据记录日志txt文件
|
||||||
|
if(!this->m_APP_Icd->ICD_newDataRecordingFile()){
|
||||||
|
QMessageBox::question(this,"ERROR","new Data Recording File failed!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 关闭串口函数
|
||||||
|
void MainWindow::on_pushButton_uartCloseDev_clicked()
|
||||||
|
{
|
||||||
|
// 调用串口关闭函数
|
||||||
|
BOOL status = this->m_APP_Icd->m_uartDriver->Uart_closeDevice();
|
||||||
|
|
||||||
|
// 判断打开串口设备是否成功
|
||||||
|
if(status == TRUE){
|
||||||
|
// 打开成功. 则关闭或开启一些组件
|
||||||
|
this->ui->comboBox_uartDevList->setEnabled(true);
|
||||||
|
this->ui->pushButton_uartCloseDev->setDisabled(true);
|
||||||
|
this->ui->pushButton_uartOpenDev->setEnabled(true);
|
||||||
|
this->ui->pushButton_uartSetPara->setDisabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 串口设置参数函数
|
||||||
|
void MainWindow::on_pushButton_uartSetPara_clicked()
|
||||||
|
{
|
||||||
|
// 读取组件中配置参数的值
|
||||||
|
ULONG Baudrate = this->ui->comboBox_uartBps->currentText().toUInt();
|
||||||
|
UCHAR StopBits = this->ui->comboBox_uartStop->currentIndex();
|
||||||
|
UCHAR Parity = this->ui->comboBox_uartVerify->currentIndex();
|
||||||
|
UCHAR DataSize = this->ui->comboBox_uartData->currentText().toUInt();
|
||||||
|
UCHAR Timeout = this->ui->lineEdit_uartTimeOut->text().toUInt();
|
||||||
|
// 调用配置参数函数进行配置
|
||||||
|
if(this->m_APP_Icd->m_uartDriver->Uart_setPara(Baudrate, StopBits, Parity, DataSize, Timeout) == FALSE){
|
||||||
|
QMessageBox::question(this,"ERROR","set uart para failed!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当分组的序号发生变化时
|
||||||
|
void MainWindow::on_comboBox_icdGroup_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
// 清除子分组的列表
|
||||||
|
this->ui->comboBox_icdSubGroup->clear();
|
||||||
|
// 设置子分组对应的列表
|
||||||
|
this->ui->comboBox_icdSubGroup->addItems(this->m_APP_Icd->comboBox_subGroupInfo.value(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送设置电压相关命令
|
||||||
|
void MainWindow::on_pushButton_icdSendVolCMD_clicked()
|
||||||
|
{
|
||||||
|
// 获取页面的命令、分组、子分组
|
||||||
|
uint8_t CMD = this->ui->comboBox_icdCmd->currentIndex() + 1;
|
||||||
|
uint8_t group = this->ui->comboBox_icdGroup->currentIndex();
|
||||||
|
if(group == 0)
|
||||||
|
group = 0xAA;
|
||||||
|
uint8_t subGroup = this->ui->comboBox_icdSubGroup->currentIndex();
|
||||||
|
if((subGroup == 0) && (group == 0xAA))
|
||||||
|
subGroup = 0xAA;
|
||||||
|
else
|
||||||
|
subGroup += 1;
|
||||||
|
// 调用设置电压命令编码函数
|
||||||
|
this->m_APP_Icd->ICD_volCMDProtoEncode(CMD, group, subGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写寄存器配置指令
|
||||||
|
void MainWindow::on_pushButton_icdRegConfig_clicked()
|
||||||
|
{
|
||||||
|
// 读取dac的编号值
|
||||||
|
uint8_t dacID = this->ui->comboBox_icdDacId->currentIndex()+1;
|
||||||
|
// 读取dac通道值
|
||||||
|
uint16_t dacCH = this->ui->comboBox_icdDacCh->currentIndex()+1;
|
||||||
|
// 判断是否为第256通道
|
||||||
|
if(dacCH == 256){
|
||||||
|
dacCH = 0;
|
||||||
|
dacID += 128;
|
||||||
|
}
|
||||||
|
// 读取funcEN值,将各个选项的使能值按照协议的报文格式叠加到funcEN数据中
|
||||||
|
uint8_t funcEN = 0x00;
|
||||||
|
if(this->ui->checkBox_icdEN_TADC->isChecked()){
|
||||||
|
funcEN += 1;
|
||||||
|
}
|
||||||
|
if(this->ui->checkBox_icdFBK_EN->isChecked()){
|
||||||
|
funcEN += 2;
|
||||||
|
}
|
||||||
|
if(this->ui->checkBox_icdTEMPTEST->isChecked()){
|
||||||
|
funcEN += 4;
|
||||||
|
}
|
||||||
|
if(this->ui->checkBox_icdTEST_EN->isChecked()){
|
||||||
|
funcEN += 8;
|
||||||
|
}
|
||||||
|
if(this->ui->checkBox_icdTRIG_TADC->isChecked()){
|
||||||
|
funcEN += 16;
|
||||||
|
}
|
||||||
|
// 读取adcCurrConfig值
|
||||||
|
uint8_t adcCurrConfig = this->ui->comboBox_icdRefCurr->currentIndex();
|
||||||
|
adcCurrConfig = adcCurrConfig*16 + this->ui->comboBox_icdADCClkPrs->currentIndex();
|
||||||
|
|
||||||
|
// 调用写寄存器编码函数
|
||||||
|
if(!this->m_APP_Icd->ICD_regWCMDProtoEncode(dacID, dacCH, funcEN, adcCurrConfig)){
|
||||||
|
QMessageBox::question(this,"ERROR","set reg para failed!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 寄存器回读命令
|
||||||
|
void MainWindow::on_pushButton_icdRegRead_clicked()
|
||||||
|
{
|
||||||
|
// 清楚
|
||||||
|
this->revData.clear();
|
||||||
|
// 读取dac的编号值
|
||||||
|
uint8_t dacID = this->ui->comboBox_icdDacId->currentIndex()+1;
|
||||||
|
// 读取寄存器的值
|
||||||
|
if(!this->m_APP_Icd->ICD_regRCMDProtoEncode(dacID)){
|
||||||
|
QMessageBox::question(this,"ERROR","write read reg para failed!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
|
||||||
|
}
|
||||||
|
// 读取串口接收区的数据
|
||||||
|
QThread::msleep(10); // 延时10毫秒
|
||||||
|
if(!this->m_APP_Icd->m_uartDriver->Uart_Read(this->revData)){
|
||||||
|
QMessageBox::question(this,"ERROR","read reg para failed!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
|
||||||
|
}
|
||||||
|
// 将返回的寄存器值显示到label界面
|
||||||
|
this->ui->label_icdRegRead->setText(this->revData.toHex(' ')); // 用空格分隔每个字节
|
||||||
|
// 记录读的数据
|
||||||
|
// this->m_APP_Icd->ICD_addContextToDataRecordingFile(false, this->revData);
|
||||||
|
// 解析数据
|
||||||
|
this->regParsedData = this->m_APP_Icd->ICD_parseRegisterData(this->revData);
|
||||||
|
qDebug() << "CH_TEST:" << this->regParsedData.CH_TEST \
|
||||||
|
<< ",EN_TADC:" << this->regParsedData.EN_TADC \
|
||||||
|
<< ",FBK_EN:" << this->regParsedData.FBK_EN \
|
||||||
|
<< ",TEMPTEST_EN:" << this->regParsedData.TEMPTEST_EN \
|
||||||
|
<< ",TEST_TADC:" << this->regParsedData.TEST_TADC \
|
||||||
|
<< ",TRIG_TADC:" << this->regParsedData.TRIG_TADC \
|
||||||
|
<< ",N_CLKDIV18:" << QString::number(this->regParsedData.N_CLKDIV18, 2).rightJustified(2, '0') \
|
||||||
|
<< ",ICON18:" << QString::number(this->regParsedData.ICON18, 2).rightJustified(4, '0') \
|
||||||
|
<< ",VCON:" << QString::number(this->regParsedData.VCON, 2).rightJustified(2, '0') \
|
||||||
|
<< ",EOC:" << this->regParsedData.EOC \
|
||||||
|
<< ",ADC_OUT:" << this->regParsedData.ADC_OUT \
|
||||||
|
<< ",D_FB:" << this->regParsedData.D_FB;
|
||||||
|
}
|
||||||
|
|
||||||
78
mainwindow.h
Executable file
78
mainwindow.h
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <drivers/spi/drv_spi.h>
|
||||||
|
#include <QVector>
|
||||||
|
#include "SpiApi.h"
|
||||||
|
#include "apps/icd/app_icd.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#define VERSION "V1.1"
|
||||||
|
#define MOD_TIME "25/07/17"
|
||||||
|
#define ICD_VERSION "V2.0.1"
|
||||||
|
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MainWindow(QWidget *parent = nullptr);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
/******************函数声明*****************/
|
||||||
|
static void mw_logOutPut(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
||||||
|
void mw_findSpiDev(void);
|
||||||
|
void mw_sendTestData(void);
|
||||||
|
void mw_tableInit(void);
|
||||||
|
|
||||||
|
void mw_onCellChanged(int row, int column);
|
||||||
|
void mw_menuBarInit(void);
|
||||||
|
|
||||||
|
// 定义对象
|
||||||
|
DRV_Spi *m_DRV_Spi; // spi驱动对象
|
||||||
|
APP_Icd *m_APP_Icd; // ICD应用层类
|
||||||
|
QByteArray revData;
|
||||||
|
// // SpiApi底层驱动类
|
||||||
|
SpiApi spiApi;
|
||||||
|
QVector<DevSimple> devices;
|
||||||
|
ParsedData regParsedData;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_pushButton_refreshDev_clicked();
|
||||||
|
|
||||||
|
void on_pushButton_closeDev_clicked();
|
||||||
|
|
||||||
|
void on_pushButton_openDev_clicked();
|
||||||
|
|
||||||
|
void on_pushButton_uartRefreshDev_clicked();
|
||||||
|
|
||||||
|
void on_pushButton_uartOpenDev_clicked();
|
||||||
|
|
||||||
|
void on_pushButton_uartCloseDev_clicked();
|
||||||
|
|
||||||
|
void on_pushButton_uartSetPara_clicked();
|
||||||
|
|
||||||
|
void on_comboBox_icdGroup_currentIndexChanged(int index);
|
||||||
|
|
||||||
|
void on_pushButton_icdSendVolCMD_clicked();
|
||||||
|
|
||||||
|
void on_pushButton_icdRegConfig_clicked();
|
||||||
|
|
||||||
|
void mw_showVersionInfo();
|
||||||
|
void mw_showUserManual();
|
||||||
|
|
||||||
|
void on_pushButton_icdRegRead_clicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
};
|
||||||
|
#endif // MAINWINDOW_H
|
||||||
1204
mainwindow.ui
Executable file
1204
mainwindow.ui
Executable file
File diff suppressed because it is too large
Load Diff
BIN
sp713.ico
Executable file
BIN
sp713.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 305 KiB |
1024
voltage_file/Vse_psi_-13.00_theta_13.53_opa_1.txt
Executable file
1024
voltage_file/Vse_psi_-13.00_theta_13.53_opa_1.txt
Executable file
File diff suppressed because it is too large
Load Diff
1024
voltage_file/Vse_psi_-14.00_theta_13.53_opa_1.txt
Executable file
1024
voltage_file/Vse_psi_-14.00_theta_13.53_opa_1.txt
Executable file
File diff suppressed because it is too large
Load Diff
1024
voltage_file/Vse_psi_-15.00_theta_13.53_opa_1.txt
Executable file
1024
voltage_file/Vse_psi_-15.00_theta_13.53_opa_1.txt
Executable file
File diff suppressed because it is too large
Load Diff
1024
voltage_file/Vse_psi_-16.00_theta_13.52_opa_1.txt
Executable file
1024
voltage_file/Vse_psi_-16.00_theta_13.52_opa_1.txt
Executable file
File diff suppressed because it is too large
Load Diff
0
voltage_file/Vse_psi_0.00_theta_13.52_opa_1.txt
Executable file
0
voltage_file/Vse_psi_0.00_theta_13.52_opa_1.txt
Executable file
1024
voltage_file/Vse_psi_11.00_theta_13.52_opa_1.txt
Executable file
1024
voltage_file/Vse_psi_11.00_theta_13.52_opa_1.txt
Executable file
File diff suppressed because it is too large
Load Diff
1024
voltage_file/Vse_psi_16.00_theta_13.53_opa_1.txt
Executable file
1024
voltage_file/Vse_psi_16.00_theta_13.53_opa_1.txt
Executable file
File diff suppressed because it is too large
Load Diff
1024
voltage_file/Vse_psi_5.00_theta_13.53_opa_1.txt
Executable file
1024
voltage_file/Vse_psi_5.00_theta_13.53_opa_1.txt
Executable file
File diff suppressed because it is too large
Load Diff
0
voltage_file/命名规范:Vse_psi_水平角度_theta_垂直角度_opa_opa标号.txt
Executable file
0
voltage_file/命名规范:Vse_psi_水平角度_theta_垂直角度_opa_opa标号.txt
Executable file
Reference in New Issue
Block a user