当前位置: 首页 > article >正文

I2C设备扫描器:嵌入式系统总线拓扑发现与地址诊断工具

1. I2C设备扫描器嵌入式系统中总线拓扑发现的核心工具I²CInter-Integrated Circuit总线因其仅需两根信号线SCL时钟线与SDA数据线、支持多主多从架构、内置仲裁与应答机制等特性成为嵌入式系统中传感器、EEPROM、RTC、显示驱动等外设连接的首选方案。然而在实际硬件调试与系统集成阶段工程师常面临一个基础却关键的问题“我接上去的设备到底有没有被总线识别”——这并非理论问题而是直接影响固件开发进度的工程瓶颈。I2C_Scanner 正是为解决这一痛点而生的底层诊断工具。它不依赖任何特定设备驱动仅通过标准I²C协议的地址探测机制即可在毫秒级时间内完成对整个总线物理拓扑的枚举与报告。其价值远超“一个Arduino示例”本质上是一个可移植、可裁剪、可集成的嵌入式总线健康检查模块。1.1 工程定位与核心设计哲学I2C_Scanner 的设计严格遵循嵌入式底层开发的黄金法则最小依赖、最大可见性、零侵入性。它不初始化任何外设寄存器不配置GPIO复用功能这些由上层HAL/LL库或裸机代码完成仅利用I²C主机控制器的最基础能力——向0x00至0x7F7位地址空间范围内的每个地址发送START地址字节READ位并监听从机是否返回ACK应答。这种“试探性握手”方式完全符合I²C规范NXP UM10204且对总线上所有符合标准的从机设备均有效无论其内部逻辑如何复杂。其输出结果地址列表直接映射到Wire.begin(address)等API所需的参数消除了因数据手册地址格式7位/8位/十进制/十六进制混淆导致的常见配置错误。在量产测试、产线烧录、现场故障排查等场景中该工具能将“总线无响应”的模糊问题精准定位为“地址错误”、“上拉电阻失效”、“设备未供电”或“硬件短路”等具体原因。1.2 硬件兼容性与平台移植要点尽管原始实现基于Arduino框架但其核心算法具有极强的跨平台适应性。在STM32平台下可无缝对接HAL库的HAL_I2C_IsDeviceReady()函数在ESP32平台下可调用i2c_master_probe()在裸机环境下则直接操作I²C控制器的CR1/CR2/SR1/SR2寄存器。关键移植点在于时序控制必须确保SCL低电平时间≥4.7μs高电平时间≥4.0μs标准模式此要求由硬件I²C外设自动满足软件模拟I²C需精确计时。地址范围严格限定为0x00–0x7F128个7位地址。0x00为通用呼叫地址0x01–0x07及0x78–0x7F为保留地址实际有效设备地址通常为0x08–0x77。扫描时需跳过0x00及保留段以避免误报。总线恢复若扫描过程中遭遇总线锁死SCL被从机拉低需执行9个时钟脉冲强制释放此逻辑需在底层驱动中实现。下表列出了主流MCU平台对应的移植接口映射MCU平台推荐底层接口关键参数说明典型调用示例STM32 (HAL)HAL_I2C_IsDeviceReady(hi2c1, (uint16_t)(addr1), 2, 100)addr1: 转换为8位地址格式2: 重试次数100: 超时msif(HAL_I2C_IsDeviceReady(hi2c1, 0x3C1, 2, 100) HAL_OK)ESP32 (ESP-IDF)i2c_master_probe(I2C_NUM_0, addr, 100)addr: 直接传入7位地址100: 超时msif(i2c_master_probe(I2C_NUM_0, 0x3C, 100) ESP_OK)NXP Kinetis (KSDK)I2C_MasterCheckForAddressMatch(I2C0, addr, kI2C_Write)kI2C_Write: 写方向探测if(I2C_MasterCheckForAddressMatch(I2C0, 0x3C, kI2C_Write))注所有平台均需预先完成I²C外设初始化时钟使能、GPIO配置、上拉电阻接入及Wire.begin()或等效初始化。扫描器本身不承担硬件初始化职责。2. 核心工作原理与协议层深度解析I2C_Scanner 的行为本质是对I²C物理层与协议层的一次系统性压力测试。其工作流程严格遵循I²C总线规范每一环节均蕴含关键工程考量。2.1 地址探测的原子操作分解一次完整的地址探测包含以下不可分割的步骤以7位地址0x3C为例START条件生成主控器将SDA线从高电平拉低同时SCL保持高电平。此跳变标志通信开始。地址字节发送主控器在SCL高电平时稳定SDA随后在SCL下降沿采样。地址字节格式为[7:1] 0x3C,[0] 0 (WRITE)→ 实际发送0x780x3C 1 | 0。ACK/NACK检测主控器释放SDA等待从机在第9个SCL周期将SDA拉低ACK或保持高电平NACK。这是判断设备存在的唯一可靠依据。STOP条件生成主控器在SCL高电平时将SDA从低电平拉高标志本次探测结束。此过程耗时约200–500μs取决于时钟频率全地址空间扫描128次理论最短耗时25.6ms标准模式100kHz。实际工程中需加入微秒级延时如delayMicroseconds(100)以确保信号建立时间故总耗时约150–300ms。2.2 为何必须使用7位地址数据手册的陷阱与真相原始文档强调“报告7位地址”此设计直指行业痛点。I²C规范明确定义地址为7位第8位为读写方向位R/W。但大量数据手册与示例代码存在表述混乱手册陷阱某OLED驱动芯片手册标注“Slave Address: 0x78”实为8位地址0x3C 1 | 0正确7位地址应为0x3C。代码陷阱部分Arduino示例写为Wire.begin(0x78)此为错误用法Wire.begin()仅接受7位地址传入0x78会导致地址错位为0xF0。I2C_Scanner 输出0x3C而非0x78强制开发者建立正确的地址认知模型。在代码中所有设备初始化必须统一为// ✅ 正确7位地址直接使用 Wire.begin(0x3C); // OLED Wire.begin(0x68); // MPU6050 Wire.begin(0x50); // AT24C02 EEPROM // ❌ 错误传入8位地址 Wire.begin(0x78); // 将导致实际寻址0xF0设备无法响应2.3 多路复用器MUX支持的硬件协同机制原始文档提及“支持I2C多路复用器”这是该工具面向复杂系统的高级特性。典型I²C MUX如TCA9548A本身是一个8通道开关其自身地址固定如0x70需先向其写入通道号再进行后续通信。I2C_Scanner的MUX支持并非自动识别而是提供结构化扫描框架主通道扫描首先扫描MUX自身地址0x70确认MUX在线。通道选择向MUX写入0x01选择通道1此时总线物理路径切换至通道1。子通道扫描在通道1上执行完整地址扫描获取挂载设备列表。循环遍历重复步骤2-3遍历所有8个通道0x00–0x07。此流程要求开发者在扫描器代码中嵌入MUX控制逻辑。典型实现如下基于Arduino Wire库#include Wire.h #define MUX_ADDR 0x70 void scanMUXChannel(uint8_t channel) { // Step 1: Select MUX channel Wire.beginTransmission(MUX_ADDR); Wire.write(1 channel); // Enable only this channel Wire.endTransmission(); // Step 2: Scan devices on this channel Serial.print(Channel ); Serial.print(channel); Serial.println(:); for (uint8_t addr 1; addr 127; addr) { if (Wire.beginTransmission(addr) 0) { // ACK received Serial.print(0x); Serial.print(addr, HEX); Serial.print( ); } } Serial.println(); } void setup() { Wire.begin(); Serial.begin(115200); // Scan all 8 channels of TCA9548A for (uint8_t ch 0; ch 8; ch) { scanMUXChannel(ch); } }该机制使单个MCU引脚可管理多达8×1271016个I²C设备彻底突破总线地址资源限制。3. API接口详解与嵌入式集成实践I2C_Scanner 的核心价值在于其API的简洁性与可扩展性。原始Arduino实现仅暴露一个scan()函数但在工业级应用中需将其封装为可配置的模块。3.1 标准化API函数签名与参数语义下表定义了推荐的标准化API接口适用于C/C嵌入式环境函数名原型功能说明参数详解i2c_scan_busuint8_t i2c_scan_bus(I2C_HandleTypeDef *hi2c, uint8_t *addr_list, uint8_t max_count)扫描指定I²C总线返回发现设备数量hi2c: HAL句柄addr_list: 存储7位地址的缓冲区max_count: 缓冲区最大容量i2c_scan_with_timeoutuint8_t i2c_scan_with_timeout(I2C_HandleTypeDef *hi2c, uint8_t *addr_list, uint8_t max_count, uint32_t timeout_ms)增强版扫描支持自定义超时timeout_ms: 每次IsDeviceReady调用的超时值msi2c_scan_muxvoid i2c_scan_mux(I2C_HandleTypeDef *hi2c, uint8_t mux_addr, uint8_t *addr_list, uint8_t *channel_counts)扫描带MUX的总线mux_addr: MUX设备地址channel_counts: 各通道设备数数组长度83.2 FreeRTOS环境下的安全集成方案在实时操作系统中I2C扫描需考虑任务调度与资源互斥。直接在任务中调用扫描函数可能导致总线占用过长影响其他高优先级任务。推荐采用以下两种模式模式一低优先级守护任务推荐创建独立任务优先级设为最低如tskIDLE_PRIORITY使用vTaskDelay()分时扫描避免阻塞void vI2CScanTask(void *pvParameters) { uint8_t addr_buffer[32]; TickType_t xLastWakeTime xTaskGetTickCount(); for(;;) { // 每5秒执行一次扫描 vTaskDelayUntil(xLastWakeTime, pdMS_TO_TICKS(5000)); // 获取I2C总线互斥信号量 if(xSemaphoreTake(xI2CSemaphore, portMAX_DELAY) pdTRUE) { uint8_t count i2c_scan_bus(hi2c1, addr_buffer, 32); // 处理结果更新全局状态、触发事件组等 xSemaphoreGive(xI2CSemaphore); } } }模式二中断触发式扫描利用GPIO外部中断如按键按下触发扫描结果通过队列发送至处理任务// 中断服务程序 void EXTI0_IRQHandler(void) { BaseType_t xHigherPriorityTaskWoken pdFALSE; uint8_t scan_cmd 0x01; xQueueSendFromISR(xScanQueue, scan_cmd, xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } // 扫描任务 void vScanHandlerTask(void *pvParameters) { uint8_t cmd; for(;;) { if(xQueueReceive(xScanQueue, cmd, portMAX_DELAY) pdTRUE) { uint8_t addrs[16]; uint8_t count i2c_scan_bus(hi2c1, addrs, 16); // 通过串口或LCD显示结果 display_i2c_results(addrs, count); } } }3.3 与HAL库深度协同的关键配置在STM32 HAL环境中HAL_I2C_IsDeviceReady()的可靠性高度依赖以下配置Timeout参数必须大于25ms标准模式下128次探测的理论最大耗时。建议设为100。DevAddress参数必须左移1位addr 1因HAL函数期望8位地址格式。Attempts参数设为2可过滤偶发噪声干扰避免误判。典型HAL调用封装uint8_t i2c_scan_bus(I2C_HandleTypeDef *hi2c, uint8_t *addr_list, uint8_t max_count) { uint8_t count 0; HAL_StatusTypeDef status; for (uint8_t addr 1; addr 127; addr) { // Skip reserved addresses per I2C spec if ((addr 0x00 addr 0x07) || (addr 0x78 addr 0x7F)) { continue; } status HAL_I2C_IsDeviceReady(hi2c, (uint16_t)(addr 1), 2, 100); if (status HAL_OK) { if (count max_count) { addr_list[count] addr; } } } return count; }4. 实战调试案例与典型问题诊断I2C_Scanner 在真实项目中暴露出的问题往往指向更深层的硬件或固件缺陷。以下是三个典型场景的深度分析。4.1 案例一扫描结果为空但设备功能正常现象OLED屏幕显示正常但扫描器报告“no devices found”。根因分析设备在初始化后进入低功耗模式关闭了I²C应答电路。例如SSD1306驱动芯片在DISPLAYOFF指令后虽仍可接收命令但不再响应地址探测。解决方案在扫描前强制唤醒设备向已知地址发送0xAFDISPLAYON指令。或修改扫描逻辑在探测失败后尝试发送通用唤醒序列如连续9个SCL脉冲。4.2 案例二扫描到异常地址如0x00, 0x7F现象扫描器报告0x00或0x7F但该地址无对应设备。根因分析总线存在严重电气问题0x00SDA线被意外拉低如焊接短路、GPIO配置错误为开漏输出但未接上拉。0x7FSCL线被意外拉低或上拉电阻阻值过大10kΩ导致信号上升沿缓慢被误判为ACK。验证方法用示波器观测SCL/SDA波形测量上拉电阻实际阻值。4.3 案例三多设备共存时部分地址丢失现象单独扫描各设备均正常但全部接入后仅能发现其中2个。根因分析总线电容超限。I²C规范规定总线电容≤400pF。每根PCB走线约10pF/cm每个设备引脚约8pF。10cm走线5个设备已达140pF若使用大容量滤波电容如100nF则瞬间超限。解决方案减少走线长度使用星型拓扑。降低上拉电阻阻值如从4.7kΩ降至2.2kΩ但需计算功耗P V²/R。在关键设备端增加局部上拉如靠近OLED的1kΩ。5. 高级应用构建自动化产线测试系统I2C_Scanner 可作为智能硬件产线测试的核心组件。某工业传感器模组产线将其集成于测试治具实现全自动良率统计# Python测试脚本通过USB转串口与MCU通信 import serial import time def run_production_test(): ser serial.Serial(COM3, 115200) time.sleep(1) # 发送扫描指令 ser.write(bSCAN\n) # 读取结果 result ser.readline().decode().strip() if 0x3C in result and 0x68 in result: print(PASS: OLED IMU detected) return True else: print(FAIL: Missing devices -, result) return False # 批量测试循环 for i in range(1000): if not run_production_test(): log_failure(i) trigger_rework_station()该系统将单台设备测试时间压缩至2秒良率数据实时上传MES系统成为质量追溯的关键节点。其成功关键在于I2C_Scanner输出的确定性、可解析性、零歧义性——这正是优秀嵌入式底层工具的本质特征。

