標記のPIC16F1705を秋月電子で購入してみました。

アマチュア無線家に応える?、アナログ機能が満載の面白そうなPICです。
まずは強化された8ビットDACを使用してみたいと思います。
ついでに、内蔵OPアンプも電圧バッファとして使用します。
これにより、以前実験的に作製したPIC12F1822低周波発生器の実用版として、
波形精度の向上および操作性も考慮してみます。
目標としては、50HZ~5KHZ程度で、そこそこきれいな波形が出力できれば
AFジェネレータとして使えるかな、と言った所です。

参考文献 PIC16F1705データシート MicroChip

↑ ①14ピンPIC用汎用基板



↑ 汎用モジュール ②と④
左側はロータリーエンコーダ・モジュール
右側が8MHZ水晶モジュール



↑ ③ボリウム・モジュール?
と言うより、配線しただけ・・・



↑⑤8桁7セグ表示モジュール
Aitendoで購入したもの



↑ 各モジュールを接続
この状態でデータ取りしました
汎用基板を利用した、実験回路の準備

①14ピンPIC用汎用基板
②8MHZ水晶モジュール
③汎用Bカーブボリウム
④ロータリーエンコーダ(RE)基板
⑤8桁7セグモジュール(Aitendoのモジュール)

上記の汎用基板?を用いて実験回路としました。
これだけで、概ねプログラムができてしまいます・・・
ブレッドボードでPICの動作実験するのは面倒くさいのでやめました・・・
各ピン用汎用基板の方が楽ちんです。
この汎用基板によるバラック状態で、まずはデータの作成となりました。
これが・・・地味に大変でした・・・ (*_*)
まずはDAC制御ルーチンを慎重に作成しました。
これがかわるとデータも変わるので、一度作るとそのままとなります・・・
実は、1回一通りデータ取りした後、必要あってDACルーチンを変更したら1命令増加、
その結果、全般的に数HZ変化、結局再データ取りの憂き目に・・・
データ以外のプログラムは、あまり大した事は無いです・・・Hi

AF-DDS部分が概ね出来上がったので、あとはLPFの実験、
高度な低周波フィルタは設計ができないし、完ぺきな正弦波の必要性も無いので、
ただのRCフィルタを2段にしただけです。
超簡単な回路なので、色々定数を変化させて実験してみました。
これはブレッドボードで試作しました。
表示用に5桁の7セグモジュールを製作するつもりでしたが、やめました・・・
以上予備実験の方法でした。

結果
ボリウム・ADCの組合せによる周波数コントロールはボツになりました。
操作性に関しては、REの足元にも及ばない事が、実験で判明した為です。
REによるコントロールは、思いの外使い勝手が良く、これ1本で行う事としました。
これで、広い周波数範囲を比較的スムーズに操作できます。
使用REはノンクリックタイプで、クリック有は使い勝手が悪くダメでした。



今までのプログラム・ツールが使えない・・・

今まで使用してきた、MPLAB IDEはPIC16F1705サポートしていません。
そして、PICKIT2も16F1705をサポートしていません。
よって、プログラミングはMPLAB X IDEを使用しています。
このMPLAB X IDEは、当然アッセンブラでの開発が可能なのですが、
C言語で開発するのを標準として想定している感じです。
当局のようなアッセンブラでポチポチ楽しみたい個人は、とっつきずらいです。
エディタからして、少々設定変更が必要です。
デバッガのWATCH窓で変数(GPR)が登録されないのに、しばらくハマりました・・・
また、ウインドウが半固定なのも頂けないです (ーー;)
MPLAB IDEのように自由に機能ウインドウが開けるようにしたいができない。
MPLAB IDEサポートを復活して欲しいと切に思います。(追記1)

書込みはPICKIT3使用となりました。
ライタソフトは、MPLABX IPEを使用しています。
PICKIT3からの電力供給としても、書込み時に電力不足と言われてしまいます・・・
ライタからの電力供給はOFFにして、ポータブル電源からVDDを供給しています。
当初は汎用CPU基板に装着したまま、ICSPピンから直接書込みをしていました。
当局内で使用するPICの種類は多くないので、各ピン数用のCPU基板を作った方が
ブレッドボードより効率が良いです。
しかし、ターゲット基板に直接書き込むのは、USBやICSPケーブル等、
太目の配線取り回しが意外と鬱陶しいのでやめました・・・
工作テーブルが部品等で散らかっているのが原因です
結局、PICを基板から着脱し、秋月の汎用書込みキットにPICKIT3を直接接続し
MPLABX IPEを使用して焼いています。
秋月のPICKIT2互換ボードと同じ書込みスタイルですが、
結局この方が当局のパソコン及び工作環境には合っています。

