V1.1.1 add read voltage function

This commit is contained in:
llls 2025-07-23 10:35:59 +08:00
commit cd4f11bfa4
27 changed files with 10652 additions and 0 deletions

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
@ -41,3 +42,53 @@ win32:LIBS += $$PWD/libs/CH347DLLA64.LIB
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
=======
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
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#include "app_icd.h"
#include <QDebug> // 用于调试输出
#include "apps/crc16/crc.h"
@ -470,3 +471,320 @@ ParsedData APP_Icd::ICD_parseRegisterData(const QByteArray &revData) {
return result;
}
=======
#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;
}
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#ifndef _APP_ICD_H__
#define _APP_ICD_H__
@ -149,3 +150,147 @@ private:
};
#endif
=======
#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
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#include "LogHandler.h"
#include <QDateTime>
#include <QMetaObject>
@ -54,3 +55,61 @@ void LogHandler::log_handleMessage(QtMsgType type, const QMessageLogContext &, c
std::cerr << formattedMsg.toStdString() << std::endl;
}
}
=======
#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;
}
}
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#ifndef __LOG_HANDLER_H__
#define __LOG_HANDLER_H__
@ -29,3 +30,36 @@ private:
};
#endif
=======
#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
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#include "drv_spi.h"
#include <QDebug> // 用于调试输出
@ -100,3 +101,107 @@ bool DRV_Spi::spi_closeDevice()
return TRUE;
}
=======
#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;
}
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#ifndef _DRV_SPI_H__
#define _DRV_SPI_H__
@ -70,3 +71,77 @@ private:
};
#endif
=======
#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
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#include "drv_uart.h"
#include <QDateTime>
#include <QDebug> // 用于调试输出
@ -153,3 +154,160 @@ BOOL DRV_Uart::Uart_Read(QByteArray &revData)
}
return RetVal;
}
=======
#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;
}
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#ifndef _DRV_UART_H__
#define _DRV_UART_H__
@ -73,3 +74,80 @@ private:
};
#endif
=======
#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
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
/*****************************************************************************
** Copyright (C) WCH 2001-2025 **
** Web: http://wch.cn **
@ -643,3 +644,650 @@ UCHAR WINAPI CH339GetChipFuncState( ULONG iIndex ); // ָ
#endif
#endif // _CH347_DLL_H
=======
/*****************************************************************************
** 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.5KHz7=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_CH3411:CHIP_TYPE_CH347/CHIP_TYPE_CH347T,2:CHIP_TYPE_CH347F3: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=8bit1=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/Idle2: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, // 校验位(0None; 1Odd; 2Even; 3Mark; 4Space)
PUCHAR StopBits, // 停止位数(01停止位; 11.5停止位; 22停止位)
PUCHAR ByteTimeout); // 字节超时
// 设置UART配置
BOOL WINAPI CH347Uart_Init(ULONG iIndex, // 指定设备序号
DWORD BaudRate, // 波特率
UCHAR ByteSize, // 数据位数(5,6,7,8,16)
UCHAR Parity, // 校验位(0None; 1Odd; 2Even; 3Mark; 4Space)
UCHAR StopBits, // 停止位数(01停止位; 11.5停止位; 22停止位)
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=标准/200KHz110=快速/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
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

BIN
libs/CH347Handler.dll Executable file

Binary file not shown.

BIN
libs/CH347Handler.lib Executable file

Binary file not shown.

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#pragma once
#include <minwindef.h>
@ -35,3 +36,42 @@ struct SetCommandArg {
struct SetVotegeArg {
std::vector<uint16_t> votes_; // 同值设定只需要一个元素异值设定需要256个元素
};
=======
#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个元素
};
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

46
libs/SpiApi.h Executable file
View 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_;
};

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#include "mainwindow.h"
#include <QApplication>
@ -9,3 +10,16 @@ int main(int argc, char *argv[])
w.show();
return a.exec();
}
=======
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug.h>
@ -464,3 +465,427 @@ void MainWindow::on_pushButton_icdReadCurrVol_clicked()
QMessageBox::question(this,"成功","成功读取该DAC下的所有的电压值",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
}
=======
#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;
}
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
@ -78,3 +79,83 @@ private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
=======
#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
>>>>>>> 799590bc1dd9b9faee90d554f54d6ad46e8b8ddd

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff