PICで分周してみる
2015-11-22
昨日は穏やかな日和りの中、ピアノの発表会を観に行きました。毎年11月の行事ですがどういうわけか雨降りの日が多く、昨年に続いての2年連続の好天は珍しく、主催者の身内としては嬉しい限り
帰路は家族で食事をして帰宅・・・と、こう書くと、ヘッポコ工作やら実験やらはやっていないように思うのは素人の浅はかさ(はぁ
)。
実はまたしても横道に誘われ、発表会に出かける前に妙な実験回路をブレッドボードに仕込み、夜遅くからプチ実験を開始しました。
昨年のハムフェアで格安入手した12.8MHzのTCXO(コスモウェーブさんで、今でも売っています)を、部品箱を漁っているときに見かけたのが数週前・・・そして、aitendoの店頭で「99円」で売っていたLCDも見つけてしまい、「ちっこい周波数カウンタを作ろうか」というダンジョンに行き着きました。周波数カウンタは、このブログにも度々登場する「赤い奴」や「中古を治した奴」があり、特に後者は精度もそこそこにチューンしてありますから当面は要らないんですが、卓上の小さなものを用意するの一興・・・と悪魔が囁くわけです
そこで、折角のTCXOから「1Hz」を得るための分周について試してみました。PICは、直前の実験にも使ったPIC16F1823を使用しました。

PICで正確な周期を刻む方法は様々ですが、クロック周波数の「切れの良さ」によって工夫が必要になります。今回の実験では先にクロック周波数が12.8MHzと決まっていますから、PICの方で「1280万分周」ができれば良いわけですが、これが案外大変
また、できるだけソフトの介在を少なくして余計な誤差発生を防ぐためには、分周比を「2の倍数」になるようにし、割込処理内に分岐命令が不要なようにするのが常套手段です。
まず、クロックはPICの外部クロックモード(ECH)を使いました。これでPIC自体が12.8MHzで動作。その上で、Timer1を周期カウンタで動作させるため、CCP1モジュールのコンペアモードで実現する「特殊イベントトリガ」を使用し、カウンタ動作として「50,000分周」としました。分周数を以下にまとめておきます。
・Timer1にはFosc/4でクロックを供給・・・4分周
・Timer1のプリスケーラを使用・・・8分周
・Timer1を周期カウンタ動作・・・50,000分周
∴ 1,600,000分周
これで、割込周期が1/8秒・・・8Hzまではハード・ロジックのみの正確な分周ができます
肝心の割込処理は、以下のようになりました。
RA0への出力にはビット処理を使わないことで分岐処理を嫌っています。また、出力をDuty比50%の波形にするため、カウンタ「cnt」の2ビット目を利用しました。コンパイル結果を確認してみましょう。

ビット合わせのシフト命令「cnt >> 2」のところでループを構成していますが、毎回2回固定ですから問題はありません。その他には分岐命令はありませんので、これで必ず「割込発生からPORTA出力まで」(上のリストの608行まで)のステップ数が毎回同じになります。
さぁ、これを「チューン済みの中古カウンタ」で測定してみました。勿論、ブレッドボード上のTCXOの周波数微調整は済ませてあります。

このカウンタの「周期測定モード」で10秒間の測定を繰り返しています。分解能は約67nsですから、小数点以下8桁目・・・スナップに写っている連続した「0」の最下桁は誤差含みになります。周辺温度はあまり気にしていませんでしたが、21℃から22℃くらいの間を行ったり来たり・・・それでも最下桁がたま~に動く程度であり、剥き出しのブレッドボードの上で発振している割にはかなり安定していそう。こうなると、周波数カウンタへの応用が確実に近づいてしまい、またしても「大物作り」がお預けになってしまいそう
お休みはもう一日あります。明日は外出予定もありますが、その他の時間はこの実験の続き・・・周波数カウンタの構想でも練りましょうかね


