如何在批处理脚本中从COM端口读取多行数据到变量?
解决批处理脚本捕获Bus Pirate串口返回数据的问题
嘿,我明白你现在的困扰——用批处理发送命令没问题,但读取串口数据时直接卡住了对吧?这其实是因为普通的文件读取命令(比如type)没法正确处理串口这种持续数据流,它会一直等新数据进来,直到端口关闭,自然就卡主了。下面我给你两种可行的解决方案,帮你把Bus Pirate返回的READ:值提取出来。
为什么你的脚本会卡主?
type %_CNum%这个命令是用来读取静态文件的,但COM端口是一个持续开放的数据流,没有“文件结束”的标记,所以type会一直等待,永远不会停止,这就是脚本卡在那里的原因。我们需要用能主动终止捕获的方法,或者用更专业的串口控制方式。
方案1:用PowerShell原生串口类(无需第三方工具)
PowerShell的.NET SerialPort类可以精准控制串口的读取时长,完美解决无限等待的问题。我修改了你的脚本,加入了数据提取逻辑:
@Echo Off setlocal EnableExtensions EnableDelayedExpansion set "_CNum=COM3" set "count=0" set "read_value=" REM 配置串口参数 mode %_CNum% BAUD=115200 PARITY=n DATA=8 STOP=1 REM 发送编程RAM的命令 >\\.\%_CNum% echo [0xA0 0x0B 0x5F 0xEB] timeout /t 1 /nobreak >nul REM 给Bus Pirate留1秒处理时间,可根据设备调整 REM 选择要读取的RAM地址 >\\.\%_CNum% echo [0xA0 0x0B] timeout /t 1 /nobreak >nul REM 请求读取2字节数据 >\\.\%_CNum% echo [0xA1 rr] timeout /t 2 /nobreak >nul REM 等待数据返回,时间可以适当延长 REM 用PowerShell捕获串口数据,限制2秒读取时长 for /f "tokens=*" %%a in ('powershell -Command "$port = new-Object System.IO.Ports.SerialPort('%_CNum%',115200,None,8,One); $port.Open(); $start = Get-Date; while ((Get-Date) - $start -lt [timespan]::FromSeconds(2)) { if ($port.BytesToRead -gt 0) { Write-Output $port.ReadLine() } }; $port.Close()"') do ( echo 收到行:%%a if "%%a" neq "" ( set "_COMData!count!=%%a" set /a count+=1 REM 自动提取READ:后面的十六进制值 echo %%a | findstr /i "READ:" >nul && ( for /f "tokens=2 delims= " %%b in ("%%a") do ( set "read_value=%%b" echo 提取到读取值:!read_value! ) ) ) ) REM 输出所有捕获到的行 echo. echo 所有捕获到的串口数据: for /l %%i in (0,1,!count!-1) do ( echo 行%%i:!_COMData%%i! ) if defined read_value ( echo. echo 最终提取的读取值:!read_value! ) else ( echo. echo 未捕获到READ数据,请检查命令或等待时间 ) pause
这个方案的优点:
- 完全用Windows原生工具,不需要额外安装软件
- 精准控制读取时长,不会无限等待
- 自动过滤并提取你需要的
READ:后面的十六进制值 - 可以看到所有返回的串口数据,方便调试
方案2:用第三方串口捕获工具(更简单的调试方式)
如果你觉得PowerShell的写法有点复杂,可以用轻量的串口工具比如comcat(一款免费的串口捕获工具),把串口数据输出到文件,再读取文件内容:
@Echo Off setlocal EnableExtensions EnableDelayedExpansion set "_CNum=COM3" set "output_file=serial_log.txt" set "count=0" set "read_value=" REM 删除旧的日志文件 if exist "%output_file%" del "%output_file%" REM 启动comcat,后台捕获串口数据到文件 start /min comcat %_CNum% 115200 > "%output_file%" REM 发送命令序列 >\\.\%_CNum% echo [0xA0 0x0B 0x5F 0xEB] timeout /t 1 /nobreak >nul >\\.\%_CNum% echo [0xA0 0x0B] timeout /t 1 /nobreak >nul >\\.\%_CNum% echo [0xA1 rr] timeout /t 2 /nobreak >nul REM 关闭comcat进程 taskkill /im comcat.exe /f >nul 2>&1 REM 读取日志文件内容 for /f "tokens=* delims=" %%a in (%output_file%) do ( set "_COMData!count!=%%a" set /a count+=1 echo %%a | findstr /i "READ:" >nul && ( for /f "tokens=2 delims= " %%b in ("%%a") do ( set "read_value=%%b" ) ) ) REM 输出结果 echo. echo 捕获到的串口数据: for /l %%i in (0,1,!count!-1) do ( echo !_COMData%%i! ) if defined read_value ( echo. echo 提取的读取值:!read_value! ) else ( echo. echo 未找到READ数据,请检查命令或工具是否正常工作 ) pause
注意事项:
- 下载
comcat后要放到脚本同目录,或者加入系统PATH - 有些杀毒软件可能会误报,添加信任即可
几个关键提示
- 调整等待时间:不同设备的响应速度不同,如果没捕获到数据,把
timeout的时间延长一点(比如改成3秒) - 清空串口缓存:如果之前的串口数据残留干扰结果,可以在发送命令前加一行
echo. > \\.\%_CNum%清空缓存 - 管理员权限:运行脚本时最好右键选择“以管理员身份运行”,避免串口访问权限问题
内容的提问来源于stack exchange,提问作者NFM
相关产品推荐
相关产品推荐

