简介:PAW3395DM-T6QU产品中文数据表面向嵌入式硬件、光学传感器与游戏外设开发人员,服务于高端光学游戏鼠标的芯片选型、电路设计、驱动适配与性能评估。压缩包仅含1个PDF文件,约3.71MB,以中文数据表形式集中整理芯片概览、关键电气参数、引脚与四线SPI接口、供电范围、工作及待机电流、分辨率、跟踪速度、提升检测、镜头配合和订购包装等信息,方便按主题快速查阅。文档对650ips高速运动检测、50g加速度、最高26000cpi且每步50cpi可调分辨率、850nm照明光源、HP/LP模式、运动中断输出以及1mm/2mm升降检测设置均有说明,可作为功耗估算、外围器件选型和调试排错的依据。目前已有508人学习或下载,适合需要核对关键指标、评估外围器件并规划有线或无线鼠标方案的硬件工程师与驱动开发者参考。
1. 一块 650 ips 的传感器摆在面前:这份中文数据表能省掉什么
样机焊好、上电、SPI 能读出数,鼠标一动指针就开始飘——这种场面做过光学鼠标的同行大概都不陌生。手里这颗 PAW3395DM-T6QU,标称 650 ips、50 g 加速度、最高 26000 cpi,参数漂亮得让人想立刻打板,但真正决定能不能一次点亮的,是那份几十页的英文规格书。这份 PAW3395DM-T6QU 产品中文数据表把芯片概览、引脚定义、电气规格、机械尺寸、SPI 时序、上电顺序、操作指南一直到寄存器汇总表和位掩码全部译了过来,目录从 1.0 介绍一路排到 8.3 寄存器写入的位掩码,做嵌入式系统底层驱动的、做光学传感器选型的、做集成电路设计参考的,都能直接拿它当工作底稿。适合谁?适合已经画完原理图、正要写第一版驱动,或者调了半天抬升检测还是误触发的人。
2. 电气边界先立住:VDD 1.8–2.1V、上电时序与一张功耗预算表
原理图阶段最容易犯的错,是把「电源范围」当成一个可以四舍五入的区间。这颗芯片给了两个电源域,而且宽窄差得很远:VDD 是 1.8 至 2.1 V,VDDIO 是 1.8 至 3.3 V。前者窄得几乎没有余量,后者宽到可以直接跟 3.3 V 的 MCU IO 对接。这两条不搞清楚,后面的调试全是玄学。
2.1 VDD 与 VDDIO 分开算:窄窗口电源域的接法
先把两个域的角色分清楚,再谈器件选型。
| 电源域 | 数据表范围 | 作用 | 常见接法 | 高频翻车点 |
|---|---|---|---|---|
| VDD | 1.8–2.1 V | 核心与模拟电路供电 | 锂电经低压差 LDO 或 DC-DC 降到 1.9 V 附近 | 直接接 3.3 V 或锂电正极 |
| VDDIO | 1.8–3.3 V | IO 电平参考 | 与主控 IO 同域,3.3 V 直连可行 | 与 VDD 短接,导致 VDD 超上限 |
| 照明源 | 850 nm | 光学照明,脉冲电流 | 独立限流与储能电容 | 与 VDD 共用细走线,纹波灌进模拟域 |
VDD 上限只有 2.1 V,意味着单节锂电的 3.0–4.2 V 绝对不能直供,必须经过一级稳压。我一般会选静态电流在几个微安量级、压差在 100 mV 以内的 LDO,原因很直接:芯片高性能模式典型电流才 1.7 mA,如果 LDO 自身的静态电流就有几十微安甚至上百微安,整机待机功耗会被这颗稳压器吃掉一大截,续航算出来好看、实测打脸。另外 850 nm 照明源是脉冲工作的,瞬时电流远大于平均值,储能电容要靠近引脚放,别让这段大电流路径穿过模拟地。
提示:绝对最大额定值那一节不要跳过。它是「超过就不保证」的边界,不是「推荐工作条件」。推荐工作条件写的是能正常跑的范围,两者差着一层安全余量。
2.2 上电顺序与复位:第一次通信失败多半出在这里
数据表把开机顺序、上电初始化寄存器设置和复位分成了三个小节,顺序是有讲究的。上电时先给 VDD 再给 VDDIO,中间留出稳定时间,然后释放复位、等待内部振荡器起振,最后才发初始化寄存器序列。芯片内部自带振荡器,不需要外部时钟输入,这一点省了晶振,但也意味着「等它起振」这段时间只能靠延时保证,没有时钟信号可以给你测。
/* 上电与初始化骨架:寄存器符号名按数据表 8.1 汇总表映射,地址不在此硬编码 */ static int sensor_power_on(void) { board_rail_enable(RAIL_VDD); /* 先 VDD,顺序依据 6.1 开机顺序 */ delay_us(300); /* 等待核心电源稳定 */ board_rail_enable(RAIL_VDDIO); /* 再 VDDIO */ delay_us(300); board_reset_release(); /* 复位释放,脉宽与时序按 6.3 复位一节 */ delay_ms(2); /* 留出内部振荡器起振窗口 */ if (spi_read_reg(REG_PRODUCT_ID) != EXPECTED_PRODUCT_ID) return -1; /* 读不到 ID 就别往下走,先查电源和时序 */ for (int i = 0; init_table[i].addr != INIT_TABLE_END; i++) spi_write_reg(init_table[i].addr, init_table[i].val); /* 6.2 初始化表 */ return 0; }这段骨架里三个参数值得单独说。第一是两级电源之间的延时,具体数值取决于稳压器输出建立时间,数据表给的是顺序要求,延时量要按自己板子上的 LDO 手册来配,我通常先给 300 µs 再往上加,不用一上来就 10 ms 糊过去。第二是复位释放后的等待,短了读 ID 会偶发失败,长了只是多花几毫秒,宁可多等。第三是 ID 校验,这是整段代码里最值钱的一行——它能一次性把「电源没起来」「复位没释放」「SPI 极性搞反」「片选接错脚」这几类问题挡在初始化之前,而不是等到鼠标动了才发现数据不对。
初始化表本身不建议手敲。数据表 6.2 给的是寄存器地址和值的对照,工程上常规做法是把这张表做成一个结构体数组或者 CSV,编译时生成,改一版芯片就换一张表,别把几十条写死在一堆赋值语句里,否则下次对照数据表核对时你会想砸键盘。
2.3 功耗预算:把 1.7 mA 拆成一张能算续航的表
低功耗是这颗芯片的卖点之一,但数据表给的是一组不同状态下的典型值,直接拿最高性能模式那个数去算电池寿命,结果会偏悲观;只拿最深的掉电模式去算,那就是自欺欺人。
| 工作状态 | 典型电流 | 说明 |
|---|---|---|
| 高性能模式 HP | 1.7 mA | 含照明源电流,游戏主用状态 |
| 低功耗模式 LP | 1.3 mA | VDD = 1.9 V 条件下测得 |
| Rest1 | 580 µA | 含 LED 电流,浅休眠 |
| Rest2 | 11 µA | 深一级休眠 |
| Rest3 | 6 µA | 更深休眠 |
| 掉电 | 4 µA | 最低功耗状态 |
算续航时把整机拆成四块:传感器平均电流、主控平均电流、射频平均电流、稳压器静态电流。传感器这一项不是取某一个状态,而是按占空比加权。举个例子,一局游戏里 30% 时间在 HP、50% 在 LP、剩下 20% 分布在 Rest1 到掉电,那平均值大约落在几百微安量级;而办公场景反过来,绝大多数时间停在 Rest1 以下,平均值会低一个数量级。剩下的主控和射频往往才是大头,尤其是无线方案里射频的收发占空比,经常比传感器本身更影响续航。
注意:Rest1 的 580 µA 明确标注了「包括 LED 电流」。做预算时如果把照明源再单独加一遍,会重复计算;反过来,如果自己改了照明源的限流电阻,这个数就不再成立,得重新测。
3. 四线 SPI 落地:读写命令、tSXX 间隔与 Motion Burst 打包
电气层面通了,接下来就是通信。这颗芯片用的是四线串行外设接口,配合一根运动中断输出引脚。SPI 本身不复杂,复杂的是时序细节和数据组织方式——尤其是当你想在 1 ms 的轮询周期里把所有轴数据一次拿完的时候。
3.1 四根线加一根中断:片选纪律比时钟频率更重要
信号角色很常规:片选、时钟、主出从入、主入从出。真正容易出问题的是片选的行为——一次事务从拉低开始到拉高结束,中间不能被别的外设打断,也不能在字节之间抬高。如果主控的 SPI 是共享总线,多个从设备挂在一起,那必须保证同一时刻只有一个片选有效,且切换片选之间留出足够的空闲时间。
运动中断输出这根线值得单独提。它不是一个「有数据就翻转」的通用中断,而是按数据表里运动引脚时序那一节的规则输出的,一般配合「有运动才读、静止不读」的策略使用。这样主控可以大部分时间睡在低功耗里,靠这根线唤醒,读一次数据又睡回去。写固件时如果把它配成边沿触发却不做软件消抖,快速甩动时中断会密集到把 CPU 拖垮,反而比定时轮询更耗电。
时钟频率不要一上来就冲高。数据表给了建立时间、保持时间和从机输出延迟这几张波形图,实际能跑多快取决于走线长度、上拉电阻和主控的分频能力。我的习惯是先降到 1 MHz 左右把读写跑通、把 ID 读对,再用逻辑分析仪逐级往上抬,抬到出错就退回一档。
3.2 读写命令与 tSXX:抓波形先看三个点
读操作和写操作的首字节格式不一样,数据表 5.4 和 5.5 分别给了波形。工程上常见做法是把读写标志位做成宏,别在代码里散落魔法数字:
/* 首字节的读写标志位取值以数据表 5.4 / 5.5 的首字节定义为准,此处仅占位 */ #define SPI_WRITE_FLAG 0x80u #define SPI_READ_FLAG 0x00u static uint8_t spi_xfer(uint8_t out) { uint8_t in = 0; for (int i = 7; i >= 0; i--) { gpio_set(SCLK, 0); gpio_set(MOSI, (out >> i) & 1u); delay_ns(50); /* MOSI 建立时间,按 5.4 波形留余量 */ gpio_set(SCLK, 1); in = (uint8_t)((in << 1) | gpio_get(MISO)); /* MISO 在时钟沿采样 */ gpio_set(SCLK, 0); } return in; } uint8_t spi_read_reg(uint8_t addr) { uint8_t v; CS_LOW(); spi_xfer(SPI_READ_FLAG | (addr & 0x7Fu)); delay_us(1); /* 读命令与后续事务之间的间隔,见 5.6 */ v = spi_xfer(0x00); CS_HIGH(); return v; }三个关键点在波形上:MOSI 相对时钟上升沿的建立与保持时间、MISO 相对时钟的有效延迟、以及两次事务之间片选抬高的最小间隔。第三点数据表 5.6 单独列了一节,写命令之后紧接读命令,或者读命令之后紧接下一次访问,中间都必须满足这个最小间隔,否则第二次读回来的数据是上一次的残值。这个坑很隐蔽——单步调试时每条命令之间有人工停顿,一切正常;一跑循环就错,而且错得毫无规律。
提示:调 SPI 的时候把逻辑分析仪的四路都接上,别只接时钟和数据。片选那条线的毛刺、抬高时间不够、以及事务之间被高优先级中断插队,只有看片选才看得出来。
3.3 Motion Burst:把多次事务压成一次
默认方式读一次运动数据,要分别访问 X 低位、X 高位、Y 低位、Y 高位,外加运动标志,一次轮询五六次事务,每次都有片选开销和间隔开销。数据表 5.7 给的动作阅读加启动 Motion Burst 的程序,就是解决这个问题的:进突发模式之后,一次片选内连续把整组运动字段读完,主控的中断服务程序可以做得非常短。
typedef struct { uint8_t motion; /* 运动标志 */ int16_t delta_x; /* 本帧 X 位移,符号按 7.1 原始数据输出定义 */ int16_t delta_y; uint8_t quality; /* 表面质量,用于抬升判断的辅助参考 */ } motion_frame_t; static int read_motion_burst(motion_frame_t *f) { uint8_t buf[BURST_LEN]; /* 长度以 burst 寄存器设置为准,勿硬编码 */ CS_LOW(); spi_xfer(SPI_READ_FLAG | REG_MOTION_BURST); for (int i = 0; i < BURST_LEN; i++) buf[i] = spi_xfer(0x00); /* 片选期间不可抬高 */ CS_HIGH(); f->motion = buf[0]; f->delta_x = (int16_t)((buf[2] << 8) | buf[1]); f->delta_y = (int16_t)((buf[4] << 8) | buf[3]); f->quality = buf[5]; return f->motion ? 0 : -1; }字段顺序按数据表 5.7.1 的动作阅读排列,缓冲长度由突发模式寄存器决定,不同固件版本配的长度可能不同,所以不要把 6 写死在数组维度里,用宏或者配置常量。位移是 16 位有符号数,低位在前,拼装时注意强制转换,不然负位移会被当成一个巨大的正数,表现为鼠标往左移指针往右飞。最后那个返回值用运动标志位判断有没有有效位移,静止时直接丢弃,避免把零位移当成事件上报给上层。
4. 光学链路与抬升检测:镜头装配、26000 cpi 设置和手动校准流程
传感器本身只是半个系统,另外半个是光学。这颗芯片设计上与 LM19-LSI 或 L0AE-LSI1 镜头配合使用,芯片组装图、镜头装配分解图、PCB 组装建议各占一节,说明原厂认为机械装配是会被问爆的地方。
4.1 镜头装配:两种镜头的分解顺序与 PCB 开孔
LM19-LSI 是圆形镜片,L0AE-LSI1 是修剪镜头,两者装配路径不同,分解图分别在 3.4.1 和 3.4.2。装配顺序上的共性要求是:先固定芯片,再对位镜头,最后锁紧或点胶,中途不能靠压合把芯片顶偏。
| 步骤 | 要点 | 装错的典型表现 |
|---|---|---|
| 芯片贴装 | 按组装图给出的方向和机械切口对位 | 方向反了,位移轴整体旋转 90 度 |
| PCB 开孔 | 孔径与光路同心,孔壁不挡光 | 边缘暗角,低 CPI 下抖动 |
| 镜头对位 | 镜头倍率 1:1,按分解图压入到位 | 焦点偏,表面质量读数偏低 |
| 锁紧/点胶 | 固化前后不复检同心度 | 跌落测试后位移漂移 |
PCB 组装建议那一节给的间距和方向要求,做结构的朋友最好一起看。芯片封装尺寸是 10.90 × 16.20 × 9.81 mm³(含镜头组件的整体外形),开孔位置差零点几毫米,在 26000 cpi 这个分辨率下会被放大成明显的轴向偏差。我自己踩过一次:光孔做成了腰形,觉得余量大好装配,结果在布面鼠标垫上表面质量一直上不去,换回圆形孔立刻恢复——光路这东西不太讲情面。
4.2 CPI 设置与 0.4% 误差:分辨率不是越高越好
分辨率可调范围到 26000 cpi,步长 50 cpi,这个粒度足够做很多档位。但数据表同时给了一个容易被忽略的数字:在 5000 cpi 上,分辨率误差典型值为 0.4%。也就是说,标称 5000 cpi 的档位,实际可能是 4980 或者 5020 左右。做产品时如果上层还有一套 DPI 换算或者游戏内灵敏度映射,这个误差会被带进去,表现为「同一档位在不同机器上手感有细微差别」。
设置流程本身不复杂:写分辨率寄存器,等一帧数据稳定,再读回校验。要点在于切换分辨率之后的第一帧不要用,那时候内部帧率还在自适应调整。这颗芯片支持自调节可变帧率以获得最佳性能,帧率跟着运动速度走,切换档位属于突变场景,给它一两帧的稳定时间是值得的。
另外 650 ips 和 50 g 这两个指标对应的是高性能模式,QCK 模式下的跟踪速度是 200 ips。做无线方案时如果为了省电长时间待在低功耗模式,却按 650 ips 的指标去设计加速度曲线,快速甩枪时就会丢帧。这不是芯片的问题,是模式和指标没对齐。
4.3 Lift Cutoff:1 mm/2 mm 通用设置与手动校准的分界
抬升检测决定了鼠标离开桌面多高之后停止输出位移。数据表给了两个层次的方案:7.4 的通用抬升切断,提供 1 mm 和 2 mm 两档;7.5 的手动抬升切断校准,允许按自己的结构和表面做一次标定,标定结果通过 7.5.2 的寄存器设置启用,7.5.3 是禁用流程。
手动校准的流程大致按 7.5.1 的步骤走:
| 顺序 | 操作 | 说明 |
|---|---|---|
| 1 | 进入校准使能状态 | 按 7.5.2 的寄存器设置 |
| 2 | 在目标表面上静置 | 表面材质要与量产物料一致 |
| 3 | 按流程抬升到标称高度 | 1 mm 或 2 mm,按结构设计值 |
| 4 | 记录并写入校准结果 | 按 7.5.1 给定步骤 |
| 5 | 退出并使能 | 按 7.5.2 完成 |
校准这件事最怕的是「用错表面」。在实验室的光面桌上校完,量产用户的布垫、树脂垫、玻璃垫各不相同,表现自然分裂。常规做法是选一块中等粗糙度的布垫做基准,再在几块极端表面上抽测,如果某类表面上误触发率高,就退回通用设置,别硬调校准参数迁就单一表面。
注意:校准数据和分辨率档位是两回事,切换 cpi 不会自动重做校准,但更换镜头组件、改变光孔结构、或者换了照明源限流之后,校准结果就不再有效,必须重做。
5. 避坑记录:五次翻车对应的现象、原因与解决
5.1 电源与上电类
现象一:板子回来,SPI 读出来全是 0xFF,换一块板子偶尔能读到正确 ID。原因:两级电源上电顺序和延时靠稳压器的自然建立时间「碰运气」,VDD 还没稳,VDDIO 已经到位,芯片内部进了不确定状态;另一块板子因为 LDO 批次不同,建立时间刚好够,于是时好时坏。解决:把上电顺序固化成代码里的显式延时,不要依赖上电器件的默认时序,同时在读 ID 之前加一次软复位,把不确定状态清掉。
现象二:续航实测只有标称的一半。原因:VDD 那级 LDO 静态电流偏大,加上照明源储能电容漏电,两者加起来比传感器本身在 Rest1 状态下的电流还高。解决:把整机分状态实测一遍电流,逐个器件断开定位,换成低静态电流的稳压器,并把照明源的供电路径与模拟域分开走线。
5.2 SPI 与数据类
现象三:单步调试一切正常,跑循环就偶发读到上一帧的旧数据,位移值看起来像「卡住一帧」。原因:两次事务之间的间隔不满足 5.6 给出的最小值,片选抬高时间不够,从机还没释放总线,主控已经开始下一条命令。解决:按 5.6 的最小值留出余量,在片选抬高之后插一个短延时;共享 SPI 总线的场景下,把其他外设的访问排到后面,别在两帧之间插队。
现象四:Motion Burst 读出来的位移方向反了,或者数值大得离谱。原因:一是字节序拼装错了,低位在前被当成高位;二是突发长度寄存器配置和缓冲区长度不一致,后半段读到了无关寄存器。解决:先用单寄存器读的方式取一帧原始数据作为基准,再和突发模式的结果逐字节比对,对上了再改结构体,别凭感觉调。
5.3 光学与固件逻辑类
现象五:快速甩动时抬升检测误触发,指针突然停住。原因有两个层面:一是用了通用 1 mm 档位,而实际结构的光学间隙偏大,快速移动时表面质量读数波动越过阈值;二是校准用的是实验台光面,用户手上是粗布垫。解决:先按 7.5 的手动校准流程在中等粗糙度表面上重做一次标定,再在几块极端表面上抽测误触发率;如果仍然偏高,换 2 mm 档位牺牲一点抬升高度换取稳定性,并且在校准流程里加一步「连续快速移动 10 秒不触发」的验收条件。
还有一个不算翻车但很容易忽略的点:无线模式下的电源管理在 7.6 单独成节,从 HP 切到 LP、从 LP 切到各级 Rest,切换过程中部分寄存器状态会变。如果固件在休眠唤醒后不复写关键配置,就会出现「睡一觉醒来 cpi 变了」的怪现象。我的做法是把休眠前后需要保持的寄存器列一张清单,唤醒后逐条校验,不一致就整表重刷。
6. 点亮之后:8 项上电自检与抓波形的习惯
数据表翻到最后一章寄存器说明和位掩码,很多人会觉得活干完了。实际上从「能读到数」到「能交付」之间,还隔着一套自检。我后来固定用下面这张表跑一遍,八项里任何一项不过,就不往下做调参。
| 序号 | 检查项 | 判据 | 不过时先看哪 |
|---|---|---|---|
| 1 | VDD 实测电压 | 落在 1.8–2.1 V 内,纹波可控 | 稳压器与去耦 |
| 2 | VDDIO 电平 | 与主控 IO 同域 | 电平匹配 |
| 3 | 上电顺序 | 先 VDD 后 VDDIO,有稳定间隔 | 6.1 与代码延时 |
| 4 | 产品 ID 读取 | 连续 100 次全对 | 复位时序、SPI 极性 |
| 5 | 单寄存器读写回环 | 写入值与读回值一致 | 5.4 / 5.5 首字节 |
| 6 | Motion Burst 一致性 | 与单寄存器读结果逐字节相同 | 突发长度配置 |
| 7 | 分辨率切换 | 切档后两帧内稳定,读回值正确 | 帧率自适应窗口 |
| 8 | 抬升检测 | 标称高度触发,快速移动不误触发 | 7.5 校准与表面 |
第 4 项和第 5 项是我加得最晚、但收益最大的两项。连续读 100 次 ID 而不是读一次,能把「上电时序临界」这类间歇性故障逼出来;单寄存器读写回环能提前发现地址位掩码搞错的问题,数据表 8.3 专门讲了寄存器写入的位掩码,有些位是只读的、有些位写入会被忽略,如果不按掩码操作,写进去读回来不一样,你会以为是通信坏了,其实是自己写错了位。
抓波形这件事也值得养成固定习惯:每次改 SPI 相关代码,不管改动多小,都抓一次完整事务的波形存盘,标注日期和固件版本。听起来很笨,但真出事的时候,能对比的旧波形就是后悔药。我吃过一次亏,某个版本的初始化表顺序被无意调换,导致低温下偶发不启动,现场没有旧波形可比,只能从头复现,白白多花了两天。从那以后我每次改上电序列或者初始化表,都强制走一遍这八项自检并留一份波形存档,不管改动看起来多无害。希望帮到你。
本文还有配套的精品资源,点击获取