PIC 16F88のPUSH POPについて

久しぶりのPICネタである

ミッドレンジのPICである16Fシリーズには、データスタックが無い
プログラムスタックは8段(最近のF1シリーズは拡張されている)となり、ネスティングが8段までとなり、プログラムスタックは、ソフトで読み書きは出来ないのである

PICでプログラムを書いていると、WレジスタがPUSH/POP出来るればと言う妄想が浮かんで来る、ついては、PUSH POPマクロをでっち上げてみた

マクロを使う場合、コードの中に以下のデータを定義する
.
.
dstack Udata_shr  h’78’
dstack_area res     8
;dstack_sp res  1
;dstack_fsr res 1
;dstack_w res  1
;dstack_data res 4
.
.

内容は Fレジスタの78番地からスタック用として8バイトを確保している
貴重な8バイトなのに、スタック出来るバイト数は4バイトなのは、愛嬌である

ちなみに70H~7FHのFレジスタは共用メモリとして重要である
メモリバンクがどこに設定されていても、必ず読めるアドレス空間である
従って、ここにスタックデータを置くことになる
以下がマクロである

;—————————————-
;Memory addrerss 00h-FFh 対応 (bank 0,1 only)
;PUSHW
;Wレジをスタックする
;78h dstack_sp データスタックポインタ
;79h dstack_w W reg save
;7ah dstack_fsr FSR save
;7bh-7fh dstack_data 5 level stack data
;

dstack_sp equ      h’80’-8
dstack_fsr equ     h’80’-7
dstack_w equ      h’80’-6
dstack_data equ  h’80’-5
;

;例: PUSHW
;—————————————-
PUSHW macro
movwf dstack_w    ;Wreg save
movfw FSR
movwf dstack_fsr   ;FSR save

movfw dstack_sp
addlw dstack_data   ;W=stack data offset
movwf FSR              ;FSR (stack_data)+sp

movfw dstack_w
movwf INDF            ;W → stack_data

incf dstack_sp,F        ;stack_sp ++

movfw dstack_fsr
movwf FSR               ;restore FSR
movfw dstack_w       ;restore W
endm

;—————————————-
;Memory addrerss 00h-FFh 対応 (bank 0,1 only)
;POPW
;スタックからWにデータをセットする
;78h dstack_sp データスタックポインタ
;79h dstack_w W reg save
;7ah dstack_fsr FSR save
;7bh-7fh dstack_data 5 level stack data
;
;例: POPW
;—————————————-
POPW macro
movwf dstack_w      ;Wreg save
movfw FSR
movwf dstack_fsr     ;FSR save

movfw dstack_sp       ;W=stack data offset
addlw dstack_data     ;W=stack data offset
movwf FSR
decf FSR,F                  ;FSR (stack_data)+sp-1

movfw INDF              ;stack_data → W

movwf dstack_w         ;Wreg save
movfw dstack_fsr
movwf FSR                  ;restore FSR
decf dstack_sp,F           ;stack_sp —
movfw dstack_w          ;restore W
endm

 

 

MPLABX

<MPLAB X IDE の画面>

デバッグはマダである
従って利用するには、大変な勇気が必要となると思われる
当然であるが、サポートは何も無いのである

実は少し使って見たので有ったが、WレジスタのPUSH/POPのために、貴重なプログラムエリアを無駄に消費してしまうのである