相关文章:

I2C设备扫描器:嵌入式系统总线拓扑发现与地址诊断工具

1. I2C设备扫描器:嵌入式系统中总线拓扑发现的核心工具IC(Inter-Integrated Circuit)总线因其仅需两根信号线(SCL时钟线与SDA数据线)、支持多主多从架构、内置仲裁与应答机制等特性,成为嵌入式系统中传感器…...

电路接口技术解析:从TTL到无线通信的演进

1. 电路接口概述:信号传输的关键桥梁在嵌入式系统和电子电路设计中,接口技术就像城市之间的高速公路系统。当不同模块需要通信时,就像不同方言的人群需要找到共同语言。我曾参与过一个工业控制器项目,CPU与传感器间的通信故障导致…...

STM32驱动X-NUCLEO-IHM02A1实现工业级步进电机控制

1. X-NUCLEO-IHM02A1 驱动开发深度解析:面向工业级步进电机控制的 STM32 底层实现 X-NUCLEO-IHM02A1 是意法半导体(STMicroelectronics)推出的高性能双通道步进电机驱动扩展板,专为 STM32 Nucleo 开发平台设计。该板基于 STSPIN22…...

Bugtton:ATmega328P专用超低开销按钮消抖库

1. 项目概述Bugtton 是一款专为 ATmega328P 微控制器深度优化的轻量级按钮消抖库,其设计哲学直指嵌入式系统中一个被长期忽视却至关重要的性能瓶颈:空闲状态下的 CPU 周期开销。在传统 Arduino 风格的按钮处理方案中,digitalRead()函数因其通…...

