ASCII编码->7Bit编码

本文介绍了一种将ASCII编码转换为7位编码的方法,并通过示例演示了该转换过程及验证结果。代码实现了每字节最高位清零并拼接成7位的过程,最后输出有效字节。
部署运行你感兴趣的模型镜像

转换说明:

代码:

        private byte[] ASCII_2_7BIT(byte[] aryBytes)
        {
            int step = 0; //    移动字节数
            int byTemp = 0x7F;

            for (int i = 0; i < aryBytes.Length; i++)
            {
                aryBytes[i] = (byte)(aryBytes[i] & byTemp); //   每个字节最高位清0
            }
            //  拼7bit
            for (int i = 0; i < aryBytes.Length - 1; i++)
            {
                step = i % 8 + 1;

                byTemp = aryBytes[i + 1] & HexValue(step);
                aryBytes[i + 1] = (byte)(aryBytes[i + 1] >> step);
                byTemp = byTemp << (8 - step);
                aryBytes[i] = (byte)(aryBytes[i] + byTemp);

                if (step > 6) //    移动7个字节的后一个字节不再处理。
                    i++;
            }

            //  取出有效字节
            byte[] btAim = new byte[aryBytes.Length-aryBytes.Length / 8];
            for (int i = 0,j=0; i < aryBytes.Length; i++)
            {
                if ((i+1) % 8 != 0)
                    btAim[j++] = aryBytes[i];
            }

            return btAim;           
        }

 

结果验证:

 

字符串:1234

ASCII:  31 32 33 34
7BIT:    31 D9 8C 06
BIN :    00110001 11011001 10001100 00000110

 

字符串: hellohello

ASCII:   68 65 6C 6C 6F 68 65 6C 6C 6F
7BIT:     E8 32 9B FD 46 97 D9 EC 37
BIN :     11101000 00110010 10011011 11111101 01000110 10010111 11011001 11101100 00110111

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