追記1) MPLAB'X IDEについて
その後の悪戦苦闘の末、少しずつ使い方が分かってきました・・・
機能ウインドウは固定から外す事が簡単に出来る事が判明
デバッガのWATCHやVARIABLEウインドウの使い方はちょっと癖がある様で、
アッセンブルを「アブソリュート」にしても、GPRメモリの定義はできる時とできない時が
ある様で、その正確な線引きがイマイチよく判っていませんです・・・
設定さえできれば、デバッグに絶大なる効果があります。
エディタでは、マウスのホイールを押したまま回すと、文字の大きさが即座に変化する。
これは当局の様な年代以降の人間にとって、とてもありがたい機能です。
初期設定ではTABが使えず、スペース地獄だったのは、他HP様の情報から解決。
書込みでは、Pickit3との相性は良く、即座に書込み、実機上デバッグが出来、便利。
当局レベルのプログラムでは、実機上のデバッグは殆ど必要なく、エミュレータ上での
デバッグで事足りる事が殆どです。
しかし・・・まだまだ不明点がてんこ盛りです・・・ (-_-;)


↑ DAC出力 250HZ TBL=128



↑ DAC出力 1000HZ TBL=64



↑ DAC出力 5000HZ TBL=32



↑ DAC出力 10000HZ TBL=16
PIC16F1705のアッセンブラ プログラミング

基本的にはPIC12F1822を使用した低周波発生器と同じ構成です。
メインルーチンはロータリーエンコーダ(RE)を使用した、アップダウンカウンタです。
そのカウント値から各種設定データを読み込みます。
DAC制御は割込みルーチンに存在し、タイマ0割り込みで飛んできます。
データはDAC用に4種類、タイマ0を含む総合組合せ用に1種類、計5種類あります。
DAC用のデータは1周期の時間軸分解能に合わせで用意、
TBL128 1周期を128分割・・・約3KHZまで生成可能です。
TBL64、1周期を64分割・・・約6KHZまで生成可能、
TBL32、1周期を32分割・・・約12KHZまで生成可能です。
TBL16、1周期を16分割・・・25KHZまで生成可能です。
これらのデータは割込みルーチンから逐次取得されます。
総合組合せデータは、2元配列データ形式で、1行あたり4バイトとなっています。
これは、TMR0値、周波数下位、周波数上位、TBL選択/プリスケーラ設定値で、
これをREカウント値から呼び込み、タイマ0とDAC制御、周波数表示を、
PIC1個で行えるように考えてみました。

周波数表示は3線シリアル制御の8桁7セグLEDで、比較的安価な上に、
明るさ調節も可能な、AitendoのMAX2719使用モジュールです。
文字が小さ目ですが、DFR0090と比較して消費電力が遥かに少なく、
電池駆動に何とか耐えられます。
モジュール制御中に割り込み発生しても、概ね問題無いのもGoodです。
実際の生成周波数表示には最大5桁しか使用しないので、
8桁目は使用TBL、7桁目は使用LPFを数値で表す事にしました。
6桁目は常にブランクとなります。
輝度は電池駆動のため、7/32としていますので、ちょっと暗めです。
このモジュール制御については当局HP別項をご参照ください



ロータリーエンコーダ制御

生成周波数を選択する、16ビットの基準カウンタ「FDAx」を生成します。
出力は変数「FDA0」を下位ビット、「FDA1]を上位ビットとした16ビットカウンタを構成、
これをアップ・ダウンカウントしています。
実験当初はボリウムとADCで行ったのですが、変化がクリチカルでボツ、
ロータリーエンコーダの方が具合が良かったで、こっちを採用。

ソースコードの「RE_DATA」サブルーチンを参照して下さい。
動作詳細はコメント欄に記してあります。
REA,REB2端子間のパルス位相差から回転方向を判別しています。
このカウンタ値から総合組合せデータを呼び出し、DACを駆動します。
頻繁に割り込みが掛かっても、カウントには大きな影響は無い様です。
ADCルーチンは残っていますが、実験段階で使用したまま放置されています・・・



低周波DDSデータ生成部

1行4桁(4バイト)の配列データ行番号(0~390まで)と、
基準カウンタ「FDAx」値とをシンクロさせています。
FDAxは0~65535までカウントできますが、実在データは390までです。
配列データは10HZ~25KHZまでを391個に分割しています。
PIC16F1705はメモリ容量が結構大きいので、まるで使いきれません、
データ部分はプログラムエリアの2ページ目(800H~)に配置していますが、
そんな無駄遣いしても、余りまくっています・・・
データを大量作成すれば良いのは分かっているが・・・
そんな気力も時間も無かったです・・・ (-_-;)

サブルーチン「GET_FRD]
これが配列データをアクセスする所です。
「FDAx」値から間接アドレス値を計算し、FSR0を設定、アクセスします。

