You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

加热调节项目中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
  • 温度计算公式:℃ = -39.64 + 0.04 × SOT

代码修正与位操作实现

关键问题修正

  1. 变量类型错误:tempExtSOT/tempIntSOT是12位整数,应使用uint16_t或int(避免浮点赋值)
  2. FT_Read参数不匹配:缓冲区仅6字节,RxBytes应设为6而非8
  3. 缺失同步校验:必须验证每个字节的高4位,确保数据未错位
  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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 11:35:35