加热调节项目中USB 2.0 3字节温度读取C代码位操作求助
温度读取模块位操作与数据转换实现方案
核心协议梳理
根据传输协议,关键要点如下:
- 一次传输共6字节:前3字节为外部温度SOT,后3字节为内部温度SOT
- 每个SOT为12位编码,拆分到3个字节的低4位,高4位为同步标识:
- 外部温度3字节高4位依次为
0x00、0x10、0x20 - 内部温度3字节高4位依次为
0x80、0x90、0xA0
- 外部温度3字节高4位依次为
- 温度计算公式:
℃ = -39.64 + 0.04 × SOT
代码修正与位操作实现
关键问题修正
- 变量类型错误:
tempExtSOT/tempIntSOT是12位整数,应使用uint16_t或int(避免浮点赋值) - FT_Read参数不匹配:缓冲区仅6字节,
RxBytes应设为6而非8 - 缺失同步校验:必须验证每个字节的高4位,确保数据未错位
- 位操作逻辑缺失:通过掩码提取低4位,再移位拼接完整12位SOT
完整修正代码
#include "releve.h" #include <windows.h> #include "ftd2xx.h" #include "define.h" #include <stdint.h> // 引入uint16_t类型定义 void releve(){ FT_HANDLE ftHandle; FT_STATUS ftStatus; DWORD RxBytes = 6; // 匹配6字节缓冲区 DWORD BytesReceived; uint16_t tempExtSOT = 0; // 12位SOT用16位整数存储 uint16_t tempIntSOT = 0; float tempExtDec = 0.0; float tempIntDec = 0.0; char RxBuffer[6] = {0}; // 初始化缓冲区 // 打开设备并检查状态 ftStatus = FT_Open(0, &ftHandle); if (ftStatus != FT_OK) { printf("Failed to open FTDI device\n"); return; } // 读取6字节数据并检查状态 ftStatus = FT_Read(ftHandle, RxBuffer, RxBytes, &BytesReceived); if (ftStatus != FT_OK || BytesReceived != RxBytes) { printf("Failed to read data, received %d bytes\n", BytesReceived); FT_Close(ftHandle); return; } // 校验外部温度同步位并提取SOT if( (RxBuffer[0] & 0xF0) == 0x00 && (RxBuffer[1] & 0xF0) == 0x10 && (RxBuffer[2] & 0xF0) == 0x20 ) { // 提取低4位并移位拼接:bit11-8 <<8 | bit7-4 <<4 | bit3-0 tempExtSOT = ((RxBuffer[0] & 0x0F) << 8) | ((RxBuffer[1] & 0x0F) << 4) | (RxBuffer[2] & 0x0F); } else { printf("External temperature sync error\n"); } // 校验内部温度同步位并提取SOT if( (RxBuffer[3] & 0xF0) == 0x80 && (RxBuffer[4] & 0xF0) == 0x90 && (RxBuffer[5] & 0xF0) == 0xA0 ) { tempIntSOT = ((RxBuffer[3] & 0x0F) << 8) | ((RxBuffer[4] & 0x0F) << 4) | (RxBuffer[5] & 0x0F); } else { printf("Internal temperature sync error\n"); } // 转换为实际温度 tempExtDec = -39.64 + (0.04 * tempExtSOT); tempIntDec = -39.64 + (0.04 * tempIntSOT); // 输出结果 printf("External SOT: %u\n", tempExtSOT); printf("Internal SOT: %u\n", tempIntSOT); printf("External Temperature: %.2f ℃\n", tempExtDec); printf("Internal Temperature: %.2f ℃\n", tempIntDec); // 关闭设备 FT_Close(ftHandle); }
位操作逻辑说明
以外部温度为例:
RxBuffer[0] & 0x0F:提取第1字节的低4位(SOT bit11-8),左移8位后占据16位整数的高4位(对应SOT的bit11-8)RxBuffer[1] & 0x0F:提取第2字节的低4位(SOT bit7-4),左移4位后占据中间4位RxBuffer[2] & 0x0F:提取第3字节的低4位(SOT bit3-0),直接放在低4位- 三者通过
|运算拼接成完整的12位SOT值
额外建议
- 增加数据循环读取逻辑:传输周期为40ms,可通过定时任务或循环读取实现连续采样
- 处理SOT范围:12位编码范围是04095,对应温度范围-39.64℃124.16℃,可增加范围校验确保数据合理性
- 确认字节序:FT245R是并行转USB,需保证FPGA输出的字节顺序与读取顺序一致
内容的提问来源于stack exchange,提问作者retiox2
相关产品推荐
相关产品推荐