OpenClaw任务编排:Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF处理依赖型工作流

OpenClaw任务编排:Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF处理依赖型工作流 1. 为什么需要任务编排 去年夏天,我接手了一个数据分析项目,需要定期从十几个网站抓取数据,清洗后生成分析报告,再邮件发送给团…...

告别纸上谈兵:用STM32和FreeRTOS动手复现NCRE嵌入式考试里的经典案例

告别纸上谈兵:用STM32和FreeRTOS动手复现NCRE嵌入式考试里的经典案例 当你在NCRE三级嵌入式考试的题库里反复刷到"任务调度优先级"或"I2C时序配置"这类概念时,是否觉得这些知识点就像漂浮在空中的理论碎片?作为经历过这个…...

他没有打断我,没有说“小孩子懂什么” ,30岁这年,我不仅拿到了父亲的认可,更拿到了他毫无保留的信任

30岁这年,我和我爸 今天和我爸坐在阳台的小茶桌前,泡了他藏了快十年的普洱,烟缸里攒了四根烟蒂,聊了整整两个小时。 散场的时候我站在窗边看他下楼开车,突然反应过来——我们今天这场对话,从头到尾没有一句“你要听话”,没有一句“钱够不够花”,没有长辈居高临下的说…...

你能不能站稳脚跟,从来不是你有多厉害,而是老板刚好需要什么

