Q 格式使用总结
注意 16位有符号数 表示的范围是 -32768~32767
假如 整形数在内存中以源码的形式存放, 则0000 0000 0000 0000 表示正整数0
则 1000 0000 0000 0000 表示负整数0 ,显然重复了。
另外采用补码 可以将减法运算变为加法:
例如: -1-2=-3 可以变为 -1的补码加上-2的补码
对于整数: [A-B]补=[A]补+[-B]补
-1的补码为
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
-2的补码为
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
相加 变为
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
上边的红色1 为进位 去掉
则
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
减1 以后, 求反 可知道为-3
结论:故数据在内存中以补码的形式存放。
数据在内存中以补码的形式存放,
对于正整数 源码=反码=补码
对于负数 例如-10
源码为 1000 0000 0000 1010 1为符号位
反码为 1111 1111 1111 0101
补码为 1111 1111 1111 0110
假设对于有符号数A 在内存中的存放形式
补码为以下:
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
则它表示的数为:
符号位不变,先减1 然后在求反, 可知 这个数不存在
于是 人为 规定 1000 0000 0000 0000 表示为-32768
对于IQ格式 数据的理解:
IQ30 表示的数据范围:
31 | 30 | Point | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
对IQ30小数点在30位和29位之间, 所以它表示的数值范围是
-2-----1.999 999 999
同理对于 IQ16
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | POINT | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
即 -32768------32767.999984741
使用方法:
IQN实际没你想的复杂,你就简单的认为是把小数的乘法,变为整数的乘法而已。
只要计算的结果 不超过你规定的IQN的范围就行。
只是这样做 CPU的在处理浮点数时,更得心应手
例如 :
对与60kW永磁场同步电机的 直流母线电压采样环节
图1
在EEPROM 参数设定的上位机 软件中 Systemp->UDC_LEM_RATIO 的值为200
BASE_VOLTAGE的值为1000
已知IQ20的表示范围为 -2048----2047.999 999 046
所以IQ20(200) 与IQ20(1000) 是合理的。 如果是IQ(3000)就不对了。
上图1 的第一行temp 我在ADDWATCHWINDOW以后,用Q24 的格式去观看,就是0.6
上图1中的第二行的temp 我在watchwindow 里观测, 其值为 0.0001465082169
如下图所示
如用_iq格式观看,其值为 2458 (这里iq 为全局IQ24 是整形数)
tmp=_IQdiv(tmp,_IQ15toIQ(Systemp->UDC_LEM_FACTOR));
Systemp->UDC_LEM_FACTOR的值为19661
19661 如果是IQ15格式 对应的数为
经过了IQ15toIQ以后, 我如果用IQ24查看,其值还是 0.6
关于对母线电压采样的说明:
直流母线采样,1000V对应调理输出为5V 然后经过电路板上分压电阻3/5转换为3V,(因为DSP要求的电压是3V), 即ADC采样得到的4095 对应的是1000V 那么假设ADC采样得到的值是y
第一极的比例
第二极的比例
第三极的比例
那么 实际的电压值应为
那么之流母线的标幺值为
在DSP程序中 通过上面的图指导UDC_PU_GAIN 的值就是
所以上面的红线高亮的udc是标幺值,上传给上位机就需要转换为真实值
当DSP把这个数据传递给上位机,在邮箱11中
用VB编写的上位机的接收的是整数, 于是在VB中定义了一个浮点数,
然后将DSP传递上来的整数除以32768 在乘以1000 即可 。
下图是VB上位机的处理
(2) IQ的乘法
描述:C编译器将两个不同的IQ格式的IQ数进行相乘。
关于对_IQNmpyIQX(_iqN1 A ,int N1 _iqN2 B ,int N2)
下面的程序 定义 temp135 为 IQ4 temp678 为IQ22 temp246为IQ16
实际计算的值
而我用IQ乘法计算得到的值为1166.952225
误差为 0.154759
如下图所示:
如果采用了 IQ4(450.256) 未超出IQ4的表示的数的数值范围
IQ22(200.789) 未超出IQ22表示的范围
而
这个90406.451984 超出了_iq16 表示的数值范围,所以计算结果不对,如下图所示。
若把temp246 改正为 _IQ10 那么计算结果会好吗?
IQ10的数值范围 -2097152------2097151.999023
计算结果为90405.24707
计算误差为
精度基本上到万分之一
精度已经很高了,能不能再高一些,
我的想法是:用IQ14代替IQ10 因为IQ14 的分辨率高于IQ10 提高精度的作用不大。
百度网盘