実はまたしても横道に誘われ、発表会に出かける前に妙な実験回路をブレッドボードに仕込み、夜遅くからプチ実験を開始しました。
昨年のハムフェアで格安入手した12.8MHzのTCXO(コスモウェーブさんで、今でも売っています)を、部品箱を漁っているときに見かけたのが数週前・・・そして、aitendoの店頭で「99円」で売っていたLCDも見つけてしまい、「ちっこい周波数カウンタを作ろうか」というダンジョンに行き着きました。周波数カウンタは、このブログにも度々登場する「赤い奴」や「中古を治した奴」があり、特に後者は精度もそこそこにチューンしてありますから当面は要らないんですが、卓上の小さなものを用意するの一興・・・と悪魔が囁くわけです


PICで正確な周期を刻む方法は様々ですが、クロック周波数の「切れの良さ」によって工夫が必要になります。今回の実験では先にクロック周波数が12.8MHzと決まっていますから、PICの方で「1280万分周」ができれば良いわけですが、これが案外大変

まず、クロックはPICの外部クロックモード(ECH)を使いました。これでPIC自体が12.8MHzで動作。その上で、Timer1を周期カウンタで動作させるため、CCP1モジュールのコンペアモードで実現する「特殊イベントトリガ」を使用し、カウンタ動作として「50,000分周」としました。分周数を以下にまとめておきます。
・Timer1にはFosc/4でクロックを供給・・・4分周
・Timer1のプリスケーラを使用・・・8分周
・Timer1を周期カウンタ動作・・・50,000分周
∴ 1,600,000分周
これで、割込周期が1/8秒・・・8Hzまではハード・ロジックのみの正確な分周ができます

