This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Q格式相乘问题



/* Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q*/ \
v.SpeedRpm = _IQmpy(v.BaseRpm,v.Speed);

v.BaseRpm为Q0格式v.Speed为Q15格式,他两个相乘为什么得到Q0格式的v.SpeedRpm。Q格式相乘不应该Q后面系数相加吗。

  • Q15*Q15生成Q15,Q0*Q15自然是Q0了。你可以参考.h里面的乘除法实现方式,其实乘完后是有降Q的动作的。

  •  v.Speed = _IQdiv(v.SpeedScaler,v.EventPeriod);

    我能再问你个问题吗,那为什么Q0除以Q0会生成Q15的格式那,我Q格式有点没学明白,

  • 安装IQmpy的定义,乘法的结果会转为宏定义的Q格式,默认是Q25。Q15和Q0相乘应该是Q0格式,因为Q15相当于I17Q15,Q0等于132Q0,结果如果是64位的话就是I49Q15,乘法结果会取高32位,所以就是132Q0,所以结果是Q0

  • 您的意思是,乘除法得到的Q格式都是按照=号之前的格式取的吗?

    v.Speed = _IQdiv(v.SpeedScaler,v.EventPeriod); \
    \
    /* Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q*/ \
    v.SpeedRpm = _IQmpy(v.BaseRpm,v.Speed);

    这两个语句中v.SpeedScaler,v.EventPeriod为Q0格式除法得到v.Speed  Q_GLOBAL

    v.SpeedRpm   v.BaseRpm为Q0格式他们的输出是不是都可以按照=号之前格式选取。而它们的值直接进行乘除

  • 跟等号前后无关,跟你用的指令有关,你用IQMPY,那就是默认QGLOBAL,如果你用IQ15MPY那就是IQ15的输出。你需要看一下SPRC990 的6,3节

  • 你好,真是麻烦你,我看了,他的乘除法Q格式和括号里面的Q格式都一样,但是我的括号里面和外面不一样格式,怎么计算那,比如我的除法内部两个都是Q0格式而除法是Q_GLOBAL具体我怎么计算那,


  • v.SpeedRpm = _IQmpy(v.BaseRpm,v.Speed);那为什么我这个输出是Q0格式那_IQmpy是Q24格式

  • 不管你括号内是什么格式,结果之和IQ后面的N有关,你括号内是IQ0,但是用了IQmpy,那结果就会被转化成IQ24格式

  • 没那么复杂,就是以你的运算指令为基准,如果你的Q为Q_GLOBAL格式,乘法就相当于运算完再在结果上除以2^Q_GLOBAL,除法则是相当于再乘上2^Q_GLOBAL。

    假如不做这个动作的话,你看一下运算过程(以乘法举例)就是(A*2^Q_GLOBAL)*(B*2^Q_GLOBAL)=A*B*2^(2*Q_GLOBAL),结果明显就不是Q_GLOBAL的格式了。所以实际过程应需等效:(A*2^Q_GLOBAL)*(B*2^Q_GLOBAL)/2^Q_GLOBAL=A*B*2^(Q_GLOBAL),这样就对应上了。

    而只有你说的其他Q形式,就按照上面的方法代入直接算一下就能知道了。

  • 你的意思是v.Speed=_IQ(0.5)v.BaseRpm=1800  v.SpeedRpm = _IQmpy(v.BaseRpm,v.Speed)  的运算就是 _IQmpy(v.BaseRpm,v.Speed) =1800*0.5*2^24 /2^24  而  v.SpeedRpm=1800*0.5*2^24/2^24?  v.Speed = _IQdiv(v.SpeedScaler,v.EventPeriod) v.SpeedScaler=180 v.EventPeriod=1000  _IQdiv(v.SpeedScaler,v.EventPeriod) =

    180/1000*2^24