ZHCADY9 April   2024 LM73 , LM75B , LM95071 , TMP100 , TMP101 , TMP102 , TMP103 , TMP104 , TMP107 , TMP1075 , TMP108 , TMP112 , TMP114 , TMP116 , TMP117 , TMP121 , TMP122 , TMP123 , TMP124 , TMP126 , TMP144 , TMP175 , TMP1826 , TMP1827 , TMP275 , TMP400 , TMP401 , TMP411 , TMP421 , TMP422 , TMP423 , TMP431 , TMP432 , TMP435 , TMP451 , TMP461 , TMP464 , TMP468 , TMP4718 , TMP75 , TMP75B , TMP75C

 

  1.   1
  2.   摘要
  3.   商标
  4. 1引言
    1. 1.1 二进制补码
      1. 1.1.1 二进制补码特征
    2. 1.2 Q 格式
    3. 1.3 常见温度数据格式
    4. 1.4 高精度温度数据格式
  5. 2代码示例
    1. 2.1  16 位(采用 Q7 表示法)
      1. 2.1.1 属性
      2. 2.1.2 C 代码
    2. 2.2  12 位(采用 Q4 表示法)
      1. 2.2.1 属性
      2. 2.2.2 C 代码
    3. 2.3  13 位(采用 Q4 表示法)(EM=1)
      1. 2.3.1 属性
      2. 2.3.2 C 代码
    4. 2.4  13 位(采用 Q4 表示法)
      1. 2.4.1 属性
      2. 2.4.2 C 代码
    5. 2.5  14 位(采用 Q6 表示法)
      1. 2.5.1 属性
      2. 2.5.2 C 代码
    6. 2.6  TMP182x 格式
      1. 2.6.1 属性
      2. 2.6.2 C 代码
    7. 2.7  14 位(采用 Q5 表示法)
      1. 2.7.1 属性
      2. 2.7.2 C 代码
    8. 2.8  8 位(无 Q 表示法)
      1. 2.8.1 属性
      2. 2.8.2 C 代码
    9. 2.9  11 位(采用 Q3 表示法)
      1. 2.9.1 属性
      2. 2.9.2 C 代码
    10. 2.10 不采用二进制补码的器件
      1. 2.10.1 属性
      2. 2.10.2 C 代码
  6. 3其他编程语言
    1. 3.1 解析
    2. 3.2 二进制补码
    3. 3.3 丢弃未使用的位
    4. 3.4 应用 Q 格式
  7. 4总结
  8. 5参考资料
  9. 6附录:Q 应用源代码
  10. 7附录:器件概要表

附录:Q 应用源代码

此实用程序可用于对任何 Q 格式编码进行温度转换。此代码专为类 Unix 的 shell 编写和测试。我们建议将源代码另存为 q.c 并使用 cc q.c -o qapp 编译代码。

#include <stdio.h>
#include <unistd.h>

void main(int argc, char *argv[])
{
	int c;
	uint8_t bits = 16;
	uint8_t qnum = 7;
	uint8_t byte1;
	uint8_t byte2;
	int16_t data;
	int mode = 0;
	while ((c = getopt(argc, argv, "b:q:hx")) != -1)
		switch (c)
		{
		case 'b':
			sscanf(optarg, "%hhi", &bits);
			break;
		case 'q':
			sscanf(optarg, "%hhi", &qnum);
			break;
		case 'h':
			mode = 1; /* print help */
			break;
		case 'x':
			mode = 2; /* print example code */
		}
	uint8_t shift = 16 - bits;
	float resolution = (float)1 / (1 << qnum);
	/* recommend using a constant for resolution in application code */
	if (mode == 0)
	{ /* parse byte(s) and print celsius */
		switch (argc - optind)
		{
		case 2:
			sscanf(argv[optind], "%hhi", &byte1);
			sscanf(argv[optind + 1], "%hhi", &byte2);
			data = (int8_t)byte1 << 8 | byte2;
			printf("input: %d (0x%hhX) and %d (0x%hhX) becomes %d (0x%hX)\n", byte1, byte1, byte2, byte2, data, data);
			break;
		case 1:
			sscanf(argv[optind], "%hi", &data);
			printf("input: %d (0x%hX) is assumed to be 16-bit\n", data, data);
			break;
		case 0:
			data = 0x7FFF;
			printf("demo: %d (0x%hX)\n", data, data);
			break;
		}
		printf("%d-bit format will have %d bits discarded by right shift\n", bits, shift);
		data >>= shift;
		printf("q%d is %f resolution\n", qnum, resolution);
		float f = data * resolution;
		printf("float: %f C\n", f);
		/* preserve fractional result while using int only */
		int mC = data * 1000 >> qnum;
		printf("int: %d mC\n", mC);
		/* discard fractional result while using int only */
		int C = data >> qnum;
		printf("int: %d C\n", C);
	}
	else if (mode == 1) /* print help */
	{
		printf("qapp [-b bits] [-q qnum] [byte] [byte2]\n\
use -b to specify number of bits\n\
use -q to specify Q format, which describes resolution\n\
byte can be 16 bit data or the first of two 8 bit bytes\n\
byte2 is the second 8 bit byte that will be assembled with byte\n\
\n\
Device settings:\n\
TMP117, TMP114:\n\
 qapp -b 16 -q 7 0x0C80\n\
TMP102, TMP112, TMP1075:\n\
 qapp -b 12 -q 4 0x1900\n\
TMP102, TMP112 EM=1:\n\
 qapp -b 13 -q 4 0x0C80\n\
TMP468:\n\
 qapp -b 13 -q 4 0x0C80\n\
TMP107:\n\
 qapp -b 14 -q 6 0x1900\n\
TMP126:\n\
 qapp -b 14 -q 5 0x0C80\n\
");
	}
	else if (mode == 2) /* print example code */
	{
		/* use 24.5 to represent nominal, ambient temperature with the first fractional bit set */
		int16_t exdata = 24.5f / resolution;
		exdata <<= shift;
		printf("C Code Examples:\n");
		printf("/* %d-bit format will have %d bits discarded by right shift\n", bits, shift);
		printf("   q%d is %f resolution\n", qnum, resolution);
		printf("   the following bytes represent 24.5C */ \n");
		printf("uint8_t byte1 = 0x%hhX;\n", exdata >> 8);
		printf("uint8_t byte2 = 0x%hhX;\n", exdata);
		if (shift)
			printf("float f = (((int8_t) byte1 << 8 | byte2) >> %d) * %gf;\n", shift, resolution);
		else
			printf("float f = ((int8_t) byte1 << 8 | byte2) * %gf;\n", resolution);
		if (shift)
			printf("int mC = (((int8_t) byte1 << 8 | byte2) >> %d) * 1000 >> %d;\n", shift, qnum);
		else
			printf("int mC = ((int8_t) byte1 << 8 | byte2) * 1000 >> %d;\n", qnum);
		if (shift + qnum == 8)
			printf("int C = (int8_t) byte1;\n");
		else if (shift)
			printf("int C = (((int8_t) byte1 << 8 | byte2) >> %d) >> %d;\n", shift, qnum);
		else
			printf("int C = ((int8_t) byte1 << 8 | byte2) >> %d;\n", qnum);
	}
}