你能不能站稳脚跟,从来不是你有多厉害,而是老板刚好需要什么 目录 你能不能站稳脚跟,从来不是你有多厉害,而是老板刚好需要什么 为什么老板的需求,才是你职场的核心标尺? 打工人的破局法则:别再埋头干活,学会按需创造价值 第一步:先搞清楚3个核心问题,精准锚定需求 …...

ESP32/ESP8266旋转编码器驱动库:支持加速度响应与复合按键事件

1. 项目概述Ai Esp32 Rotary Encoder是一款专为 ESP32 和 ESP8266 平台深度优化的旋转编码器驱动库,其设计目标远超基础脉冲计数——它面向嵌入式人机交互(HMI)场景,提供带加速度响应的数值选择、边界约束、步进精度控制、循环遍历…...

AI 输出 Token 优化:文言文极简模式的实践

AI 输出 Token 优化:文言文极简模式的实践在 AI 应用开发中,token 消耗直接影响成本。HagiCode 项目通过 SOUL 系统实现了"文言文极简输出模式",在不损失信息密度的前提下,将输出 token 降低约 30-50%。本文分享这套方案…...

基于MATLAB与SVM实现河道水面漂浮物的自动检测与识别

摘要:河道水面漂浮物不仅影响水环境质量,还威胁水利设施安全和水生态健康。传统人工巡检方式效率低、成本高,难以满足大范围、实时化的 监测需求。针对上述问题,本文基于 MATLAB 平台,结合支持向量机(SVM&a…...

C语言字符串操作函数实现与优化技巧

1. 字符串操作函数的重要性与实现意义在C语言开发中,字符串操作是最基础也是最频繁使用的功能之一。标准库提供的字符串函数虽然可以直接调用,但理解其底层实现原理对开发者而言至关重要。这不仅能帮助我们在出现问题时快速定位,更能提升对内…...

当绩效开始算Token:AI时代打工人的新KPI

你的公司开始算Token了吗?最近,多家大厂传出消息:绩效考核开始和Token消耗挂钩。有的部门把Token额度作为「生产力指标」,有的甚至直接影响转正晋升。AI时代,打工人的KPI正在被重新定义。 为什么算Token?公…...

第1节:如何统一多源文档格式?

RAG与Agent性能调优:1.如何统一多元文档格式? Gitee地址:https://gitee.com/agiforgagaplus/OptiRAGAgent 文章详情目录:RAG与Agent性能调优 下一节:待更新 导论 从路口着手解决问题 在RAG技术中,文档…...

Linux IO调度器详解与性能优化指南

1. Linux IO调度器概述作为一名长期从事Linux系统调优的工程师,我经常需要面对磁盘IO性能优化的问题。今天我想和大家深入探讨Linux内核中的四大IO调度算法,这些算法直接影响着系统的IO性能表现。现代计算机系统中,磁盘IO往往是性能瓶颈所在。…...

STM32单片机技术解析与应用实践

1. STM32的崛起背景与市场格局演变在2007年之前,单片机市场呈现"三足鼎立"的格局:以STC为代表的51系列8位机占据教学和工业控制领域,MSP430在低功耗应用场景表现突出,AVR和PIC则在特定细分市场各有所长。这些8位和16位单…...

Docker镜像管理全攻略:从拉取到自定义镜像的完整流程

Docker镜像管理全攻略:从拉取到自定义镜像的完整流程 容器技术正在重塑现代软件交付的范式。想象一下这样的场景:开发团队在本地构建的应用,无需任何修改就能在生产环境以完全相同的方式运行;运维人员不再需要为不同服务器的依赖冲…...

深入解析Dify中的RAG内容检索:Rerank模型与权重计算的实战对比

1. RAG内容检索的核心挑战与Rerank的价值 当你用Dify搭建一个智能问答系统时,最头疼的问题往往是:明明数据库里有正确答案,但系统总是返回一堆不相关的文档。这就像在图书馆用关键词搜索书籍,结果管理员给你搬来了整个书架——这时…...

深入Helmholtz原理与NFA:EDLines如何像“质检员”一样控制误检率

Helmholtz原理与NFA:EDLines如何用数学语言定义"有意义"的线段 在计算机视觉领域,直线检测看似是个基础问题,却蕴含着深刻的数学智慧。当我们观察EDLines算法时,会发现它不仅仅是一系列操作步骤的堆砌,更是一…...

OpenClaw v2026.3.31 深度解读:为什么这次更新不是“小修小补”,而是一次明显的安全收口与后台任务体系成形

🔥个人主页:杨利杰YJlio❄️个人专栏:《Sysinternals实战教程》《Windows PowerShell 实战》《WINDOWS教程》《IOS教程》《微信助手》《锤子助手》 《Python》 《Kali Linux》《那些年未解决的Windows疑难杂症》🌟 让复杂的事情更…...

从“中式英语”到地道表达:我用Notion搭建了一个动态写作原则库

从“中式英语”到地道表达:我用Notion搭建了一个动态写作原则库 第一次参加国际学术会议时,我站在海报前手足无措——不是研究内容不够扎实,而是当外国学者用"Your findings are intriguing but the methodology section lacks clarity&…...

嵌入式LCD菜单框架:基于FSM的轻量级状态管理方案

1. WSEMenu 库概述WSEMenu 是一个面向嵌入式 LCD 人机交互场景的轻量级状态管理与菜单框架,专为字符型液晶显示屏(典型规格:204 字符)设计。其核心目标并非提供图形渲染能力,而是解决嵌入式系统中普遍存在的“状态跳转…...

爬虫对抗实战 - ZLibrary 反爬机制分析与突破

一、背景介绍1. 爬虫与反爬的永恒博弈网络爬虫的核心原理是通过程序模拟 HTTP/HTTPS 请求,获取网页数据并解析提取,广泛应用于数据采集、搜索引擎索引、数据分析等场景。网站部署反爬措施的核心必要性:保护服务器资源,避免恶意爬虫…...

2026届学术党必备的降AI率平台横评

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 降低那个AIGC率的关键要点在于削弱机器生成所呈现出的模式化特性。其一,对句式结…...

构建具备 Cyclic Loop(循环反思) 与 Self-Correction(自我修正) 能力的企业级 Agent

摘要:当"降本增效"成为常态,企业知识流失的速度远超你的想象。本文将不再停留在简单的 RAG demo 层面,而是深入 LangGraph 的底层架构,带你从零构建一个具备 Cyclic Loop(循环反思) 与 Self-Corr…...

STM32远程固件升级(FOTA)实现方案详解

1. STM32远程升级方案概述在嵌入式设备开发中,远程固件升级(FOTA)是一项至关重要的功能。当设备部署在难以物理接触的场所时,通过无线或有线方式实现固件更新可以大幅降低维护成本。STM32系列单片机凭借其灵活的存储布局和丰富的通信接口,非常…...

基于 LangGraph 的 Agentic RAG 核心架构

核心摘要:当资深运维专家离场,留下的往往不仅是空荡荡的工位,更是无数无法被Wiki捕捉的“隐性知识”。本文将摒弃空洞的概念炒作,基于 Agentic RAG 架构,利用 LangGraph 与 Qwen2.5,从零构建一个具备“反思…...

4564564

43434...

Go语言的gRPC服务开发

Go语言的gRPC服务开发 1. gRPC简介 gRPC是Google开发的高性能、开源的RPC框架,基于HTTP/2协议和Protocol Buffers序列化格式。它支持多种语言,包括Go、Java、C、Python等,非常适合构建微服务架构。 gRPC的优势 高性能:基于HTTP/2协…...

​Problem - 2180D - Codeforces​

Problem - 2180D - Codeforces 题意很简单 要求圆的面积没有交点 然后求尽可能大的相切点的个数 首先每个点的半径的上界就是他到相邻两个节点的距离的最小值 对于一段合法的圆 我们可以求一下第一个圆的半径的范围 然后就可以根据圆之间的距离求出下一个圆的半径的范围 如…...