void interrupt int_divider() { cnt = (cnt + 1) & 0x07; // 8分周 PORTA = (PORTA & 0xfe) | (cnt >> 2); // RA0に出力 CCP1IF = OFF; } |
RA0への出力にはビット処理を使わないことで分岐処理を嫌っています。また、出力をDuty比50%の波形にするため、カウンタ「cnt」の2ビット目を利用しました。コンパイル結果を確認してみましょう。

ビット合わせのシフト命令「cnt >> 2」のところでループを構成していますが、毎回2回固定ですから問題はありません。その他には分岐命令はありませんので、これで必ず「割込発生からPORTA出力まで」(上のリストの608行まで)のステップ数が毎回同じになります。
さぁ、これを「チューン済みの中古カウンタ」で測定してみました。勿論、ブレッドボード上のTCXOの周波数微調整は済ませてあります。

このカウンタの「周期測定モード」で10秒間の測定を繰り返しています。分解能は約67nsですから、小数点以下8桁目・・・スナップに写っている連続した「0」の最下桁は誤差含みになります。周辺温度はあまり気にしていませんでしたが、21℃から22℃くらいの間を行ったり来たり・・・それでも最下桁がたま~に動く程度であり、剥き出しのブレッドボードの上で発振している割にはかなり安定していそう。こうなると、周波数カウンタへの応用が確実に近づいてしまい、またしても「大物作り」がお預けになってしまいそう

お休みはもう一日あります。明日は外出予定もありますが、その他の時間はこの実験の続き・・・周波数カウンタの構想でも練りましょうかね

- 関連記事
-
- OCXOを半分直す
- ハートレー型水晶発振と戯れた話
- PICで分周してみる
- 中華DDSのノイズ軽減中・・・
- 失敗LOを復活させよう
コメントの投稿
レベルの基準について
いつも参考にさせていただいております。
周波数の校正は基準を入手し易いのですが、SSGの出力レベルやスペアナのレベル表示の校正に利用できる基準って何かアイデア有りませんか?
お金をかければ校正手段は有りますが頻繁に依頼するのもしんどいもので、自分で任意のタイミングで確認できるようにしたいと思う次第です。
周波数の校正は基準を入手し易いのですが、SSGの出力レベルやスペアナのレベル表示の校正に利用できる基準って何かアイデア有りませんか?
お金をかければ校正手段は有りますが頻繁に依頼するのもしんどいもので、自分で任意のタイミングで確認できるようにしたいと思う次第です。
「自分基準」なら・・・
tomさん、コメントありがとうございます。
自分も同じ悩みを抱えています(^^; 例えば、SSGなどの出力電力なら、校正直後に自前のミリワット計(拙ブログにも何度か登場しているショットキーダイオードで作ったような奴)で測っておき、任意のタイミングでチェックしたりはできそうですね。そして、これを信用してスペアナの校正ができるかも・・・。
tomさんがもしアマチュア無線家であれば、JARLの測定サービスを使えば(会費は要りますが)、測定自体は無料で、ある程度のことはやって貰えるかも・・・。
自作の範疇では、絶対値に対してどう折り合うか・・・今は、前出の自作ミリワット計やAPB-3の表示を「自分基準」として納得しています。
参考にならず、申し訳ない・・・懲りずにまた寄って下さいm(__)m
自分も同じ悩みを抱えています(^^; 例えば、SSGなどの出力電力なら、校正直後に自前のミリワット計(拙ブログにも何度か登場しているショットキーダイオードで作ったような奴)で測っておき、任意のタイミングでチェックしたりはできそうですね。そして、これを信用してスペアナの校正ができるかも・・・。
tomさんがもしアマチュア無線家であれば、JARLの測定サービスを使えば(会費は要りますが)、測定自体は無料で、ある程度のことはやって貰えるかも・・・。
自作の範疇では、絶対値に対してどう折り合うか・・・今は、前出の自作ミリワット計やAPB-3の表示を「自分基準」として納得しています。
参考にならず、申し訳ない・・・懲りずにまた寄って下さいm(__)m
自分基準もいいですね
なるほど、最も信頼できる時に別の受動構成の機器で記録しておいて、増減を観るのが手軽でいいですね。手元に50μAの電流計が有りますので、さっそく作っておこうと思います。
絶対値を表明しなければならないシーンはあまり無いので自分が使い慣れた標準値からの差を取れば済んでしまいそうです。
JARLはずいぶん前に切れていますので利用できませんし、持ち込むのも大変なので遠慮しておきます(笑)
どうもありがとうございました。
絶対値を表明しなければならないシーンはあまり無いので自分が使い慣れた標準値からの差を取れば済んでしまいそうです。
JARLはずいぶん前に切れていますので利用できませんし、持ち込むのも大変なので遠慮しておきます(笑)
どうもありがとうございました。
Timer2で
Timer2で256分周しといちゃあかんの?Focs/4だから1024分周が最低か
ただのフリーランだからいけるような気がするよ
それか、Timer0の16bitで49999カウントにして、余りをTimer2で24xカウントするとか
同期カウンタなんだからGateをデューティ50%にするのはもったいなくね?
ただのフリーランだからいけるような気がするよ
それか、Timer0の16bitで49999カウントにして、余りをTimer2で24xカウントするとか
同期カウンタなんだからGateをデューティ50%にするのはもったいなくね?
DUTY比50%が必要なわけ
とぉちゃん、お久しぶりのコメアリです。
はい、仰る通り、他のタイマーで補助分周すればOKですし、timer2なら上手く作ることができますね。
実は、timer2でこの記事と同じ仕様のものは作ってあります(^^ゞ
今回のtimer1へのこだわりは、単にCCPモジュールを使ってみたかったのに加え、どうせなら、1つのタイマーで片づけてみようと思ったからです。
また、DUTY比50%にしたかったのは、外部のNANDゲートを正確に1秒でON/OFFしたかったからです。
今後も遠慮なく、コメカキコして下さいm(_ _)m
はい、仰る通り、他のタイマーで補助分周すればOKですし、timer2なら上手く作ることができますね。
実は、timer2でこの記事と同じ仕様のものは作ってあります(^^ゞ
今回のtimer1へのこだわりは、単にCCPモジュールを使ってみたかったのに加え、どうせなら、1つのタイマーで片づけてみようと思ったからです。
また、DUTY比50%にしたかったのは、外部のNANDゲートを正確に1秒でON/OFFしたかったからです。
今後も遠慮なく、コメカキコして下さいm(_ _)m