用 Uno 当烧录器给 atmega328 烧录 bootloader
用 Uno 当烧录器给 atmega328 烧录 bootloader
- date: 2023-8-10
https://backmountaindevil.github.io/#/hackaday/arduino/isp
引脚接线
把两个板子的 11(MOSI)、12(MISO)、13(SCK)、5V、GND 两两相连,还要把 Uno(烧录器)的 10 接到atmega328(待烧录的对象)的 RES(RESET) 上。这六根线必接,程序里还有三个 LED 状态指示,可以不接
接线,然后将示例中的 ArduinoISP 程序按照正常操作验证上传到 Uno 上,这一步通常没啥问题。其实这一步是把 ino 程序编译后缀为 hex 的固件,然后把固件刷上去(打开详细输出就能看到这些信息)
error
avrdude error: cannot find USBtiny device (0x2341/0x49)
avrdude error: unable to open programmer arduinoisp on port usb
烧录引导程序出错。
菜单栏:文件 - 首选项,显示详细输出,把上传给勾选上
再尝试一次获取详细信息,工具-编程器 选 Arduino as ISP
(默认是 AVRISP),然后 工具-烧录引导程序
Arduino:1.8.19 (Linux), 开发板:"Arduino Uno"//bin/avrdude -C//etc/avrdude.conf -v -patmega328p -carduinoisp -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m avrdude: Version 7.2Copyright the AVRDUDE authors;see https://github.com/avrdudes/avrdude/blob/main/AUTHORSSystem wide configuration file is /etc/avrdude.confUser configuration file is /home/mifen/.avrdudercUser configuration file does not exist or is not a regular file, skippingUsing Port : usbUsing Programmer : arduinoisp
avrdude usbtiny_open() error: cannot find USBtiny device (0x2341/0x49)
avrdude main() error: unable to open programmer arduinoisp on port usbavrdude done. Thank you.烧录引导程序出错。
上面的 Port 感觉就不对,按理说是类似这样的 /dev/ttyUSB0
,通过编译上传的详细信息可以看到 avrdude 在上传时也是识别到了对应端口,怎么到这一步骤就不行了呢。然后查了一下网上的,要么更新程序,要么用别的软件来搞,有准备尝试配置文件的方式,最后发现是编程器选错了,要选 Arduino as ISP
而不是 ArduinoISP
,成功烧录的详细信息如下
成功烧录详情
//bin/avrdude -C//etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m avrdude: Version 7.2Copyright the AVRDUDE authors;see https://github.com/avrdudes/avrdude/blob/main/AUTHORSSystem wide configuration file is /etc/avrdude.confUser configuration file is /home/mifen/.avrdudercUser configuration file does not exist or is not a regular file, skippingUsing Port : /dev/ttyUSB0Using Programmer : stk500v1Overriding Baud Rate : 19200AVR Part : ATmega328PChip Erase delay : 9000 usPAGEL : PD7BS2 : PC2RESET disposition : possible i/oRETRY pulse : SCKSerial program mode : yesParallel program mode : yesTimeout : 200StabDelay : 100CmdexeDelay : 25SyncLoops : 32PollIndex : 3PollValue : 0x53Memory Detail :Block Poll Page PolledMemory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------eeprom 65 20 4 0 no 1024 4 0 3600 3600 0x00 0x00flash 65 10 128 0 yes 32768 128 256 4500 4500 0x00 0x00lfuse 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00hfuse 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00efuse 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00lock 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00signature 0 0 0 0 no 3 1 0 0 0 0x00 0x00calibration 0 0 0 0 no 1 1 0 0 0 0x00 0x00Programmer Type : STK500Description : Atmel STK500 version 1.x firmwareHardware Version: 2Firmware Version: 1.18Topcard : UnknownVtarget : 0.0 VVaref : 0.0 VOscillator : OffSCK period : 0.1 us
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e950f (probably m328p)
avrdude: erasing chipavrdude: processing -U lock:w:0x3F:m
avrdude: reading input file 0x3F for lockwith 1 byte in 1 section within [0, 0]
avrdude: writing 1 byte lock ...
avrdude: 1 byte of lock written
avrdude: verifying lock memory against 0x3F
avrdude avr_verify() warning: ignoring mismatch in unused bits of lock(device 0xff != input 0x3f); to prevent this warning setunused bits to 1 when writing (double check with datasheet)
avrdude: 1 byte of lock verifiedavrdude: processing -U efuse:w:0xFD:m
avrdude: reading input file 0xFD for efusewith 1 byte in 1 section within [0, 0]
avrdude: writing 1 byte efuse ...
avrdude: 1 byte of efuse written
avrdude: verifying efuse memory against 0xFD
avrdude: 1 byte of efuse verifiedavrdude: processing -U hfuse:w:0xDE:m
avrdude: reading input file 0xDE for hfusewith 1 byte in 1 section within [0, 0]
avrdude: writing 1 byte hfuse ...
avrdude: 1 byte of hfuse written
avrdude: verifying hfuse memory against 0xDE
avrdude: 1 byte of hfuse verifiedavrdude: processing -U lfuse:w:0xFF:m
avrdude: reading input file 0xFF for lfusewith 1 byte in 1 section within [0, 0]
avrdude: writing 1 byte lfuse ...
avrdude: 1 byte of lfuse written
avrdude: verifying lfuse memory against 0xFF
avrdude: 1 byte of lfuse verifiedavrdude done. Thank you.//bin/avrdude -C//etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -Uflash:w:/usr/share/arduino/hardware/archlinux-arduino/avr/bootloaders/optiboot/optiboot_atmega328.hex:i -Ulock:w:0x0F:m avrdude: Version 7.2Copyright the AVRDUDE authors;see https://github.com/avrdudes/avrdude/blob/main/AUTHORSSystem wide configuration file is /etc/avrdude.confUser configuration file is /home/mifen/.avrdudercUser configuration file does not exist or is not a regular file, skippingUsing Port : /dev/ttyUSB0Using Programmer : stk500v1Overriding Baud Rate : 19200AVR Part : ATmega328PChip Erase delay : 9000 usPAGEL : PD7BS2 : PC2RESET disposition : possible i/oRETRY pulse : SCKSerial program mode : yesParallel program mode : yesTimeout : 200StabDelay : 100CmdexeDelay : 25SyncLoops : 32PollIndex : 3PollValue : 0x53Memory Detail :Block Poll Page PolledMemory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------eeprom 65 20 4 0 no 1024 4 0 3600 3600 0x00 0x00flash 65 10 128 0 yes 32768 128 256 4500 4500 0x00 0x00lfuse 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00hfuse 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00efuse 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00lock 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00signature 0 0 0 0 no 3 1 0 0 0 0x00 0x00calibration 0 0 0 0 no 1 1 0 0 0 0x00 0x00Programmer Type : STK500Description : Atmel STK500 version 1.x firmwareHardware Version: 2Firmware Version: 1.18Topcard : UnknownVtarget : 0.0 VVaref : 0.0 VOscillator : OffSCK period : 0.1 us
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e950f (probably m328p)
avrdude: Note: flash memory has been specified, an erase cycle will be performed.To disable this feature, specify the -D option.
avrdude: erasing chipavrdude: processing -U flash:w:/usr/share/arduino/hardware/archlinux-arduino/avr/bootloaders/optiboot/optiboot_atmega328.hex:i
avrdude: reading input file /usr/share/arduino/hardware/archlinux-arduino/avr/bootloaders/optiboot/optiboot_atmega328.hex for flashwith 502 bytes in 2 sections within [0x7e00, 0x7fff]using 4 pages and 10 pad bytes
avrdude: writing 502 bytes flash ...
Writing | ################################################## | 100% 0.08s
avrdude: 502 bytes of flash written
avrdude: verifying flash memory against /usr/share/arduino/hardware/archlinux-arduino/avr/bootloaders/optiboot/optiboot_atmega328.hex
Reading | ################################################## | 100% 0.00s
avrdude: 502 bytes of flash verifiedavrdude: processing -U lock:w:0x0F:m
avrdude: reading input file 0x0F for lockwith 1 byte in 1 section within [0, 0]
avrdude: writing 1 byte lock ...
avrdude: 1 byte of lock written
avrdude: verifying lock memory against 0x0F
avrdude avr_verify() warning: ignoring mismatch in unused bits of lock(device 0xcf != input 0x0f); to prevent this warning setunused bits to 1 when writing (double check with datasheet)
avrdude: 1 byte of lock verifiedavrdude done. Thank you.
用国行(开发板信息BN显示未知、无SN)烧正规军(可以获取开发板信息如序列号)可以(上面就是),用正规军烧国行则不行,会报错如下
Arduino:1.8.19 (Linux), 开发板:"Arduino Uno"//bin/avrdude -C//etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyACM0 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m avrdude: Version 7.2Copyright the AVRDUDE authors;see https://github.com/avrdudes/avrdude/blob/main/AUTHORSSystem wide configuration file is /etc/avrdude.confUser configuration file is /home/mifen/.avrdudercUser configuration file does not exist or is not a regular file, skippingUsing Port : /dev/ttyACM0Using Programmer : stk500v1Overriding Baud Rate : 19200AVR Part : ATmega328PChip Erase delay : 9000 usPAGEL : PD7BS2 : PC2RESET disposition : possible i/oRETRY pulse : SCKSerial program mode : yesParallel program mode : yesTimeout : 200StabDelay : 100CmdexeDelay : 25SyncLoops : 32PollIndex : 3PollValue : 0x53Memory Detail :Block Poll Page PolledMemory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------eeprom 65 20 4 0 no 1024 4 0 3600 3600 0x00 0x00flash 65 10 128 0 yes 32768 128 256 4500 4500 0x00 0x00lfuse 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00hfuse 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00efuse 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00lock 0 0 0 0 no 1 1 0 4500 4500 0x00 0x00signature 0 0 0 0 no 3 1 0 0 0 0x00 0x00calibration 0 0 0 0 no 1 1 0 0 0 0x00 0x00Programmer Type : STK500Description : Atmel STK500 version 1.x firmwareHardware Version: 2Firmware Version: 1.18Topcard : UnknownVtarget : 0.0 VVaref : 0.0 VOscillator : OffSCK period : 0.1 us
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x000000 (retrying)
avrdude: device signature = 0x000000 (retrying)
avrdude: device signature = 0x000000
avrdude main() error: Yikes! Invalid device signature.
avrdude main() error: expected signature for ATmega328P is 1E 95 0FDouble check connections and try again, or use -F to overridethis check.avrdude done. Thank you.烧录引导程序出错。
根据上面的错误信息,我在终端加 -F 也不行,还是验证失败。奇怪的是,国行和正规军的差别在于串口芯片啊,Arduino as ISP 没走 ch340 国道啊,mcu 都是一样的咋就不行了?然后又对调一下(接线没动),发现出现了上面验证失败的错误,也就是说明接错线会发生这个错误。然而实际上刚才我有对调11、12看接线,没想到啊,看样子是刚才接线错了,重新拔掉接一遍就可以了。
指定引导程序
如果说要烧录指定的引导程序,如ATmega-Soldering-Station下的引导文件,那该怎么办呢?结合仓库的介绍和上面的详细信息可以知道两行指令,需要修改端口号和文件路径,在终端中运行即可
avrdude -C//etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyACM0 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m avrdude -C//etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyACM0 -b19200 -Uflash:w:/path/to/filename.hex:i -Ulock:w:0x0F:m
想刷回原版引导,用 arduino 运行烧录引导程序程序即可
参考
Arduino 烧写bootloader cheng3100 2017.02.10
[Arduino]烧写Arduino BootLoader的几种方法 李万鑫 2017-06-27:和上面接线是一样的,只是看着不一样,因为 ISP 口有几个
Arduino: [已修复] IDE 1.6.9 + ArduinoISP =“找不到 USBtiny 设备 (0x2341/0x49)”错误消息 => 使用“Arduino 作为 ISP”2016-07-12 HP-Sparks
我找到了问题的根源:程序员选择的“ArduinoISP”与“Arduino as ISP”
相关文章:
用 Uno 当烧录器给 atmega328 烧录 bootloader
用 Uno 当烧录器给 atmega328 烧录 bootloader date: 2023-8-10 https://backmountaindevil.github.io/#/hackaday/arduino/isp 引脚接线 把两个板子的 11(MOSI)、12(MISO)、13(SCK)、5V、GND 两两相连,还要把 Uno(烧录器)的 10 接到atmeg…...

