2016-10-07 6 views
1

私は1 Hzのパルスを生成する32.768 kHzの発振器を持っています。私はこのパルスを40MHzクロックで測定しています。私は、期待される結果と得られた結果を比較することによって、発振器の実際の周波数を測定しようとしています。Cでfloatまたはuint64型を使用しないで発振器周波数を計算する

  • 私が測定している期間を変更することはできません.1Hz(1s)でなければなりません。
  • float、double、またはuint32より大きい型は使用できません。
  • 整数部分の後ろの最初の桁も必要です(32768.1Hzなど)。だから、40008312の測定期間の結果がどのようにこのことができます327611.

    なります

    computedFreq = (uint32) ((float32)32768u/(((float32)measuredPeriod/(float32)40,000,000)/(float32)10u)); 
    

    または

    computedFreq = (32768*10*40,000,000)/measuredPeriod; 
    

制約がなければ解決策は次のようになります制約条件を満たすことで達成できるか?

+3

使用2 UINT32 'measurePeriod'の可能な範囲で何dHez – Garf365

+0

にUINT64と仕事をエミュレートするために? – user694733

+0

@ user694733 40,000,000 +/- 10,000。 –

答えて

2

あなたの問題は、測定範囲が40010000 Hzになり、20000 Hzの範囲のみに興味があるということです。したがって、解決策は範囲を制限することです。

2点を使用して線形補間で行うことができます。

  1. 2つの入力値を選択します。最小/最大ポイントが行う可能性があります:あなたの式を使用して

    inMin = 40,000,000 - 10,000 
    inMax = 40,000,000 + 10,000 
    
  2. 事前計算のそれぞれの出力値(ここでは値がラフな値であり、自分自身を計算する):あなたは、あなたのコード内で定数としてこれらを保存することができます。

    outMin = (32768*10*40,000,000)/inMin = 327761 
    outMax = (32768*10*40,000,000)/inMax = 327598 
    

    公式の性質上、最大値はどのように最小値よりも小さいかに注意してください。これは、以下のタイプを選択するときに重要です。

  3. 使用の両方以前のポイントを使用して結果を計算するために、線形補間:

    out = (in - inMin) * (outMax - outMin)/(inMax - inMin) + outMin 
    

    (outMax - outMin)がマイナスであるため、あなたは、このために符号付き整数を使用する必要があります。

    乗算の上限は(inMax - inMin) * (outMax - outMin)であり、これはint32に適合するはずです。

任意の2点を選ぶことができますが、乗算にあふれすぎるほど大きな値を生成しないものを選択する必要があります。また、ポイントがお互いに近すぎると、答えがあまり正確でない可能性があります。

余分な精度がある場合は、outMin/outMaxで10より大きい乗数を使用し、後で精度を上げるために丸めます。

+0

私は数式を補間の一般的な形式に変更しましたので、他の場所でも便利です。 – user694733

+0

私はそれを試して、あなたに戻って、提案をありがとう。また、32.768kHzオシレータの周波数が低いということは、1-HZパルスが1秒以上かかることを意味し、逆も同様です。 –

+0

@AlexandruCimpanu注記すると、重要なデータ型の編集を追加しました。これも符号なし整数でも可能ですが、必要がない限り追加しません。 – user694733

2

32768 * 10 * 40000000 = 3200000000 * 2^12に注意してください。

次のように周波数を近似するために、この事実を使用することができます。

computedFreq = (3200000000/measuredPeriod) << 12; 

UPDATE:

を私は39990000 <= measuredPeriod <= 40010000ことを理解しています。この制限の下で周波数を近似する

より良い方法は、次のようになります。

computedFreq = 327761-(measuredPeriod-39990000)/122; 
+1

私はそれがあまり役立つかどうかはわかりません。彼の値の範囲を考慮すると、整数計算しか使えないという結果が得られるのは、 '327680'と' 323584'です。 – user694733

+1

@ user694733: 'computedFreq'と' measuredPeriod'が整数であると仮定すると、**は**整数 - 数学です。唯一の可能な結果が「327680」と「323584」だとあなたが考えている理由はよく分かりません。 –

+0

問題は「3200000000 /(40000000-10000)= 80」と「3200000000 /(40000000 + 10000)= 79」という限られた範囲です。 – user694733

関連する問題