サブルーチン「SET_TBPS]
上記の読み込んだデータから、タイマ0とDACを設定します。
また、表示用生成周波数やLPF設定も用意されます
この2つのルーチンが今回のプログラムの内容的な主構造となります。

データの作成は8MHZクリスタルと4XPLLで32MHZのシステムクロックを生成、
TMR0値とプリスケーラを変化させてDACを駆動、その出力を記録しています。
生成周波数の1周期分解能は、128、64、32、16分割と4種類用意
それぞれの分解能/TMR0値/PS値で実測生成周波数を記録しています。
その2000個に及ぶ記録データの中から391個をセレクトしています。
実は・・・破棄分を含めると、4000個程データ取りしています・・・ (-_-;)
実測でなくとも、計算でも概ね同じデータが取れます。
アッセンブラ ソースファイル

 16f1705_afgen02.asm

上記ソースファイルをMPLABX IDEで
適当なプロジェクトを作って、
アッセンブルして下さい。
その後Pickit3で書き込んで下さい


HEXファイル

 16F1705_AFGEN02.X.production.hex

上記HEXファイルをMPLAB'X IPEで
Pickit3を使用して書き込んで下さい

使用したツール類
 MPLAB XIDE
 MPLAB XIPE
 PicKit3



参考

割込み処理ルーチンソース ver1.0

INT
 movlb 02h ←START
 incf DCX,F
 movf DCX,W
 addwf FSR1L,F
 movf INDF1,W ;2sys
 movwf DAC1CON1 ←DAC書込み
 movf DCM,W
 xorwf DCX,W
 btfsc STATUS,Z
 clrf DCX
 movlb 0h
 movf DCR,W
 movwf TMR0 ←TMR0書込み
 bcf INTCON,TMR0IF
 retfie

DAC入力データテーブル

前回の実験では1周期を32分割した場合のデータのみでした。
今回は、16分割、32分割、64分割、128分割の4つのテーブルを用意。
もちろんデータが結構重なります。

用意したデータの計算式は、下記です。
 Y = 127SIN(X-90)+127
ここで、
 Y はDACへの入力値
 X は「度」(degree)で、最小値は360/128度と言う事になります。 

8ビットDAC、128分割波形はさすがに綺麗です・・・ \(^o^)/
LPFを通すと、文句の付けようがありません。
ただし、高域が出せません・・・
16分割波形は予想通り、がっかり波形です・・・
ただし、高域性能は良く、25KHZまで生成可能です。



生成周波数の計算について

(1)割込みルーチン 15インストラクション(INDFは2cyc) 0.125us/cyc

 A) 割り込みレイテンシ
  ↓ 3cyc
 B) START
  ↓ 7cyc A+B=10cyc=1.25us
 C) DAC書込み DACW1と略す
  ↓ 7cyc(0.875us)
 D) TMR0書込み(不感2cyc後にカウント開始)
  ↓ 255-TMR0値+2(cyc)
 E) その他処理(生成時間には関与しない)
  ↓
 F) TMR0カウントアップ(TMR0割り込み発生)
  ↓
 G) 割り込みレイテンシ
  ↓ 3cyc
 H) START
  ↓ 7cyc
 I) DAC書込み DACW2と略す

(2)生成周波数計算方法 (詳細は別記資料詳細を参照してください)

ここで、生成周波数は、
 ((DACW1~DACW2)×周期分解能)の逆数となる

例1) 250HZの時、TMR0=18H(24)、TBL=128、PS=1/1
   TMR0カウントは、255-24=231カウントで割り込み発生
   C~D=7cyc、D~F=233cyc、G~I=10cyc
   よってDACW1~DACW2の時間は、
   7+233+10=250cyc=31.25us
   TBL=128なので、
   31.25us×128=4000us → 250HZ

例2) 1000HZの時、TMR0=95H(149)、TBL=64、PS=1/1
   TMR0カウントは、255-149=106カウントで割り込み発生
   C~D=7cyc、D~F=108cyc、G~I=10cyc
   よってDACW1~DACW2の時間は、
   7+108+10=125cyc=15.625us
   TBL=64なので、
   15.625us×64=1000us=1ms→ 1000HZ

例3) 5000HZの時、TMR0値=E0H(224)、TBL=32、PS=1/1
   TMR0は255-224=31カウントで割り込み発生
   C~D=7cyc、D~F=33cyc、G~I=10cyc
   7+33+10=50cyc=6.25us
   TBL=32なので、
   6.25us×32=200us → 5000HZ

↑ 実機メイン基板回路図



↑ メイン基板を製作



↑ 出力波形 250HZ



↑ 出力波形 1000HZ



↑ 出力波形 2500HZ



↑ 出力波形 5000HZ



↑ 出力波形 10KHZ



↑ 出力波形 25KHZ
実機の作製