spring boot策略模式实用: 告警模块为例
spring boot策略模式实用: 告警模块 0 涉及知识点 策略模式, 模板方法, 代理, 多态, 反射 1 需求概括 场景: 每隔一段时间, 会获取设备运行数据, 如通过温湿度计获取到当前环境温湿度;需求: 对获取回来的进行分析, 超过配置的阈值需要产生对应的告警 2 方案设计 告警的类…...
Camunda 7.x 系列【10】使用 Rest API 运行流程实例
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. 官方接口文档3. 本地接口文档3.1 Postman3.2 Camunda Platform Run Swagger3.3 S…...

Python-OpenCV中的图像处理-边缘检测
Python-OpenCV中的图像处理-边缘检测 边缘检测Canny算子 边缘检测Canny算子 Canny 边缘检测是一种非常流行的边缘检测算法,是 John F.Canny 在 1986 年提出的。它是一个有很多步构成的算法:噪声去除、计算图像梯度、非极大值抑制、滞后阀值等。 Canny(i…...

一文了解Java序列化和反序列化:对象的存储与传输
一文了解Java序列化和反序列化:对象的存储与传输 作者:Stevedash 发布时间:2023年8月9日 21点30分 前言 Java序列化是一项强大而重要的技术,它允许我们将对象转换为字节流,以便在存储、传输和重建时使用。在本文中&…...
react-codemirror2 编辑器需点击一下或者延时才显示数据的问题
现象: <Codemirror/>组件的数据已经赋上值的情况下,初始状态不渲染数据,需要点击编辑框获取焦点后才展示,或者延迟了几秒才显示出来。 原因: 指定了一些依赖的版本,可能不兼容了一些功能,…...

火山引擎联合Forrester发布《中国云原生安全市场现状及趋势白皮书》,赋能企业构建云原生安全体系
国际权威研究咨询公司Forrester 预测,2023年全球超过40%的企业将会采用云原生优先战略。然而,云原生在改变企业上云及构建新一代基础设施的同时,也带来了一系列的新问题,针对涵盖云原生应用、容器、镜像、编排系统平台以及基础设施…...

需要数电发票接口的,先熟悉下数电发票基本常识
最近有一些技术小伙伴来咨询数电发票接口的时候,对数电发票的一些常识不太了解, 导致沟通起来比较困难。比较典型的这三个问题: 一、开具数电票时,如何设置身份认证频次? 请公司的法定代表人或财务负责人登录江苏省电…...
node-sass是什么
一、Sass(Syntactically Awesome Style Sheets) 是一种CSS预处理器,它扩展了CSS的功能并提供了更强大的样式表语言。Sass允许开发人员使用变量、嵌套规则、混合(Mixins)、继承等高级功能来编写更简洁、可维护的样式代…...

C语言指针之 进阶
前言 今天来较为深入的介绍一下指针,希望大家能有所收获~ 那么,先进行一些简单的基础知识复习吧。 字符指针 格式:char * 补充: 表达式“abcdef”的值是首字符a的地址 所以当像下面这么使用时,它的含…...
C++单例模式
文章目录 1、什么是单例2、一个好的单例应该具备的条件3、懒汉模式与饿汉模式4、单例实现:线程安全、内存安全的懒汉式单例(基于C11的智能指针和互斥锁) 1、什么是单例 单例 Singleton 是设计模式的一种,其特点是只提供唯一一个类…...
C++ 析构函数
析构函数 析构函数于构造函数相对应,构造函数是对象创建的时候自动调用的,而析构函数就是对象在销毁的时候自动调用的 特点: 1)构造函数可以有多个来构成重载,但析构函数只能有一个,不能构成重载 2&…...
CSS——字体选择
在网页设计和开发中,字体选择是一个非常重要的因素。字体不仅仅是文字的表现形式,它们还能够传达出一种特定的情感和风格。在CSS中,我们可以通过使用字体代码来定义网页中使用的字体。 CSS提供了一种简单而灵活的方式来设置字体。通过使用fo…...
SpringBoot自动装配及run方法原理探究
自动装配 1、pom.xml spring-boot-dependencies:核心依赖在父工程中!我们在写或者引入一些SpringBoot依赖的时候,不需要指定版本,就因为有这些版本仓库 1.1 其中它主要是依赖一个父工程,作用是管理项目的资源过滤及…...