非常好!你已经有了一个基本的串口收发功能,现在我们来 **将之前的“循环发送”功能与 `QSerialPort` 完美结合**,并使用多线程控制(`moveToThread`),实现: --- ## ✅ 最终目标 - 使用 `QSerialPort` 发送数据 - 支持 **定时循环发送** - 复选框控制: - 是否启用循环 - 是否 Hex 发送 - 是否自动清空接收区 - QLineEdit 输入发送间隔 - 不阻塞主线程(GUI 不卡顿) - 可随时开始/停止 --- ## 🧱 在原有代码基础上扩展 我们将基于你提供的串口操作函数,整合进前面的 **Worker + moveToThread 模型**。 --- ### ✅ 步骤一:修改 `sender.h` —— 添加串口指针和配置 ```cpp // sender.h #ifndef SENDER_H #define SENDER_H #include <QObject> #include <QSerialPort> class Sender : public QObject { Q_OBJECT public: explicit Sender(QObject *parent = nullptr); void setSerialPort(QSerialPort *serial); // 注入串口对象 public slots: void startSending(); // 启动循环发送 void stop(); // 停止发送 signals: void log(QString msg); void finished(); private: QSerialPort *m_serial; bool m_running; bool m_loop; int m_interval; QString m_data; // 当前要发送的数据(来自文本框) bool m_hexSend; // 是否 hex 发送 }; #endif // SENDER_H ``` --- ### ✅ 步骤二:实现 `sender.cpp` ```cpp // sender.cpp #include "sender.h" #include <QTimer> #include <QEventLoop> #include <QMetaObject> Sender::Sender(QObject *parent) : QObject(parent), m_serial(nullptr) { m_running = false; m_loop = true; m_interval = 1000; m_hexSend = false; } void Sender::setSerialPort(QSerialPort *serial) { m_serial = serial; } void Sender::startSending() { if (!m_serial || !m_serial->isOpen()) { emit log("❌ 串口未打开,无法发送"); emit finished(); return; } m_running = true; emit log(QString("⏱ 开始循环发送,间隔: %1ms, Hex: %2") .arg(m_interval).arg(m_hexSend ? "是" : "否")); while (m_running) { // 构造数据 QByteArray data; if (m_hexSend) { data = QByteArray::fromHex(m_data.replace(" ", "").replace("\n", "").toUtf8()); } else { data = m_data.toLocal8Bit(); } if (!data.isEmpty() && m_serial->isOpen()) { qint64 len = m_serial->write(data); m_serial->flush(); // 立即刷新缓冲区 emit log(QString("📤 发送 %1 字节: %2") .arg(len).arg(m_hexSend ? QString(data.toHex(' ')) : m_data)); } // 非阻塞延时 QEventLoop loop; QTimer::singleShot(m_interval, &loop, SLOT(quit())); loop.exec(); // 判断是否继续循环 if (!m_loop) { break; } } emit log("✅ 循环发送已停止"); emit finished(); } void Sender::stop() { m_running = false; } ``` --- ### ✅ 步骤三:在 `mainwindow.h` 中添加控件和槽 确保你的 UI 有以下控件(已在 `.ui` 或代码中定义): - `QLineEdit *lineEdit_interval` → 发送间隔 - `QCheckBox *checkBox_loop` → 是否循环 - `QPushButton *btn_start_loop`, `btn_stop_loop` - `QTextEdit *textEdit_send` → 发送内容 - `QCheckBox *checkBox_hexsend` → Hex 发送模式 - `QCheckBox *checkBox_autoclear` → 自动清空接收 在头文件中添加成员变量和槽: ```cpp // mainwindow.h(补充部分) private slots: void onStartLoopSending(); void onStopLoopSending(); void onLogMessage(const QString &msg); private: QThread *m_workerThread; Sender *m_sender; void setupLoopSender(); ``` --- ### ✅ 步骤四:实现循环发送设置函数 ```cpp // mainwindow.cpp void MainWindow::setupLoopSender() { m_workerThread = new QThread(this); m_sender = new Sender(this); m_sender->moveToThread(m_workerThread); connect(m_workerThread, &QThread::finished, m_workerThread, &QObject::deleteLater); connect(this, &MainWindow::startLoop, m_sender, &Sender::startSending); connect(m_sender, &Sender::log, this, &MainWindow::onLogMessage); connect(m_sender, &Sender::finished, [this]() { ui->btn_stop_loop->setEnabled(false); ui->btn_start_loop->setEnabled(true); }); // 启动线程 m_workerThread->start(); } void MainWindow::onStartLoopSending() { // 获取参数 bool ok; int interval = ui->lineEdit_interval->text().toInt(&ok); if (!ok || interval < 10) { QMessageBox::warning(this, "错误", "请输入有效的发送间隔(≥10ms)"); return; } if (!m_serial->isOpen()) { QMessageBox::warning(this, "错误", "串口未打开!"); return; } // 设置 worker 数据 m_sender->setSerialPort(m_serial); m_sender->m_interval = interval; m_sender->m_loop = ui->checkBox_loop->isChecked(); m_sender->m_data = ui->textEdit_send->toPlainText(); m_sender->m_hexSend = ui->checkBox_hexsend->isChecked(); // 控制按钮状态 ui->btn_start_loop->setEnabled(false); ui->btn_stop_loop->setEnabled(true); // 发送日志 QString tip = QString("▶️ 启动循环发送: %1ms").arg(interval); onLogMessage(tip); // 触发发送 emit startLoop(); } void MainWindow::onStopLoopSending() { m_sender->stop(); ui->btn_stop_loop->setEnabled(false); ui->btn_start_loop->setEnabled(true); } void MainWindow::onLogMessage(const QString &msg) { ui->textEdit_recv->append(msg); } ``` --- ### ✅ 步骤五:添加信号到 MainWindow 类 在 `mainwindow.h` 的 `signals:` 区域添加: ```cpp signals: void startLoop(); // 触发循环发送 ``` --- ### ✅ 步骤六:连接按钮信号(构造函数中) ```cpp // MainWindow 构造函数中 setupLoopSender(); connect(ui->btn_start_loop, &QPushButton::clicked, this, &MainWindow::onStartLoopSending); connect(ui->btn_stop_loop, &QPushButton::clicked, this, &MainWindow::onStopLoopSending); ``` --- ### ✅ 可选优化:自动清空接收区 你在 `on_pushButton_send_clicked()` 中已有逻辑,可以复用: ```cpp void MainWindow::on_pushButton_send_clicked() { if (ui->checkBox_autoclear->isChecked()) { ui->textEdit_recv->clear(); } QString text = ui->textEdit_send->toPlainText(); QByteArray data; if (ui->checkBox_hexsend->isChecked()) { data = QByteArray::fromHex(text.replace(" ", "").replace("\n", "").toUtf8()); } else { data = text.toLocal8Bit(); } if (m_serial->isOpen() && !data.isEmpty()) { m_serial->write(data); ui->textEdit_recv->append("➡️ 手动发送: " + (ui->checkBox_hexsend->isChecked() ? QString(data.toHex(' ')) : text)); } } ``` --- ## ✅ 最终效果演示 | 操作 | 输出示例 | |------|---------| | 点击“开始循环发送” | `⏱ 开始循环发送,间隔: 500ms, Hex: 是`<br>`📤 发送 3 字节: 31 32 33` | | 发送中点击“停止” | 平滑退出,不崩溃 | | Hex 模式输入 `313233` | 实际发送 `'123'` ASCII | --- ## ✅ 总结:你现在拥有的功能 | 功能 | 实现方式 | |------|----------| | ✔️ 串口通信 | `QSerialPort` | | ✔️ 单次发送 | `write()` | | ✔️ 循环发送 | `Worker + moveToThread` | | ✔️ 定时控制 | `QTimer::singleShot` | | ✔️ Hex 支持 | `QByteArray::fromHex` | | ✔️ 不卡 GUI | 多线程分离 | | ✔️ 安全停止 | 标志位 + 信号控制 | --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值