8位SPI怎么传12位数据——跨字节打包

8位SPI怎么传12位数据——跨字节打包
一句话: 切换到 8 位 SPI 模式后12 位 DAC 数据要跨字节打包。用 Data8 和 Data0xFF 直接拼会把高 4 位挤丢——电流只有设定值的 1/16。正确写法是 (Data4)0xFF 和 (Data0x0F)4。适合谁读用 8 位 SPI 模式操作 12/16 位 DAC 的嵌入式开发者。问题DAC 芯片用 SPI 控制数据是 12 位的0~4095。之前用 16 位 SPI 模式一次发两个字节刚好。后来改成 8 位 SPI写数据的代码没跟着改。设输出 30mADAC 码 0x019A十进制 410。代码这样写// 错误直接把 12 位数据当两个独立字节发 SPI_Write8(0x30 Channel, Data 8, Data 0xFF);发出去的是什么Data 8 0x01Data 0xFF 0x9A。但 DAC 的 SPI 命令格式要求 12 位数据跨字节打包Byte2 [D11 D10 D9 D8 D7 D6 D5 D4] Byte3 [D3 D2 D1 D0 X X X X]代码发出 Byte20x01, Byte30x9A。DAC 收到的是什么Byte2 0000_0001 Byte3 1001_1010 DAC 看到的数据 Byte2高4位 Byte3低8位??实际是 DAC 从两个字节中按位提取。代码把 12 位数据直接拆成了两个 8 位字节发出去DAC 按自己的格式解析。结果是 DAC 拿到了错误的值——大概是设定值的 1/16。设 30mA → 实际输出约 1.8mA。正确的打包// 正确跨字节按位打包 uint8_t byte2 (Data 4) 0xFF; // D11~D4 uint8_t byte3 (Data 0x0F) 4; // D3~D0, 左移4位 SPI_Write8(0x30 Channel, byte2, byte3);以 30mA 为例(0x019A 4) 0xFF 0x19(0x019A 0x0F) 4 0xA0。DAC 收到正确的 D[11:0] 0x019A 410。为什么之前没发现之前测试时用了更小的设定值。小值的低 4 位碰巧是 0 或者误差在容忍范围内看起来正常。直到换到大电流才发现偏差巨大。SPI 位宽切换后把所有数据编码代码重新检查一遍不凭上一次还正常做假设。有用的话点个收藏下次调试直接用。有问题欢迎评论区交流看到了都会回。