メイン基板は秋月のBタイプ穴あき基板使用です。
ローパスフィルタや電源部も載せますので、大きめの基板を使用しました。
消費電流は100mA以内を想定していますので、小さい放熱器を使用しています。
電源投入時に一瞬、想定値の2~3倍程大きく電流が流れます。
これはLEDモジュールの、立ち上がり時のテストモードによるものと思われます。
通常時は50~80mA程度と思われますが、LEDを程よく暗くすると良さそうです。
電源は単三電池6本9Vを想定しています。
これを7805で5Vに落としますので、効率は悪いです。
LPFはダイオードを使用したアナログスイッチで、3回路を切り替えます。
これにより、低域でも波形の滑らかさを確保します。
もちろんPICが切り替えます。
基板に余裕があるので、ICSP端子もとりあえず付けました。
DATA、CLOCKラインに、LPF制御のC・R類がぶら下がっていますが、
MPLABX IPE+Pickit3にてデバイス認識・書込みを確認しています。

ケースは秋月の、ちょっと大きめのプラケースを使用しました。
これに電源スイッチ、ロータリーエンコーダ、出力ボリウム、
そして7セグLEDを取り付けます。
いい加減な筐体ですが、自分用ですので問題無です・・・ (^_^;)

調整
これは出力周波数をカウンタで見ながら、X’TALのトリマを調整
校正可能周波数
 1000HZ、2500HZ、5000HZ、10000HZ、12500HZ、20000HZ



最終仕様

発生周波数範囲  10HZ~20KHZ
実用周波数範囲  20HZ~5KHZ(自己判断ですが・・・)
生成波形時間軸分解能
 10HZ~600HZまで128分割/周期
 600HZ~2.9KHZまで64分割/周期
 2.9KHZ~5KHZまで32分割/周期
 5KHZ~20KHZまで16分割/周期
ローパスフィルタ切替
 700HZ以下は低域用LPF
 700HZ~5KHZまで中域用LPF
 5KHZ以上は高域用LPF

発生周波数変化量
 10HZ~110HZまでは1HZ単位
 110HZ~910HZまでは10HZ単位で近似値
 910HZ以上は生成される実周波数を表示

 当局は10KHZ以上は聞こえません・・・ (-_-;)
 実際は、無線機の製作・調整には50HZ~5KHZあれば十分です。
 生成波形も5KHZ以下に留めておく方が綺麗です。
 この辺の味付けは、当局個人の趣味が入っております。
 目的等に合わせて、データ変更を行うと良いと思います。

消費電流 約60mA~70mA
 LEDモジュールの輝度を7/32に設定しています。
 表示セグメントが多いと消費電流が多くなります。
 ただし、起動時に一瞬フルセグメンド分が流れます。
 輝度を15/32に設定の場合、約100mAとなります。
 好みに合わせて、ソースファイル内設定値を変更してください。

考察・補足事項

フィルタを通すと128分割、64分割の波形は、きれいなサイン波になります。
16分割の波形はフィルタを通しても、ちょっといびつです。
しかし、LPFの減衰域である10KHZ以上では、何とかサイン波らしくなってきます・・・
この分解能を使用する帯域は、おまけ程度と考えた方が良いかも・・・
オシロで観察していると、X軸分割切替がはっきり分かります。
LPFの切替は、あんまりわかりませんでした。

周波数表示精度と周波数生成に関しては結構悩みました・・・
低域では1HZあるいは10HZ単位での周波数表示精度が取れますが、
中域以上では10HZ単位での切り良い生成ができず、
無理に四捨五入したのでは、表示周波数精度が取れません。
苦し紛れに、表示周波数精度を上げるため、生成実周波数を表示としました。
よって、好きな周波数を高精度で生成出来る訳ではありません。
この辺が本物のDDS?との大きな性能差となっています。
この辺の理由は、CPU動作周波数、割込みルーチンの処理速度、その他との
兼ね合いがあると思います。
実際、今回のCPU速度やプログラム等での、生成データを見ると、
ある周期で高精度な切り良い周波数を生成します。
と言う事は、とりあえずTBLデータの種類を大幅に増やすと、胸を張ってDDSと
言えるような分解精度で生成可能かもしれません。
その場合は、ハードウエアの変更無で実現できるかな。

現時点では、出来る限り時間軸分解能の高い方を使用しようとすると、
反って周波数分解能が低くなってしまします。
その辺の味付けが面倒な所で、結果的にこの様な表示仕様としてみました。

このままの構成でツートーン波形を再現できるかなとは一瞬考えましたが・・・
時間管理や当局の技術の低さ、自分時間が少ない等の問題でボツ
その際は2CPU構成の方が簡単そうかな?・・・



追記 2017年07月13日

 このプログラムで使用しているDAC用設定データをまとめました
 MS-WORDで書いてあります。

 8ビットDAC用設定データおよび解説

戻る  実験・製作の記録TOPへ戻る