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.

TMS320F28035: Question about IQmath calculate

Genius 3095 points
Part Number: TMS320F28035
Other Parts Discussed in Thread: C2000WARE

Dear team:

I want to calculate an equation:

dutybase=timbase*duty/100;

The scope of Duty: 10~50 (decimal system)

timbase is a fixed value: 4166 (decimal system)

Then I use the Q format to calculate, the code is as follows:

void Setduty(Uint8 duty)

{

Uint16 timbase,dutybase;

_iq q_base;

timbase=4166;

q_base=_IQ15div(_IQ14mpy(_IQ15toIQ(timbase),_IQ24toIQ(duty)),_IQ24toIQ(100));

dutybase=_IQ15int(q_base);

}

When I pass in duty = 10, the dutybase value is 13 (decimal). Normally, the value I get should be 4166 * 10 / 100 = 416. If I don't use the Q format:

dutybase=timbase*duty/100;

This results in a value of 0.

What is the cause of this problem?

Best regards

  • Your float computation needs a bracket, otherwise the division operation duty/100 will result in 0, hence overall result is 0. You need dutybase = (timbase * duty)/100;

    IQ part ->

    If the inputs to the equation are in decimal format, then that means they first need to be converted to the IQ format before being used. In your equation, you are assuming they already in a specific IQ format which is not the case. Think of your inputs as real floating-point type inputs i.e. 10.0, 100.0, 4166.0.

    Another issue I see is a mix up of different IQ types. Assuming your global IQ type is 15, why is there an IQ14mpy? Assuming it is 14, why is there an IQ15div?

    Another issue is the range of Duty 10-50. Assuming it is 50, 4166 x 50 = 208,300, which cannot be represented by IQ14 (14 fractional bits, 17 integer bits, 1 sign bit, Max integer represented is 2^17 = 131,072). Likewise, it cannot be represented by IQ15 either (15 fractional bits, 16 integer bits, 1 sign bit, Max integer represented is 2^16 = 65536). So you may want to consider the Global Q choice. IQ13 should work.

    Anyway, getting back to your specific example, let us assume Global Q is 15.

    We need _IQ(timbase) (this will be 4166 x 2^15 = 136,511,488)

    We need _IQ(duty) (this will be 10 x 2^15 = 327,680)

    We need _IQmpy(_IQ(timbase),_IQ(duty)) (this will be 1,365,114,880 after multiplying and right shifting by 15)

    We need _IQ(100) (this will be 100 x 2^15 = 3,276,800)

    Then we need q_base = _IQdiv(_IQmpy(_IQ(timbase),_IQ(duty)),_IQ(100)) (this will be 416.6 x 2^15 = 13,651,149)

    Finally, we need _IQ15int(q_base) (this will be 416).

    I tested this and it worked. You can also see with Q15, the value overflows when you increase duty to a number like 25.

    Thanks,

    Sira

  • "I tested this and it worked. You can also see with Q15, the value overflows when you increase duty to a number like 25." that 's ture. So it is the reason why I just want to change iq15mpy to iq14mpy, because that there will be no overflow, but the result is also wrong. If my duty varies from 25 to 50, how can my equation be used? Because of Q_ base=_ IQ15div(_ IQ15mpy(_ IQ15(timbase),_ IQ15(duty)),_ IQ15 (100)); will overflow. Now  the question is:

    Can I use an expression to convert my Q_base value  when my duty changes from 0 to 50 will not overflow?

    Thanks

  • You can reduce the Q for intermediate computations, then move back to the global Q once you have the final result. Please refer to the IQMath_Quickstart.pdf in C2000Ware, specifically the example present in the IQtoIQN description for how to go about this.

    The way you have applied it is not correct. You need to be consistent.

    Thanks,

    Sira