feedforward 发表于 2020-8-3 10:34:43

Windows下如何不通过串口调试助手进行串口发送

      最近使用的一款处理器有点残疾,直接通过DSU和处理器建立连接会失败!100%!解决办法是连接前通过DSU向处理器发送一帧数据,之后再通过DSU和处理器建立连接。常规做法是先通过串口调试助手向DSU发数,收到回应后关闭串口调试助手,再通过DSU建立连接。遗憾的是这个处理器调试过程中很容易死机,而且死机之后必须要进行复位才能重新通过DSU建立连接。这就有点麻烦了,每次都需要关闭DSU—>打开串口调试助手—>发送数据帧—>关闭串口—>启动DSU接连连接。。。极其繁琐。能不能写段代码,在启动DSU时先自动执行这段代码向DSU发送数据帧呢?下面开启折腾旅程。
       由于连接DSU的grmon是编译好的工具,我们无法修改,所以首先考虑能否采用Windows下的批处理程序实现该功能。需要向DSU发送的数据帧为:0x55 0x55 0x55 0x55 0x55 0x55 0x80 0x81 0x00 0x00 0x00,现学现用写了一段代码:

mode com4:115200,N,8,1
set var=0x55 0x55 0x55 0x55 0x55 0x55 0x80 0x81 0x00 0x00 0x00
for %%a in (%var%) do (
echo %%a>com4
)
pause
      用串口调试助手进行接收测试,16进制显示,收到的数据帧竟然如下:
35 35 20 35 35 20 35 35 20 35 35 20 35 35 20 35 35 20 38 30 20 38 31 20 30 30 20 30 30 20 30 30

      显然,16进制的数据帧0x55 0x55 0x55 0x55 0x55 0x55 0x80 0x81 0x00 0x00 0x00被当做字符串发送了!于是问题归结为如何不采用串口调试助手发送16进制数据帧?由于本次待发送的16进制数据帧是固定的,所以首先想到的是将16进制数据帧转换为ASCII码字符串,然后通过上述批处理代码发送字符串。
      尝试的结果让人很沮丧,因为16进制书0x81和0x00不在ASCII码表中,0x55 0x55 0x55 0x55 0x55 0x55 0x80 0x81 0x00 0x00 0x00转换的结果为UUUUUU€?,通过以上代码发送出去后收到的是0x55 0x55 0x55 0x55 0x55 0x55 0x80,反复折腾,最终得出一个结论:我无法用批处理程序实现16进制数发送!
      放弃那一切幻想,下面老老实用最原始的办法,通过C语言写一个数据帧发送的控制台应用程序,然后通过批处理程序先执行串口发送程序,再执行grmon连接DSU,最终间接实现一建连接DSU。
      使用熟悉的C就容易多了,下面直接上代码:
#include "stdafx.h"
#include "stdio.h"
#include<iostream>
#include<windows.h>
#include<time.h>
#include<stdlib.h>
using namespace std;

int com_tx(char *comport)
{
            int i = 0;
      HANDLE hcom;      
      hcom = CreateFile((comport), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);               

      if (hcom == INVALID_HANDLE_VALUE)
      {
            fprintf(stderr, "串口打开失败\n");
            exit(0);
      }
                else
                {
                        printf("串口打开成功\n");
                }
      SetupComm(hcom, 100, 100);
      DCB dcb;
      GetCommState(hcom, &dcb);
      dcb.BaudRate = 115200;
      dcb.ByteSize = 8;
      dcb.Parity = NOPARITY;
      dcb.StopBits = 1;
      SetCommState(hcom, &dcb);
                if (hcom)                // check if the port is opened
                {
                        PurgeComm(hcom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
                }
                char read = {0,0,0,0};
                DWORD dwReadLen = 0;
      
      char data[] = {0x55,0x55,0x55,0x55,0x55,0x55,0x80,0x81,0x00,0x00,0x00};
                DWORD dwWriteLen = 0;
                DWORD dwErrorFlags;
                COMSTAT ComStat;
                ClearCommError(hcom,&dwErrorFlags,&ComStat);
                // Clear buffer
                PurgeComm(hcom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
                Sleep(1000);
      if (!WriteFile(hcom, data, 11, &dwWriteLen, NULL))
      {
          fprintf(stderr, "发送失败\n");
      }
                else
                {
                        printf("·发送成功\n");
                }
                Sleep(500);
                dwReadLen = 0;
                ReadFile(hcom, read, 4, &dwReadLen, NULL);
                for(i=0;i<dwReadLen;i++)
                {
                        printf("%02X ",0xFF & read);
                }
                printf("\n");

      return 0;   
}


int main(int argc, char* argv[])
{
      char *com;

if(argc==2)
          {
                  com = argv;
          }
else
          {
                  printf("miss com options format\n");
                  exit(0);
          }
com_tx(com);

      return 0;
}
      最终写一段批处理程序,并保存为.bat格式:
cd /d %~dp0
com com2
echo batch cmd.bat | grmon -leon2 -ni -uart com2
      双击.bat文件,cd /d %~dp0进入.bat所在目录,com com2向com2发送数据帧,echo batch cmd.bat | grmon -leon2 -ni -uart com2通过com2连接DSU,一键连接DSU终于完整实现。
      由于采用C语言实现,串口发送代码有点长,哪位大神知道如何使用批处理程序实现16进制数串口发送还请回帖告诉我啊!
页: [1]
查看完整版本: Windows下如何不通过串口调试助手进行串口发送