news 2026/6/10 8:03:02

I2CSPI 沉浸式测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
I2CSPI 沉浸式测试

CH347L I2C 扫描地址

Linux- 树莓派测试

#!/usr/bin/env python3 # coding=utf-8 import ctypes from ctypes import * import sys DEV = "/dev/ch34x_pis0" DEV_C = c_char_p(DEV.encode()) LIB = "./libch347.so" # ---- load lib ---- ch347 = ctypes.cdll.LoadLibrary(LIB) # ---- prototypes ---- ch347.CH347OpenDevice.argtypes = [c_char_p] ch347.CH347OpenDevice.restype = c_int ch347.CH347CloseDevice.argtypes = [c_int] ch347.CH347CloseDevice.restype = None # StreamI2C fallback prototype ch347.CH347StreamI2C.argtypes = [c_int, c_ulong, c_void_p, c_ulong, c_void_p] ch347.CH347StreamI2C.restype = c_int def has_retack(): return hasattr(ch347, "CH347StreamI2C_RetACK") def bind_retack(): """ int CH347StreamI2C_RetACK( int DevHandle, ULONG iWriteLength, PVOID iWriteBuffer, ULONG iReadLength, PVOID oReadBuffer, PULONG oAckCount ) """ fn = ch347.CH347StreamI2C_RetACK fn.argtypes = [c_int, c_ulong, c_void_p, c_ulong, c_void_p, POINTER(c_ulong)] fn.restype = c_int return fn def open_dev(): h = ch347.CH347OpenDevice(DEV_C) if h == -1: print("CH347 open failed") sys.exit(1) return h def close_dev(h): ch347.CH347CloseDevice(h) def probe_ack_retack(fn_retack, h, addr7): """ 真·扫描:用 RetACK 看 ACK 数 事务:START + SLA+W + STOP 只要 ack_cnt > 0,说明这个地址有ACK(存在设备) """ tx = (c_ubyte * 1)() rx = (c_ubyte * 1)() ack = c_ulong(0) tx[0] = ((addr7 << 1) & 0xFE) # SLA+W r = fn_retack(h, 1, tx, 0, rx, byref(ack)) if r != 0: return False return ack.value > 0 def probe_ack_fallback(h, addr7): """ 退化版(不保证真):用“写地址+读1字节”试图触发NACK变为错误码 注意:很多 libch347 版本不会把 NACK 反映到返回值,所以可能假阳性 """ tx = (c_ubyte * 1)() rx = (c_ubyte * 1)() tx[0] = ((addr7 << 1) | 1) & 0xFF # SLA+R r = ch347.CH347StreamI2C(h, 1, tx, 1, rx) return r == 0 # 仅作退化判断 def scan(): h = open_dev() use_retack = has_retack() fn_retack = bind_retack() if use_retack else None if use_retack: print("CH347 I2C scan mode: RetACK (reliable)") else: print("CH347 I2C scan mode: fallback (NOT reliable)") print("Tip: your libch347.so may not export CH347StreamI2C_RetACK, so true i2cdetect-like scan is impossible.") # header print(" " + " ".join(f"{i:02X}" for i in range(16))) for hi in range(0x00, 0x80, 0x10): row = [f"{hi:02X}: "] for lo in range(16): a = hi + lo if a < 0x00 or a > 0x7F: row.append("--") continue if use_retack: ok = probe_ack_retack(fn_retack, h, a) else: ok = probe_ack_fallback(h, a) row.append(f"{a:02X}" if ok else "--") print(" ".join(row)) close_dev(h) if __name__ == "__main__": scan()

Windows 电脑测试

