jfpoilpretの受け入れられた回答は非常によく書かれており、完全に有効であり、99%のケースでは、彼が説明するとおりに行います。彼のソリューションは定義されたパラメーターの範囲内にあるため、非常にうまく機能するはずです。しかし、「非常によく」より優れている点は何ですか。完璧!結局のところ、問題は正確な値を生成することです。ほとんどの場合(間違いなくすべて)、十分に近いことが適切であり、1秒を1秒にする必要があるときに時計として何かを処理する場合でも、継承された部分の欠陥に苦しむ必要があります。
私が提案することは常に可能であるとは限りません。場合によっては可能ですが、この場合よりもはるかに手間と労力がかかります。それはケースバイケースで依存する価値がありますか?私の目標は、主に、ややフリンジのケースでより良い将来の参照の代替を示すことです。これは、エレクトロニクスの経験があまりない初心者のArduinoユーザーを対象に書かれています。
より進んだ人にとっては、これはおそらく冗長すぎて、だまされて見えるでしょう。しかし、私は、それらの同じ人々はおそらくすでにそれを知っていて、この答えを必要としないと信じています。これは、すべてのマイクロコントローラー、すべてのメーカーとアーキテクチャにも当てはまります。しかし、他のマイクロコントローラーについては、正しいデータシートを調べて、適切なレジスターとプリスケールの名前と値を見つける必要があります。
あなたのケースでは、特定の周波数が必要ですが、その良い点は、正確に56 kHzが実際に非常に簡単に実現できることです(パーツの実際的な欠陥は数えません)。これも完璧な例です。
信号の生成は、jfpoilpretでよく説明されているように、マイクロコントローラーのタイマーとクロックソースに依存します。彼の答えは、1つの視点のみの問題を扱っており、それはタイマーをいじっています。しかし、クロックソースをいじることもできますが、相乗効果とすばらしい結果の両方を実現することもできます。環境のパラメーターを変更することにより、この場合はシステムをハッキングし、クロックソースを置き換えることで、特定の問題にはるかに簡単かつ簡単に対処できます。
まず、ピンの状態を切り替えるため、信号周波数の2倍のISRを実行する必要があります。これは毎秒112,000回です。すでに指摘したように、56,000と16,000,000はうまく加算されません。信号周波数またはタクト周波数を変更する必要があります。ここでは、不変の信号周波数を扱い、より良いクロック速度を見つけましょう。
ゼロを追加するだけであり、この種の計算はほとんどの人にとって最も単純であるため、56 kHz(または112 kHzですが、実際には同じです)の1桁以上大きいクロックを選択するのが最も簡単です。残念ながら、この世界のすべては何かとのある種の妥協です。すべての値が機能するわけではありません。
最初の例は、タクトジェネレータの速度が低すぎる場合です。
56,000 Hzのクロックを選択した場合、サイクルごとにISRを呼び出す必要があり、他には何もできないため、何もできません。それは全く役に立たない。10倍速い速度(560 kHz)を選択した場合、9(タイマーが最大値に到達するための10サイクル-ISR関数を呼び出すための1サイクル)マイクロコントローラーサイクルで作業が行われますが、これでは十分ではありません。多くの場合、より多くの計算能力が必要になります。
一方、あまりにも大きい値を選択した場合、56 MHzとなるため、マイクロコントローラーはそれを使用できません。速すぎます。そのため、ショップで最大の価値を選択するだけでは、それを削減することはできません。
元のArduino Uno R3は16 MHzのストッククロックを備えているため、動作が遅いことが保証されているものはすべて低速です。56 MHzより大きく16 MHzより低い次の値は5.6 MHzです。これにより、50サイクルごとにISRを呼び出すことができ、完璧な112,000 Hzのタイマー周波数が作成されます。そして、信号は正確に56 kHzになります。ISR呼び出し間でプログラムを実行するために49 MCUサイクルがありますが、それでも元のクロックの速度の約1/3です。112をベースとして使用し、11.2 MHzクロックを使用すると、ストックの16 MHz共振器の約2/3が得られます。ISR関数は100サイクルごとに呼び出され、完全な56 kHz信号を生成します。
ただし、これらの値には2つの大きな問題があります。
最初の問題はニーズによって大きく異なります。見つけやすいレジスタ値(OCR iirc)を使用する正確な信号周波数を取得するには、最大計算能力の約1/3(11.2 MHzを使用)を犠牲にします。あなたはそれで大丈夫かもしれませんし、そうでないかもしれません。
2番目の問題は、ハードショートッパーです。値を見つけるのは非常に簡単ですが、製造されたクロックソースとして存在しないことがよくあります。これは、5.6 MHzと11.2 MHzの両方が欠けているFarnellの共振器Webページです。
これを回避するには、利用可能な共振器の値を調べて、正確に必要な値を生成するために使用できる他の何かを見つけます。56を4で除算すると、14が得られ、幸いにも14 MHzの共振器があります。これにより、速度とパワーが大幅に向上し、レジスタ値を簡単に見つけることができます。1秒あたり112,000回ISRを呼び出すには、10進数の124または16進数の0x7Cの値をOCRレジスタに入れる必要があるため、ISRを呼び出すために124サイクル+ 1をカウントすると、目的の完全な値が得られます。
NB
- ISR-割り込みサービスルーチン(これは、生成された割り込みでのみ実行されるコードです)
- プログラムの大きさは、メモリサイズによって異なります。それはクロック速度とは関係がなく、ISRを呼び出す頻度とは関係がありません。
マイクロコントローラーがプログラムコマンドで起動すると、カウンターが増加します。割り込みが発生すると、ISRが呼び出され、この値が特殊レジスターに格納されます。ISRコードが完了すると、プログラムカウンターの値がこの特殊レジスターから復元され、プログラムは、中断されたところから、あたかも発生しなかったかのように続行します。
私は非常に馬鹿げた例を挙げます。あなたが純粋主義者なら、私はあなたに警告します:鼻と目の出血が起こるかもしれません。
あなたがどこかからどこかに歩く必要があると想像してください。ステップバイステップのルート指示は、メインプログラムとそのコマンドです。歩いたり走ったりする速さは、「クロック速度」に依存しますが、ルートの指示には依存しません(前進30歩、左1ターン90進、前進10歩、右45進など)。常に同じです。 。小さな子供や貪欲な腐敗した地元の政治家があなたの靴をときどき解くと想像してみてください。これは、割り込みを生成するイベントです。次に、最後のステップの後で停止し、ひざまずいて靴をもう一度結びます。これはISRプログラムです。
次に、停止した場所から続行します。あなたは最初から始めません。世の中を気にせずにいつも歩くときは、一歩おきに靴を結ぶ必要があるとしても、気にしないでください。しかし、オリンピックで100メートルを走る(または空腹の肉食の捕食者から走る)など、時間の制約がある状態でそれを行うと、靴を止めて結ぶことは悲惨な結果をもたらす可能性があります。マイクロコントローラーも同様です。たとえコードが1行だけ実行されたとしても、低速ではありますが、プログラムは続行されます。速度をまったく気にしなくても問題ありません。他のタイマーに依存するアクションを使用するなど、時間に関連する何らかの操作を行う必要がある場合、干渉は非常に望ましくなく、問題になる可能性があります。
少ないほうがいいですね!クロックが速いほど良いとは限りません。遅いクロックのデバイスはかなり少ない電力を使用します。これは、バッテリ駆動デバイスの重要なポイントになる可能性があります。
必要なサイクルは、次の式から導き出されます:(
クロック速度/(プリスケーラ値*必要なISR呼び出し周波数))-1