精华内容
下载资源
问答
  • 例如要发送如下bin文件,打开查看其内容如下 Pycharm中输入以下python代码 import serial try: ser = serial.Serial("COM4", 115200, timeout=0.5) if ser.is_open: print("COM4" + "打开成功") with open...

    例如要发送如下bin文件,打开查看其内容如下

    Pycharm中输入以下python代码

    import serial
    
    try:
        ser = serial.Serial("COM4", 115200, timeout=0.5)
        if ser.is_open:
            print("COM4" + "打开成功")
            with open('F:/Python/Demo.bin', 'rb') as f:
                a = f.read()
            print("正在发送bin文件")
            count = ser.write(a)
            print("发送完成,共发送字节数:", count)
    
    except Exception as e:
        print("---异常---:", e)

    运行上述代码

    通过另一个串口利用串口助手接收python串口发送的数据,可见接收到的数据和bin文件中的数据一模一样

    如果没有找到串口则提示异常信息

    原创作品,如需转载,请注明出处!

    https://blog.csdn.net/xiaowenshen/article/details/109332042

     

     

    展开全文
  • 我在做LPC1788 IAP升级,用串口发送bin文件,发送成功。但是程序不执行,比如说我写个小灯点亮的程序bin发给单片机,写入到flash了,就是没现象。是不是跳转程序有问题。我换了两个串口软件试的,请知道的大虾指点...
  • Qt利用串口读取bin文件,并采用定时器把bin文件发送出去
  • STM32串口烧录BIN文件、字库文件【QT上位机】 项目已开源至GitHub,供大家一起学习...使用串口通讯进行发送规定的帧数据,上位机会将BIN文件数据分析打包成每一帧传送给下位机。 下位机,接受到数据后,进行ACK应答,程

    STM32串口烧录BIN文件、字库文件【QT上位机】

    项目已开源至GitHub,供大家一起学习使用 点我传送

    一.上位机部分

    • 使用QT-C++ 编写的上位机 预览图如下
      在这里插入图片描述
    • 程序思路:
      使用串口通讯进行发送规定的帧数据,上位机会将BIN文件数据分析打包成每一帧传送给下位机。
      下位机,接受到数据后,进行ACK应答,程序接受到应答后,继续发送数据,直至完成发送。

    1.帧协议格式:

    在这里插入图片描述
    在这里插入图片描述

    如发送数据:C5 5C 00 00 04 22 33 44 FF AE 5C C5
    BCC = 除了帧头帧尾和bcc本身的异或
    BCC = 00 ^ 00 ^ 04 ^ 22 ^ 33 ^ 44 ^ FF = AE

    2.QT部分程序

    //将串口的 readyread 信号绑定到 read_com 这个槽函数上
    connect(&mySerial,SIGNAL(readyRead()),this,SLOT(read_COM()));
    

    此处读取到下位机的ACK应答后,触发自定义信号[readOK],再进行下一步发送

    void MainWindow::read_COM()
    {
        QByteArray mytemp = mySerial.readAll();
    
        if(!mytemp.isEmpty())
        {
            //qDebug() << mytemp.toHex();
            if((mytemp.at(0) & 0xff) != 0xC5)
                return;
            if((mytemp.at(1) & 0xff) != 0x5C)
                return;
            if((mytemp.at(5) & 0xff) == 0x00){
    
                ui->textEdit_Log->append("send Data OK!");
                sendedBytes += currentLen;
                unSendedBytes = file_length - sendedBytes;
                if(unSendedBytes < 0)
                    unSendedBytes = 0;
                ui->label_sendedBytes->setNum(sendedBytes);
                ui->label_unSendedBytes->setNum(unSendedBytes);
                ui->progressBar->setValue(static_cast<int>((static_cast<float>(sendedBytes) / static_cast<float>(file_length)) * 100));
                if(unSendedBytes > 0){
                    emit(recvOK());
                }else {
                    ui->textEdit_Log->append("all data send over!");
                    ui->pushButton_StartSending->setEnabled(true);
                }
    
            }
            else {
                ui->pushButton_StartSending->setEnabled(true);
                ui->textEdit_Log->append("send Data failed!");
                ui->textEdit_Log->append(QString("ERROR:%1").arg(mytemp.at(5) & 0xff));
            }
            //mytemp.clear();
        }
    }
    
    //将自定义的信号和发送函数连接
    connect(this, &MainWindow::recvOK, this, &MainWindow::sendOnce);
    
    
    void MainWindow::sendOnce(){
        QByteArray sendBuf, dataBuf;
    
        char file_length0,file_length1;
        QString str;
        char bcc = 0x00;
    
        if(unSendedBytes >= ui->lineEdit_ByteNum->text().toInt()){
            dataBuf = file_array.mid(sendedBytes, ui->lineEdit_ByteNum->text().toInt());
            currentLen = ui->lineEdit_ByteNum->text().toInt();
         }
        else {
            dataBuf = file_array.mid(sendedBytes, unSendedBytes);
            currentLen = unSendedBytes;
        }
        //qDebug() << dataBuf.size();
        sendBuf.clear();
        sendBuf.append("\xC5\x5C");
        sendBuf.append(static_cast<char>(0));
        file_length0 = static_cast<char>(currentLen / 0xFF);
        file_length1 = static_cast<char>(currentLen % 0xFF);
        sendBuf.append(file_length0);
        sendBuf.append(file_length1);
        //qDebug() << sendBuf.toHex().toUpper();
    
        sendBuf.append(dataBuf);
        //qDebug() << sendBuf.toHex().toUpper();
    
        for(int i = 2; i < sendBuf.size(); i++){
            //str.append((QString("%1  ").arg(file_array.at(i) & 0xff, 2, 16, QLatin1Char('0')).toUpper()));
            bcc ^= sendBuf.at(i) & 0xff;
        }
        sendBuf.append(bcc);
        sendBuf.append("\x5C\xC5");
        //qDebug() << sendBuf.toHex().toUpper();
    
        for(int i = 5; i < sendBuf.size() - 3; i++){
            str.append((QString("%1  ").arg(sendBuf.at(i) & 0xff, 2, 16, QLatin1Char('0')).toUpper()));
        }
        ui->textEdit_Status->append("---------------------------------------");
        ui->textEdit_Status->append(QString("地址[ %1 ] to [ %2 ] 的数据:").arg(sendedBytes).arg(sendedBytes + currentLen - 1));
        ui->textEdit_Status->append(str);
        ui->textEdit_Status->append(QString("---  BCC校验码: %1  ---").arg(bcc & 0xff, 2, 16, QLatin1Char('0')).toUpper());
    
        ui->textEdit_Log->append(QString("send [ %1 ] to [ %2 ] Data ...").arg(sendedBytes).arg(sendedBytes + currentLen - 1));
        mySerial.write(sendBuf);
    
    
    }
    

    二.下位机部分

    1.接收与处理

    上位机将BIN文件分成若干可设置数据长度的帧数据,以帧的形式串口发送给下位机,下位机接收帧,检验帧头帧尾和BCC校验码,如果正确无误,将数据烧写至外部储存器,烧写完成后,发送应答给上位机。上位机发送一帧数据后,会等待下位机的应答,接收到应答后,再继续发送下一帧数据,直至全部发送完成。

    2.ACK应答帧格式

    在这里插入图片描述

    3.下位机通用C++代码(Lib)

    //"transfer_BIN_to_EX_FLASH.h"
    #ifndef __transfer_BIN_to_EX_FLASH
    #define __transfer_BIN_to_EX_FLASH
    
    extern u8 TBEF_uart_recv_finish , TBEF_uart_recving_flag , rTBEF_uart_recv_tim_cnt;
    //extern u8 TBEF_recvBuf[400];
    //extern u16 TBEF_recvBuf_tail;
    
    
    
    void TBEF_uart_receive_process(u8 data);
    
    void TBEF_tim_process(void);
    void TBEF_SendACK(u8 ERROR);
    void TBEF_clearRecvBuf();
    u8 TBEF_framePrasing();
    void TBEF_mainFun();
    void TBEF_data_CallBack(u8 *dataBuf, u16 len);
    #endif
    
    
    
    /************************************************************************************
    *  Copyright (c), 2020, LXG.
    *
    * FileName		:
    * Author		:firestaradmin
    * Version		:1.0
    * Date			:2020.7.21
    * Description	:串口接收BIN文件数据烧录至外部储存器
    * History		:
    *
    *
    *************************************************************************************
    帧协议格式:
    		Byte0	Byte1	Byte2		Byte3		Byte4		Byte5	…		last but two Byte	last but one Byte	Last Byte
    		0xC5	0x5C	XX			XX			XX			XX		XX		XX					0x5C				0xC5
    		帧头	帧头	命令		长度高字节	长度低字节	数据	数据	BCC校验码			帧尾				帧尾
    		
    		如发送数据:C5 5C 00 00 04 22 33 44 FF AE 5C C5
    		BCC = 除了帧头帧尾和bcc本身的异或
    		BCC = 00 ^ 00 ^ 04 ^ 22 ^ 33 ^ 44 ^ FF = AE
    
    命令:	0x00	0x01			0x02			0xFF
    备注:	数据	数据传输开始	数据传输结束	应答
    
    *************************************************************************************/
    
    
    #include "stm32f10x.h"
    #include "../bsp/transfer_BIN_to_EX_FLASH/transfer_BIN_to_EX_FLASH.h"
    #include "../bsp/w25qxx/w25qxx.h" 
    #include "../BSP/usart/usart.h"
    
    //W25Q64
    //容量为8M字节,共有128个Block,2048个Sector 
    //4Kbytes为一个Sector
    //16个扇区为1个Block
    
    //以下表示地址为W25QXX的第一个区块的第0个扇区的第0个地址
    #define W25QXX_STORAGE_Block	1
    #define W25QXX_STORAGE_Sector	0
    #define W25QXX_STORAGE_Sector_OFFSET	0
    u32 TBEF_W25QXX_StorageAddress = W25QXX_STORAGE_Block * 4 * 1024 * 16 + 4 * 1024 * W25QXX_STORAGE_Sector + W25QXX_STORAGE_Sector_OFFSET;	//要烧录的具体地址
    u32 bytesStored = 0;	//已经储存的字节
    
    u8 TBEF_recvBuf[1000];	//接受buf,最大单次传输字节数应不大于buf大小-8
    u16 TBEF_recvBuf_tail = 0;
    u8 TBEF_uart_recv_finish = 0, TBEF_uart_recving_flag = 0, TBEF_uart_recv_tim_cnt = 0;
    
    
    //用户回调函数,此处修改需要烧录的函数
    void TBEF_data_CallBack(u8 *dataBuf, u16 len)
    {
    	//根据需求修改此处
    	W25QXX_Write(dataBuf, TBEF_W25QXX_StorageAddress + bytesStored, len);//写入flash
    	
    	bytesStored += len;
    }
    
    //串口处理函数,在串口中断中调用,将接收到的字节传入data
    void TBEF_uart_receive_process(u8 data)
    {  	
    	if(TBEF_uart_recv_finish == 0){
    		TBEF_recvBuf[TBEF_recvBuf_tail++] = data;		// 存入缓存数组
    		TBEF_uart_recving_flag = 1;                     // 串口 接收标志
    		TBEF_uart_recv_tim_cnt = 0;	                    // 串口接收定时器计数清零	
    	}
    	if(TBEF_recvBuf_tail >= sizeof(TBEF_recvBuf))
    	{
    		 TBEF_recvBuf_tail = 0;                               	// 防止数据量过大
    	}		
    	
    }
    
    //定时器处理函数,在定时器中断中调用,1Ms一次
    void TBEF_tim_process(void)		//1MS调用一次
    {
    	/* 串口接收完成判断处理 */
    	if(TBEF_uart_recving_flag)                        	// 如果 usart接收数据标志为1
    	{
    		TBEF_uart_recv_tim_cnt++;             // usart 接收计数	
    		if(TBEF_uart_recv_tim_cnt > 10)       // 当超过 3 ms 未接收到数据,则认为数据接收完成。
    		{
    			TBEF_uart_recv_finish = 1;
    			TBEF_uart_recving_flag = 0;
    			TBEF_uart_recv_tim_cnt = 0;
    		}
    	}
    	
    }
    
    //在主函数中调用,需要一直循环调用,此函数为阻塞函数
    void TBEF_mainFun()
    {
    	u8 ret = TBEF_framePrasing();
    	TBEF_recvBuf_tail = 0;
    	TBEF_uart_recv_finish = 0;
    	TBEF_SendACK(ret);
    }
    
    u8 TBEF_framePrasing()
    {
    	u16 length = 0;
    	u8 cmd = 0;
    	u8 bcc = 0x00;
    	while(TBEF_uart_recv_finish != 1);	//wait receive finish
    	
    	
    	if(TBEF_recvBuf[0] != 0xC5)
    		return 1;	//帧头错误
    	if(TBEF_recvBuf[1] != 0x5C)
    		return 1;	//帧头错误
    	cmd = TBEF_recvBuf[2];
    	length = TBEF_recvBuf[3] * 0xFF + TBEF_recvBuf[4];
    	
    	for(u16 i = 2; i < 5 + length; i ++){
    		bcc ^= TBEF_recvBuf[i];
    	}
    	
    	if(bcc != TBEF_recvBuf[5 + length])
    		return 2;	//bcc校验码错误
    	
    	if(TBEF_recvBuf[6 + length] != 0x5C)
    		return 3;	//帧尾错误
    	if(TBEF_recvBuf[7 + length] != 0xC5)
    		return 3;	//帧尾错误
    	
    	
    	if(cmd == 0x00)
    	{
    		TBEF_data_CallBack(TBEF_recvBuf + 5, length);
    	}
    	else if(cmd == 0x01)
    	{
    		bytesStored = 0;
    	}
    	else if(cmd == 0x02)
    	{
    	
    	}else {
    		
    	}
    	
    	
    	return 0;
    	
    }
    
    //如:C5 5C FF 00 01 00 FE 5C C5	表示没有错误
    void TBEF_SendACK(u8 ERROR)
    {
    	u8 sendBuf[9] = {0xC5, 0x5C, 0xFF, 0x00, 0x01, ERROR, 0x00, 0x5C, 0xC5};
    	sendBuf[6] = sendBuf[2] ^ sendBuf[3] ^ sendBuf[4] ^ sendBuf[5] ; 
    	
    	UartSendMultByte(USART1, sendBuf, 9);
    }
    
    void TBEF_clearRecvBuf()
    {
    	while(TBEF_recvBuf_tail--)
    	{
    		TBEF_recvBuf[TBEF_recvBuf_tail] = 0;
    	}
    	
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    展开全文
  • 本例由《qt开发环境 - ...实现功能:打开.bin文件,显示文件内容  通过串口按固定字节大小发送文件  显示串口收到的内容 下面是源代码: 代码下载地址:http://download.csdn.net/download/zn2857/10194028 /*

    本例由《qt开发环境 - 简易二进制文件打开,串口自发自收》更改来。(由qt官方terminal demo 修改)

    实现功能:打开.bin文件,显示文件内容

              通过串口按固定字节大小发送文件

              显示串口收到的内容

    下面是源代码:

    代码下载地址:http://download.csdn.net/download/zn2857/10194028

    /****************************************************************************
    **
    ** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com>
    ** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
    ** Contact: https://www.qt.io/licensing/
    **
    ** This file is part of the QtSerialPort module of the Qt Toolkit.
    **
    ** $QT_BEGIN_LICENSE:BSD$
    ** Commercial License Usage
    ** Licensees holding valid commercial Qt licenses may use this file in
    ** accordance with the commercial license agreement provided with the
    ** Software or, alternatively, in accordance with the terms contained in
    ** a written agreement between you and The Qt Company. For licensing terms
    ** and conditions see https://www.qt.io/terms-conditions. For further
    ** information use the contact form at https://www.qt.io/contact-us.
    **
    ** BSD License Usage
    ** Alternatively, you may use this file under the terms of the BSD license
    ** as follows:
    **
    ** "Redistribution and use in source and binary forms, with or without
    ** modification, are permitted provided that the following conditions are
    ** met:
    **   * Redistributions of source code must retain the above copyright
    **     notice, this list of conditions and the following disclaimer.
    **   * Redistributions in binary form must reproduce the above copyright
    **     notice, this list of conditions and the following disclaimer in
    **     the documentation and/or other materials provided with the
    **     distribution.
    **   * Neither the name of The Qt Company Ltd nor the names of its
    **     contributors may be used to endorse or promote products derived
    **     from this software without specific prior written permission.
    **
    **
    ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
    **
    ** $QT_END_LICENSE$
    **
    ****************************************************************************/
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    //#include "console.h"
    #include "settingsdialog.h"
    
    #include <QMessageBox>
    #include <QLabel>
    #include <QtSerialPort/QSerialPort>
    
    #include <QFile>
    #include <QFileDialog>
    #include <QDir>
    #include <QTextStream>
    #include <QDataStream>
    #include <QTimer>
    
    
    #define APP_DISPLAY_SIZE 64
    
    //! [0]
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
    //! [0]
        ui->setupUi(this);
    //    console = new Console;
    //    console->setEnabled(false);
    //    setCentralWidget(console);
    //! [1]
        serial = new QSerialPort(this);
    //! [1]
        settings = new SettingsDialog;
    
        ui->actionConnect->setEnabled(true);
        ui->actionDisconnect->setEnabled(false);
        ui->actionQuit->setEnabled(true);
        ui->actionConfigure->setEnabled(true);
    
        status = new QLabel;
        ui->statusBar->addWidget(status);
    
        initActionsConnections();
    
        connect(serial, static_cast<void (QSerialPort::*)(QSerialPort::SerialPortError)>(&QSerialPort::error),
                this, &MainWindow::handleError);
    
    //! [2]
        connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData);
    //! [2]
    //    connect(console, &Console::getData, this, &MainWindow::writeData);
    //! [3]
        timer = new QTimer(this);
        connect(timer,SIGNAL(timeout()),this,SLOT(timerTransDate()));
        ulNum = 0;
    //    timer->start(1000);
    //    setCentralWidget(MainWindow);
    }
    //! [3]
    
    MainWindow::~MainWindow()
    {
        delete settings;
        delete ui;
    }
    
    
    //! [4]
    void MainWindow::openSerialPort()
    {
        SettingsDialog::Settings p = settings->settings();
        serial->setPortName(p.name);
        serial->setBaudRate(p.baudRate);
        serial->setDataBits(p.dataBits);
        serial->setParity(p.parity);
        serial->setStopBits(p.stopBits);
        serial->setFlowControl(p.flowControl);
        if (serial->open(QIODevice::ReadWrite)) {
    //        console->setEnabled(true);
    //        console->setLocalEchoEnabled(p.localEchoEnabled);
            ui->actionConnect->setEnabled(false);
            ui->actionDisconnect->setEnabled(true);
            ui->actionConfigure->setEnabled(false);
            showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
                              .arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
                              .arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
        } else {
            QMessageBox::critical(this, tr("Error"), serial->errorString());
    
            showStatusMessage(tr("Open error"));
        }
    }
    //! [4]
    
    //! [5]
    void MainWindow::closeSerialPort()
    {
        if (serial->isOpen())
            serial->close();
    //    console->setEnabled(false);
        ui->actionConnect->setEnabled(true);
        ui->actionDisconnect->setEnabled(false);
        ui->actionConfigure->setEnabled(true);
        showStatusMessage(tr("Disconnected"));
    }
    //! [5]
    
    void MainWindow::about()
    {
        QMessageBox::about(this, tr("About Simple Terminal"),
                           tr("The <b>Simple Terminal</b> example demonstrates how to "
                              "use the Qt Serial Port module in modern GUI applications "
                              "using Qt, with a menu bar, toolbars, and a status bar."));
    }
    
    //! [6]
    void MainWindow::writeData(const QByteArray &data)
    {
        serial->write(data);
    }
    //! [6]
    
    //! [7]
    void MainWindow::readData()
    {
    //    QByteArray data = serial->readAll();
    
    //    console->putData(data);
        QByteArray temp = serial->readAll();
        QString buf;
    
            if(!temp.isEmpty()){
                ui->textBrowser->setTextColor(Qt::black);
    //                if(chrReceive->isChecked()){
    //                    buf = temp;
    //                }else if(hexReceive->isChecked()){
                        for(int i = 0; i < temp.count(); i++){
                            QString s;
                            s.sprintf("%02X ", (unsigned char)temp.at(i));
                            buf += s;
                        }
    //                }
    //            ui->textBrowser->setText(ui->textBrowser->document()->toPlainText() + buf);
                ui->textBrowser->append(buf);
    
                QTextCursor cursor = ui->textBrowser->textCursor();
                cursor.movePosition(QTextCursor::End);
                ui->textBrowser->setTextCursor(cursor);
    
                ui->receivebyteLcdNumber->display(ui->receivebyteLcdNumber->value() + temp.size());
    //            ui->statusBar->showMessage(tr("成功读取%1字节数据").arg(temp.size()));
    
            }
    
    }
    //! [7]
    
    //! [8]
    void MainWindow::handleError(QSerialPort::SerialPortError error)
    {
        if (error == QSerialPort::ResourceError) {
            QMessageBox::critical(this, tr("Critical Error"), serial->errorString());
            closeSerialPort();
        }
    }
    //! [8]
    
    void MainWindow::initActionsConnections()
    {
        connect(ui->actionConnect, &QAction::triggered, this, &MainWindow::openSerialPort);
        connect(ui->actionDisconnect, &QAction::triggered, this, &MainWindow::closeSerialPort);
        connect(ui->actionQuit, &QAction::triggered, this, &MainWindow::close);
        connect(ui->actionConfigure, &QAction::triggered, settings, &SettingsDialog::show);
        connect(ui->actionClear, &QAction::triggered, this, &MainWindow::clearTextBrowser);
        connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::about);
        connect(ui->actionAboutQt, &QAction::triggered, qApp, &QApplication::aboutQt);
    }
    
    void MainWindow::showStatusMessage(const QString &message)
    {
        status->setText(message);
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        timer->start(500);
    }
    
    void MainWindow::clearTextBrowser()
    {
        ui->textBrowser->setText(NULL);
    }
    
    void MainWindow::on_openFileButton_clicked()
    {
        //get file name
        fileName = QFileDialog::getOpenFileName(this,"Open File",QDir::currentPath());
    //    qDebug()<< "fileName is" << fileName;
        ui->filePathLineEdit->setText (fileName);
        if(fileName.isEmpty())
        {
            QMessageBox::information(this,"Error Message", "Please Select a Text File");
            return;
        }
        QFileInfo *pcsfileInfo = new QFileInfo(fileName);
        binSize = pcsfileInfo->size ();
    
        QFile* file = new QFile;
        file->setFileName(fileName);
        bool ok = file->open(QIODevice::ReadOnly);
        if(ok)
        {
    //        QTextStream in(file);
    //        ui->textEdit->setText(in.readAll());//read all context from the file
        }
        else
        {
            QMessageBox::information(this,"Error Message", "File Open Error" + file->errorString());
            return;
        }
        QDataStream in(file);
        char * binByte = new char[binSize];
        in.setVersion (QDataStream::Qt_5_9);
    
        ui->statusBar->showMessage(tr("准备读取数据"));
        in.readRawData (binByte, binSize);      //读出文件到缓存
        ui->statusBar->showMessage(tr("读取数据完毕"));
    
        tempByte = new QByteArray(binByte, binSize);                //格式转换
    
        QString *tempStr = new QString(tempByte->toHex ().toUpper ());
    
        //显示文件内容
        qint8 cnt = 1;
        qint16 kcnt = 0;
        for(qint64 i = 2; i < tempStr->size ();)
        {
            tempStr->insert (i, ' ');//每个字节之间空一格
            i += 3;
            cnt++;
            if(cnt == 8)//每8个字节空2格
            {
                tempStr->insert (i, ' ');
                i += 1;
            }
            if(cnt == 16)//每16个字节空一格
            {
                cnt = 1;
                kcnt ++;
                if(kcnt == 64)//每64行,即1K数据,空一行
                {
                    kcnt = 0;
                    tempStr->insert (i, '\n');
                    i++;
                }
                tempStr->insert (i, '\n');
                i += 3;         //避免换行后开头一个空格,换行相当于从新插入
            }
    
        }
        ui->statusBar->showMessage(tr("准备显示"));
        ui->fileViewPlainTextEdit->insertPlainText (*tempStr);
        ui->statusBar->showMessage(tr("显示完毕"));
    
    //    timer->start(1000);
    //    serial->write(binByte,25);
        delete tempByte;
        delete[] binByte;
        delete tempStr;
    
        file->close ();
        delete file;
    }
    void MainWindow::timerTransDate()
    {
        qint16 temp = 0;            //剩余待传数据
        qint16 FileSendEndFg;
    
    
        QFile *binFile = new QFile(fileName);
        binFile->open (QIODevice::ReadOnly);
        binFile->seek (ulNum * 1024);
    
        QDataStream in(binFile);
        char * binByte = new char[binSize];
        in.setVersion (QDataStream::Qt_5_9);
    
        in.readRawData (binByte, binSize);      //读出文件到缓存
    
        char * binLitByte = new char[64];//bin缓存
        static int binfileseek = 0;
    
        if(binfileseek > binSize)
        {
            binfileseek = 0;
            timer->stop();
            return;
        }
        memcpy (binLitByte, binByte + binfileseek, 64);
        binfileseek += 64;
    
        temp = binSize - 1024*ulNum;
    
        serial->write(binLitByte,64);
    
        delete binByte;
    
    }
    


    展开全文
  • ``` DWORD WINAPI ThreadWrite(LPVOID lpParameter)//进程1 { char outputData[100];//输出数据缓存 ...这样写用虚拟串口发送给串口助手时没有问题的,但是发送给单片机数据丢失特别严重望大佬指点。
  • 说明:本代码经本人测试,stm89c51等开发板传感器采集数据发送串口,实现读取并写入数据库,不懂之处大家留言,看见会及时回复大家。 1:读取串口数据写入csv文件: #!/usr/bin/python3 from PyQt5....

     

     

     

    问题咨询及项目源码下载请加群:

    群名:IT项目交流群

    群号:245022761

    说明:本代码经本人测试,stm89c51等开发板传感器采集数据发送到串口,实现读取并写入数据库,不懂之处大家留言,看见会及时回复大家。

     

     

    1:读取串口数据写入csv文件:

     

    #!/usr/bin/python3
    
    from PyQt5.QtCore import QTimer, QByteArray, QIODevice
    from PyQt5.QtSerialPort import QSerialPort, QSerialPortInfo
    
    from PyQt5.QtWidgets import *
    import sys
    
    from SaveData import *
    
    
    class SerialWidget(QWidget):
    
        def __init__(self, parent=None):
            super().__init__(parent)
    
            self.__data = QByteArray()
            self.__serial = QSerialPort()
            self.__timer = QTimer(self)
    
            for info in QSerialPortInfo.availablePorts():
                if info.description() == "USB-SERIAL CH340":
                    self.__serial = QSerialPort(info)
                    print(self.__serial.portName())
                    break
    
            self.__serial.readyRead.connect(self.__read_data)
            self.__timer.timeout.connect(self.__timer_update_com)
    
            self.__temperature = 0
            self.__humidity = 0
            self.__co2 = 0
            self.__tvoc = 0
            self.__pm25 = 0
            self.__pm10 = 0
            self.__o2 = 0
    
            if self.__serial.open(QIODevice.ReadWrite):
                print("open success")
            else:
                print("open fail")
            self.__auto_save_thread = AutoSave(self)
            self.__auto_save_thread.start()
    
        def closeEvent(self, QCloseEvent):
            self.__auto_save_thread.kill()
            super().closeEvent(QCloseEvent)
    
        def __read_data(self):
            self.__timer.start(40)
            self.__data.append(self.__serial.readAll())
    
        def __timer_update_com(self):
            self.__timer.stop()
            length = self.__data.length()
            i = 0
            while i < length:
                num = ord(self.__data[i])
                if num == 116:
                    num = ord(self.__data[i + 1])
                    self.__temperature = num
                    i += 1
                    print("temperature:" + str(self.__temperature))
                elif num == 116 - ord('t') + ord('h'):
                    num = ord(self.__data[i + 1])
                    self.__humidity = num
                    i += 1
                    print("humidity:" + str(self.__humidity))
                elif num == 116 - ord('t') + ord('c'):
                    num = ord(self.__data[i + 1]) * 258 + ord(self.__data[i + 2])
                    self.__co2 = num
                    i += 2
                    print("CO2:" + str(self.__co2))
                    num = ord(self.__data[i + 1]) * 258 + ord(self.__data[i + 2])
                    self.__tvoc = num
                    i += 2
                    print("TVOC:" + str(self.__tvoc))
                elif num == 116 - ord('t') + ord('o'):
                    num = ord(self.__data[i + 1]) * 258 + ord(self.__data[i + 2])
                    num = num * (3300 / 4096) / 100
                    num = round(num, 3)
                    self.__o2 = num
                    i += 2
                    print("O2:" + str(self.__o2) + "%")
                elif num == 116 - ord('t') + ord('p'):
                    num = ord(self.__data[i + 1]) * 258 + ord(self.__data[i + 2])
                    num /= 10
                    self.__pm25 = num
                    i += 2
                    print("PM2.5:" + str(self.__pm25))
                    num = ord(self.__data[i + 1]) * 258 + ord(self.__data[i + 2])
                    num /= 10
                    self.__pm10 = num
                    i += 2
                    print("PM10:" + str(self.__pm10))
                i += 1
            self.__data.clear()
    
        def get_temperature(self):
            return self.__temperature
    
        def get_humidity(self):
            return self.__humidity
    
        def get_co2(self):
            return self.__co2
    
        def get_tvoc(self):
            return self.__tvoc
    
        def get_pm25(self):
            return self.__pm25
    
        def get_pm10(self):
            return self.__pm10
    
        def get_o2(self):
            return self.__o2
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        my_serial = SerialWidget()
        my_serial.show()
        sys.exit(app.exec_())
    

     

     

    数据保存:

    #!/usr/bin/python3
    
    import threading
    import time
    import os
    
    from openpyxl import Workbook, load_workbook
    from openpyxl.styles import Font
    
    
    class SaveData:
    
        def __init__(self, my_serial):
            self.serial = my_serial
            self.__dirpath = "../Data/"
            if not os.path.exists(self.__dirpath):
                os.makedirs(self.__dirpath)
    
        @staticmethod
        def check_path(filepath):
            if not os.path.exists(filepath):
                new_workbook = Workbook()
                new_workbook.save(filepath)
    
        @staticmethod
        def insert_headings(current_sheet):
            columns = ["Time", "Temperature", "Humidity", "CO2", "TVOC", "O2", "PM2.5", "PM10"]
            for i in range(8):
                cell = current_sheet.cell(column=i + 1, row=1, value=columns[i])
                cell.font = Font(size=12, bold=True)
    
        def save_to_local(self):
            localtime = time.localtime(time.time())
            filepath = self.__dirpath + time.strftime("%Y_%m", localtime) + ".xlsx"
            self.check_path(filepath)
            current_workbook = load_workbook(filepath)
    
            sheetname = time.strftime("%m-%d", localtime)
            current_sheet = current_workbook.active
            for sheet in current_workbook:
                if sheet.title == "Sheet":
                    sheet.title = sheetname
                    self.insert_headings(sheet)
                    current_workbook.save(filepath)
                    current_sheet = sheet
                    break
                elif sheet.title == sheetname:
                    current_sheet = sheet
                    break
            if current_sheet.title != sheetname:
                current_sheet = current_workbook.create_sheet(sheetname)
                self.insert_headings(current_sheet)
                current_workbook.save(filepath)
    
            current_time = time.strftime("%H:%M", localtime)
            temperature = self.serial.get_temperature()
            humidity = self.serial.get_humidity()
            co2 = self.serial.get_co2()
            tvoc = self.serial.get_tvoc()
            o2 = self.serial.get_o2()
            pm25 = self.serial.get_pm25()
            pm10 = self.serial.get_pm10()
            new_data = [current_time, temperature, humidity, co2, tvoc, o2, pm25, pm10]
            current_sheet.append(new_data)
            current_workbook.save(filepath)
    
    
    class AutoSave(threading.Thread):
    
        def __init__(self, my_serial):
            threading.Thread.__init__(self)
            self.name = "auto_save_data"
            self.serial = my_serial
            self.__save_data = SaveData(self.serial)
            self.__saved = False
            self.__closed = False
    
        def run(self):
            while True:
                if self.__closed:
                    break
                localtime = time.localtime(time.time())
                if localtime.tm_min == 0 and not self.__saved:
                    self.__save_data.save_to_local()
                    self.__saved = True
                elif localtime.tm_min != 0:
                    self.__saved = False
    
        def kill(self):
            self.__closed = True
    
    
    if __name__ == '__main__':
        my_thread = AutoSave()
        my_thread.start()
        my_thread.kill()
    

     

     

     

    2:读取串口数据写入数据库:

    #备注 代码根据自己数据库及存储格式修改
    
    import serial
    import pymysql  # 导入pymysql包
    
    # import easygui
    log = 0
    ser = serial.Serial()
    
    ser.baudrate = 9600  # 设置波特率(这里使用的是stc89c52)
    ser.port = 'COM12'  # 端口是COM3
    print(ser)
    ser.open()  # 打开串口
    print(ser.is_open)  # 检验串口是否打开
    db = pymysql.connect("localhost", "root", "", "test")  # 打开数据库,配置数据库
    
    cursor = db.cursor()  # 数据库操作
    cursor.execute("DROP TABLE IF EXISTS Monitor_Data")  # 如果存在表则重新创建
    
    creatTab = """CREATE TABLE Monitor_Data( # 创建表
    
        LOG_ID INT NOT NULL,
        temp CHAR(50),
        temp_value CHAR(50),
        guang CHAR(50),
        guang_value CHAR(50)
    
         )"""
    
    cursor.execute(creatTab)  # 执行数据库语句
    
    while (1):
        # Yes_or_No = easygui.buttonbox("是否良品?", choices=[ 'Yes', 'No', '退出' ])  # 提供简易UI
        # if Yes_or_No == '退出': break
        # if Yes_or_No == 'Yes':
        #     demo = b"2"  # 传入2的ASCII码 这里用b+str强制转换
        # else:
        #     demo = b"1"  # 传入1的ASCII码 这里用b+str强制转换
    
        # ser.write()
        s = ser.readline()
        log += 1  # 传输次数记录+1
        data_pre = str(s)  # 强制用字符串格式
    
        data = data_pre[ 2:-2 ]  # 取部分数据
        did = data_pre[ 2:6 ]  # 分类取有效数据
        did1 = data_pre[ 8:12 ]  # 分类取有效数据
        did2 = data_pre[ 13: 18 ]  # 分类取有效数据
        did3 = data_pre[ 20:25 ]  # 分类取有效数据
    
        print(log, did, did1, did2, did3)
        sql = "INSERT INTO Monitor_Data(LOG_ID,temp,temp_value,guang,guang_value)VALUES('%d','%s','%s','%s','%s')" % (
        log, did, did1, did2, did3)  # 存入数据库
        cursor.execute(sql)  # 执行数据库语句
    

     

    展开全文
  • 打开一个bin文件,读取里面的内容,然后将内容按照每组256个字节进行分组, byte[] buf = new byte[];发送第一组256个字节内容,前面加上FF B5 最终变成 FF B5 +256 总共258个内容进行发送,然后等待收到回复确认...
  • 打开串口调试助手,波特率不为默认波特率74880,则会显示乱码,但很多的串口调试助手是没有74880的频率设置的,可以选择custom进行设置,或者使用安信可自家的串口调试助手。。 设置波特率为74880(例程默认的波特...
  • vb串口通讯上传文件

    2010-08-10 18:12:17
    上传bin文件给单片机,企业用,起到连接发送功能
  • 问题描述如标题,如果发送的是全英文的时候或少数中文字的时候,对比发送和保存文件内容一致,没有丢数据。我(用了14万行文件发送,收到的数据对比都正确) 个人认为:GB2312编码中文字是2个字节表示,串口在读...
  • [STAThread] [DllImport("sms.dll", EntryPoint = "Sms_Connection")] ... [DllImport("sms.dll... 然后又将sms.dll文件放在了项目bin目录下,以及release和debug目录下,程序干脆就启动不起来了,请大神指点。
  • 1. 前提条件:u-boot.bin通过Jtag烧写到0x1000 0000中 U-boot->loadb 2010 0000 选择要下载的地址 ...这时候选择超级终端菜单上:传送>发送文件>文档名选择uImage>协议选择Kermit,点发送。能够看到发送
  • 编写好的基于STM32F207的串口IAP程序,也就是引导加载程序(Bootloader)分配64K的内存大小,可通过串口发送.BIN文件直接升级APP程序。
  • stm32 IAP 串口

    2019-04-23 14:20:42
    stm32通过串口来升级,从uboot启动,如果不需要升级代码,则直接跳转到...对于我的app足够用),在app中随意按下按键,通过可以从应用程序跳转到uboot,然后发送1,通过ymodem协议发送.bin文件后,按下3则跳转应用程序
  • 概述 上位机使用Qt开发,计划整合多个工具为一体,用作以后的调试工具。...选择文件,启动升级之后会间隔100ms 向下位机发送S,等待下位机应答'C',开始通过Ymodem 发送bin文件。 3、和校验计算 4...
  • 多功能串口调试助手

    2015-12-01 17:29:15
    此功能可以把Hex文件转化为Bin文件,供单片机下载程序。 (四)字符转工具 (1)可以支持ASCII转字符 (2)可以支持字符(中文,英文字符串都可以)转ASCII(UTF8),是单片机工程师,嵌入式工程师,做液晶字符显示强...
  • java串口通信

    2019-01-23 11:40:02
    把该dll文件放置到jdk,jre的bin目录下,通过java的RXTXcomm.jar第三方库进行二次开发,发送指令或接受返回消息
  • ROS实现串口通信

    2020-10-18 21:23:51
    参考Linux下添加虚拟串口,接收和发送数据 com.py文件代码如下: #! /usr/bin/env python #coding=utf-8 import pty import os import select def mkpty(): # master1, slave = pty.openpty() slaveName1 = os...
  • 串口IAP升级在正点原子的例程中有讲解,正点原子的方法是:在RAM中开辟一个120K的数据空间,用来存放bin文件bin文件通过串口一次性发送到单片机,然后再实现程序的跳转。但是这种方法在实际项目中并不实用,因为...
  • 因此,当APP程序需要升级时只需通过串口将.bin文件发送至BootLoader引导程序即可。 1、BootLoader引导程序编写 由于需要将APP程序存储至flash,因此需要调用flash读写api,(需要添加f021flash读写api、增加cmd文件...
  • springboot + mina 实现串口通讯

    千次阅读 热门讨论 2019-09-06 13:35:24
    记一次串口开发,以下代码只能调用本机的串口发送指令。 下载mfz-rxtx-2.2-20081207-win-x64压缩包,将以下三个文件放入指定文件夹内。 Copy RXTXcomm.jar ---> <JAVA_HOME>\jre\lib\ext Copy rxtxSerial....
  • IAP是应用编程,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级,后续产品发布后,更新程序我只需要把.bin文件通过串口发送给芯片就可以执行更 新,很方便产品的维护工作。对于...
  • STM32F4串口IAP固件更新

    千次阅读 2014-03-27 20:17:12
    STM32F4串口IAP固件更新操作过程: 修改ST官方IAP程序,使之能在自己的开发板跑起来,关键是串口、...选择传送--发送文件--浏览,选择要发送的.bin文件,并且协议选择Ymodem。最后,发
  • 用Java实现串口通信(windows系统下),需要用到sun提供的串口包 javacomm20-win32.zip。其中要用到三个文件,配置如下: 1.comm.jar放置到 JAVA_HOME/jre/lib/ext...电子秤称重时,计算机通过串口给称重控制显示器发送
  • 我们有个升级stm32的需求,需要通过发送bin文件,虽然有cutecom但是发送的方式不一样,明显速度慢很多,这个差异有再研究,所以决定,在ubuntu上使用sscom来发送文件 网上找了sscom的 linux版本,不大行,没有成功,...

空空如也

空空如也

1 2 3 4 5
收藏数 97
精华内容 38
关键字:

串口发送bin文件