#! /usr/bin/env python # coding=utf-8 import os, sys from ctypes import * # ===== DLL ===== _here = os.path.dirname(os.path.abspath(__file__)) _dll = "CH347DLLA64.DLL" if sizeof(c_void_p) == 8 else "CH347DLL.DLL" ch347 = WinDLL(os.path.join(_here, _dll)) USB_ID = 0 # 第一个 CH347 # ===== prototypes ===== ch347.CH347OpenDevice.argtypes = [c_int] ch347.CH347OpenDevice.restype = c_int ch347.CH347CloseDevice.argtypes = [c_int] ch347.CH347CloseDevice.restype = None ch347.CH347StreamI2C.argtypes = [ c_int, c_ulong, c_void_p, c_ulong, c_void_p ] ch347.CH347StreamI2C.restype = c_int def has_retack(): return hasattr(ch347, "CH347StreamI2C_RetACK") def bind_retack(): fn = ch347.CH347StreamI2C_RetACK fn.argtypes = [ c_int, c_ulong, c_void_p, c_ulong, c_void_p, POINTER(c_ulong) ] fn.restype = c_int return fn def open_dev(): if ch347.CH347OpenDevice(USB_ID) == -1: print("CH347 open failed") sys.exit(1) def close_dev(): ch347.CH347CloseDevice(USB_ID) def probe_retack(fn, addr7): tx = (c_ubyte * 1)() rx = (c_ubyte * 1)() ack = c_ulong(0) tx[0] = (addr7 << 1) & 0xFE # SLA+W r = fn(USB_ID, 1, tx, 0, rx, byref(ack)) return r == 0 and ack.value > 0 def probe_fallback(addr7): tx = (c_ubyte * 1)() rx = (c_ubyte * 1)() tx[0] = ((addr7 << 1) | 1) & 0xFF return ch347.CH347StreamI2C(USB_ID, 1, tx, 1, rx) == 0 def scan(): open_dev() use_retack = has_retack() fn = bind_retack() if use_retack else None print("CH347 I2C scan (Windows)") print("mode:", "RetACK (reliable)" if use_retack else "fallback (not reliable)") print(" " + " ".join(f"{i:02X}" for i in range(16))) for hi in range(0x00, 0x80, 0x10): row = [f"{hi:02X}:"] for lo in range(16): addr = hi + lo if addr > 0x7F: row.append("--") continue ok = probe_retack(fn, addr) if use_retack else probe_fallback(addr) row.append(f"{addr:02X}" if ok else "--") print(" ".join(row)) close_dev() if __name__ == "__main__": scan()
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 21:30:35

TOP 50!边界智能出席中国数字金融独角兽榜单颁奖仪式并作精彩分享

近日&#xff0c;由北京金融街研究院主办的「中国数字金融独角兽榜单 2025 颁奖仪式及交流会」在北京举行。来自清华大学金融科技研究院、西南财经大学全球金融战略实验室、招商银行研究院等权威机构的专家学者&#xff0c;以及边界智能等数字金融独角兽上榜企业代表汇聚现场&a…

作者头像 李华
网站建设 2026/6/10 14:34:42

云服务器入门指南:从概念到核心价值全面解读

在数字化时代&#xff0c;云服务器已成为个人开发者、企业机构开展线上业务的核心基础设施&#xff0c;但仍有不少人对其概念、原理和价值存在认知盲区。简单来说&#xff0c;云服务器&#xff08;Elastic Compute Service&#xff0c;简称ECS&#xff09;是一种基于云计算技术…

作者头像 李华
网站建设 2026/6/10 12:57:10

数据库的索引知识以及常见相关面试题

什么是索引&#xff1f; 数据库索引是一种数据结构&#xff0c;用于快速查找数据库表中的特定数据。它类似于书籍的目录&#xff0c;可以加快数据检索速度。索引是数据库优化的重要手段之一&#xff0c;它可以帮助数据库系统高效地定位到需要的数据行&#xff0c;从而提升查询…

作者头像 李华
网站建设 2026/6/10 12:57:16

一文讲清楚Spring中的三级缓存(附完整流程演示)

01-三级缓存的核心目的Spring 三级缓存主要解决两个核心问题&#xff1a;单例 Bean 的循环依赖问题&#xff1a;Bean A 依赖 Bean B&#xff0c;Bean B 又依赖 Bean AAOP代理与循环依赖的兼容问题&#xff1a;在循环依赖场景下&#xff0c;如何确保注入的是正确的代理对象02-三…

作者头像 李华
网站建设 2026/6/10 13:00:54

[Python实战] 告别浏览器驱动烦恼:用 Playwright 优雅实现网页自动化

在日常的网页自动化任务中&#xff0c;我们经常会遇到一个令人头大的问题&#xff1a;浏览器驱动的管理。无论是 Selenium 还是 Puppeteer&#xff0c;都离不开各种浏览器驱动&#xff0c;如 ChromeDriver、GeckoDriver 等。这些驱动不仅版本繁多&#xff0c;而且常常因为浏览器…

作者头像 李华
网站建设 2026/6/10 13:00:05

32、COM+ 技术:数据传输与管理的利器

COM+ 技术:数据传输与管理的利器 1. COM+ 管道技术 在 COM(Component Object Model)中,标准的封送技术最初旨在尽可能隐藏 RPC(Remote Procedure Call)机制的细节。当客户端调用方法时, [in] 参数会被传输到服务器,而 [out] 参数会在调用结束时返回。通常情况下,…

作者头像 李华