画期的と思ったのは私の妄想であった
。゚(゚´Д`゚)゚。

直読型周波数カウンタの制作 要素開発編2

2つ目の要素開発項目は、16F88自体での周波数カウント方法である

ポイントは内蔵タイマをどの様に使って周波数数カウントし、限界値(最大測定周波数)が要求仕様に入っているかを確認する事である
LCDが動作しているので、周波数をカウント出来れば単体で、テストが出来る様になる
今回は、timer0とtimer1を試して比較してみた

PICではtimerと呼び名が付いているが、オーバフロー時または設定したカウンタ値に到達したら、割り込みが発生するフリーランカウンタである

入力に一定周期のバルスを入力すると当然タイマーとなるのである
入力周波数をカウントするのに、どのTimerが良いか検討した

1.timer0

16F88のtimer0は入力信号と内部クロックの信号が同期となっている

・入力はシュミットトリガでは無い

・カウントのON/OFFが制御出来無い

従って原理的にCPUクロック(20MHz)以上のカウントは出来ない

2.time1

16F88のtimer1は入力信号と内部クロックの信号が同期を非同期に設定することが可能

・カウントのON/OFFが制御出来る

・入力はシュミットトリガ

CPUクロックに非同期入力なので、カウンタロジックの限界値までカウントが可能

3.time2

・カウントのON/OFFが制御出来る

・内部クロックのみ入力可能なので、外部信号のカウントには使用出来ない

当然ながら信号の周期数カウントにはTimer1を使用する事にした

次にゲートタイムの測定用timerであるが、timerのon/offが制御出来るので、timer2を使用することなった

この辺りの構成は、結局稲垣氏の周波数カウンタVer7と全く同じであり、稲垣氏の着眼点に敬意を表するのである

ちなみに私の実験ではtimer1のプリスケーラなしで、60MHzのカウントが出来た

timer1のカウント入力は簡単に確認出来、次にtime2を使用して、1秒と0.1秒のゲートタイムタイムにする
この辺りは、基本フローを紙に書き出して、タイミングと処理内容を整理して、ファームウェア実装を行い、周波数の計測が出来ることを確認した
ゲートタイムの評価は、Timer1の入力設定でクロック信号の1/4を利用する
この場合測定周波数が20MHzの1/4である5MHzになる筈である

一旦はこれで、基本機能評価が出来る用になったのである

 

IMGP5671

要素開発編3へ続く

 

直読型周波数カウンタの制作 要素開発編1

要素開発とは、なかなか聞き慣れない方も多いと思う

一般的には製品を作る中で、必要な技術を確立させることである

今回の周波数カウンタ程度では、要素開発なんて大げさではある、けれど個人の趣味プロジェクトなので、偉そうに使った言葉ではある
さて、今回の制作には3つの要素開発が必要と考えた
1つ目は、16桁2行のLCDの制御である、LCDは一般に発売されているSC1602Bを利用する、SC1602Bについては一般的に動作さいてる実績が沢山あるので、今更感はあるのである

けれど、情けないことに自分の手の内(自分で理解して修正や応用が出来る)にはないのである

従って、自分でSC1602Bの初期化を含め、データのハンドシェクの一連を手の内に入れることを目的として、LCD制御部分を作成してみることにした
今回はLCDのBUSYを読出しする事で少しでも周波数測定のサイクルタイムを早くする必要があるので、とりあえず色々とやって見ることにした
取敢えずは諸先輩方のソースを色々と拝見させて頂き、大体の制御の流れを理解する
初期化処理、4bitモードでのハンドシェイク、画面クリアやカーソル処理などスクリーン制御と、1文字入力からカーソル位置によってのスクロール処理を実装した
その後に、C言語でのputc()と同等の関数を作成して、LCD表示についての処理を表示モジュールに集約してみた

とりあえずは、SC1602Bの制御は手の内に入ったと思う

IMGP5670

(写真は、キャラクターコードを順に表示しながら、スクロールしている画面、スクロールも高速である)

ちなみにLCDの制御については、PICのポートをどの様に使うかが諸先輩の嗜好が別れており面白い所である

要素開発編2に続く

 

直読型周波数カウンタの制作 仕様検討編

いままで、色々と調べて来た内容から、制作する周波数カウンタの仕様概要を決めるのである

HMY0121_4

<とりあえずの回路図である>

以下 直読型周波数カウンタの仕様概要案

1.動作範囲等

a.周波数の測定範囲は100KHzから40MHzまでとする (内蔵PreScale OFF時)

b.入力感度は3dBm以上入力インピーダンスは50KΩ以上 (40MHz時)

c.動作温度は常温とする

2.周波数計測桁数は10MHz測定時に7桁(ゲートタイム0.1秒時)とし、ゲートタイムが1秒時には8桁とする

3.測定周波数とオフセット周波数の表示は同時に行う

4.表示は16桁2行のLCDとする

5.操作系のスイッチは以下の通り

a.ゲートタイム切替  b.オフセット登録(FUNCTIONキー) c.変調モード切替(MODEキー) d.内蔵PreScreler切替 e.バントメモリ切替(ロータリーSW)

FunctionとModeキーは登録したオフセット周波数の+-の調整機能を持たせる

6.マイクロコントローラはEEPROMが256Bytesでプログラムステップ4Kwordの16F88を使用する (将来は16F1827切替を予定)

7.周波数計測の増幅器は、入力インピーダンスを高くし感度を確保するため、初段にFETを使用しPICへのT1入力へトランジスタを使用する二段アンプとする

8.ファームウェアの実装でC言語だとプログラム容量の不足が想定されるため、開発言語にはアセンブラを用いる

9.クロック信号には20MHzの水晶発振ユニットとする、精度が必要な場合は発振器を選別で対応をする
ざっくりとした仕様は上記であるが、全体のかなりの部分がファームウェアの開発に費やされることになるである

要素技術確認編へ続く

*筆者はこの回路及び記事を使用した場合の責任は負いませんのでご留意下さい

直読型周波数カウンタの制作 調査編1

欲しいものは高価なのである
R-4AFT-101等で使用出来る、直読型周波数カウンタについて調べてみた
各機種専用のメーカ純正品や、サードパーティの専用品はオークションで偶に出品されている
しかし、コレクターズアイテム価格で、とても私ごときが、おいそれと購入は出来ないのである
そこで、諸先輩方の周波数カウンタの制作実例を拝見させて頂いた
皆様色々と工夫されているのである。

お手本として、16F88を使用した稲垣氏の周波数カウンタVer7をダウンロードして組立てて見た

シンプルな回路で、ここまで出来るのは凄いことである

稲垣氏のオリジナル
(稲垣氏開発のファームウェア、周波数カウンタV7)

一般的なラジオの中間周波数である455KHzをオフセットとして測定周波数に対して足して表示する周波数カウンタの作例は多い、それ以外のオフセットについては自分で、PICファームウェアの書き換えか、PICのEEPROMの書き換えが必要である
製作例によっては、オフセット周波数書換え専用ツールがあるが、出来ればパソコン無しでオフセット登録をしたい

YC-601みたいにバンド切替SWで、オフセット周波数とオフセット演算が選択出来て、主要なバンドの周波数が直読出来ればよいのである。

現時点での要求仕様では、市販品や諸先輩の作例をそのままの利用は難しい、との結論に至ったのであった。

ここで、R-4AとFT-101などで使える、直読型周波数カウンタの仕様検討を開始することにしたい

調査編2へ続く..