Mybatis实现JsonObject对象与JSON之间交互
项目中使用PostGresql数据库进行数据存储,表中某字段为Json类型,用于存储Json格式数据。PG数据库能够直接存储Json算是一大特色,很多特定情境下使用直接存储Json字段数据能够大量节省开发时间,提高后台数据查询和转换效率。 1、基…...

spring boot 集成 jetcache【基础篇:@Cached、@CreateCache、@CacheRefresh】
手打不易,如果转摘,请注明出处! 注明原文:https://zhangxiaofan.blog.csdn.net/article/details/129832925 目录 前言 版本 配置通用说明 项目结构 代码 启动类 实体类 基础使用——增删改查(Cached、CacheInv…...
个人对前后端分离的一些看法
内容简介:前端开发过程中能完全不依赖后端的才是真正的前后端分离指的是工作过程中,前端的的代码中往往会掺杂一些后端的逻辑。后端返回了一个json对象 前端开发过程中能完全不依赖后端的才是真正的前后端分离 指的是工作过程中,前端的的代码…...
TailWindCss 在Hbuilderx中使用
基于这个插件 weapp-tailwindcss 地址 本次说明基于HbuilderX 创建的项目非CLI 安装步骤按照文档走,先安装上几个依赖。然后是几个配置文件 tailwind-input.css tailwind的css文件用来引入到app.vue /* #ifdef H5 */ tailwind base; /* 如果是小程序的话&#x…...

Unity导入图片时,通过设置属性快速实现资源的压缩
是在学习tilemap绘制世界地图的时候发现的这个功能。 之前一直只是粗略的知道这部分是对应图片资源的压缩的。比如Compression是指的压缩质量,想要完全不压缩就设置None,会导致图片资源会大一些。 在我的例子工程中,其他图片资源的尺寸都是6…...

AlmaLinux 9 安装 Go 1.20
AlmaLinux 9 安装 Golang 1.20 1. 下载 go 安装包2. 安装 go3. 配置环境变量4. 确认 go 版本 1. 下载 go 安装包 访问 https://go.dev/dl/,下载你想安装的版本,比如 go1.20.7.linux-amd64.tar.gz, 2. 安装 go (可选)删除旧版本,…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...