Old MC6800(Home) > 新しい基板 > Clock Generator
MC6800用 Clock Generator の実験  (Old MC6800) 


PIC12F1822 DIP-8 & SOP-8今回は クロック UP に挑戦しました 
目  次内  容更新日
[0] 始めに今回の Clock Generator の用途2018/01/21
[1] クロックUPクリスタル発信器の設定
[2] 変更後の接続変更 2ピン、追加 3ピン
[3] ソフト変更オリジナルにパッチを当てました(コントロールレジスタは書換?)
[4] 動作確認結果の波形  分解能が 1/8 から 1/20 になった
[5] 試作二階建てにしてリセットスイッチも付けてみた
   試作 Ver.2表面実装にしてリセットスイッチを中央に付けてみた2018/02/13
   試作 Ver.3見栄えを良くして、試供用の基板を起こしてみた2018/03/25
[6] リセット信号改善不具合対策も兼ねた リセット時間延長をしてみた2018/01/28
[7] クロック可変機能クロック周波数の可変機能と設定の保存機能を追加してみた
[8] 通信速度の変更38400bps でのテスト (ロード時間が 1/4になります)2018/01/28
   可変BRG Ver.19600/19200/38400bps の切り替え版 (PIC:Clock=32MHz)2018/03/25
   可変BRG Ver.29600/19200/38400/57600/115200bps の切り替え版 (PIC:Clock=80MHz)2018/03/25



[0] 始めに
今回の Clock Generator の用途
偶然にも、40年前に活躍していた MC6800マイコンを新たに復活させようとしている
プロジェクトを発見して懐かしくなり再び製作してみる事にしました

この MC6800は、オーバーラップしない 2相のクロックを必要とします
    ___     ___     ___     ___  
φ1 _   _____   _____   _____   __
        ___     ___     ___     _
φ2 _____   _____   _____   _____ 
さらにこのクロックの振幅は TTLレベルでは無くほぼ 5Vまで振る必要があります
このボードの開発者(vintagechipsさん)も、ここの所を悩まれた様で
振幅はクリアしていますが、クロックのパルス幅に付いてはやや不足ぎみで
1MHzのクロックでも MC68A00(1.5MHz仕様のチップ)が必要です

使っている PIC12F1822 のクロック最高周波数 32MHzでは
振幅を制御するための分解能は 1/(32000000/4)秒の 0.125μSしかとれません
1MHz を 0.125μSで分割してみると、たった 8分割にしか出来ません
    ___     ___     ___     ___  
φ1 _123_____   _____   _____   __
       45678 (以下繰返し)
        ___     ___     ___     _
φ2  ____567_____   _____   _____ 
   _1234   8 (以下繰返し)
    <---- 1μS ----> (1MHz)
オーバーラップしないために上の図で 4と8の区間がどうしても必要です
純粋にデジタル的にクロックを作ろうとすると PIC12F1822 ではこれが限界です
4と8の区間を減らすには、分解能を上げるしか方法は有りません



因みに 40年前に作ったボードでは
4と8の区間の無い波形から CR で各パルスの前縁を遅らせた後、整形するアナログ的な方法でした

発振回路は CMOSロジックのインバータによるマルチバイブレータで、2つの時定数(コンデンサ容量)が
不揃いのため φ1・φ2 の時間が異なっています  クロック周波数も約900kHz位で、かなりアバウトでした

IF誌 No.3(1976/04)掲載のクロック回路 (松本吉彦氏)2相クロック (自作した回路の実測波形)



[1] PIC12F1822 のクロックを上げる方法
オリジナルは、内部オシレータの 8MHzを 4xPLLで 4逓倍して 32MHzにする標準の方法です
内部オシレータで 4xPLL を利用できるのは 8MHz だけですが、データシートのブロック図を
見ると外部オシレータやクリスタルオシレータからも 4xPLL を利用できる構造になっています

 
実験1
クリスタル発信器の設定にして、どこまで 4xPLL が動作するか試してみた結果
手持ちの 16MHzと 20MHz のセラミック振動子では問題なく動作しました
20MHz のセラミック振動子で 4xPLL すると、クロックは実に 80MHzにもなります
20MHz までの振動子を使う事は仕様の範囲内ですが、
仕様には 20MHz を用いて 4xPLLで逓倍出来るとは書いてありません(動かなくても自己責任で!)

実験2
これ以上の周波数のセラミック振動子は手元に無いので
外部信号入力の設定にして、Clock INに 32MHzを入れてみました
32MHz は(もう1個の)PIC12F1822を内部オシレータ 8MHz・4xPLLとして
クロック(32MHz)をピンから出力する設定にして作りました
結果は、4xPLL が正常に作動せず中途半端な周波数になりました
今回は手持ちのセラミック振動子の周波数でしか実験していませんが
20MHzより高い周波数まで動作する可能性は有ります

しかし、目的のMC6800用のクロックは切りの良い周波数にしておかないと
ループタイマーなどの計算が厄介なので 20MHz のセラミック振動子を用いる事にしました





[2] 変更後の接続
(12F1822)
変更点
(1) 20MHz のセラミック振動子(又は水晶振動子)を RA4(3), RA5(2) 端子間に接続
   セラミック振動子のセンターピンは GND に接続 (水晶振動子の場合はコンデンサが必要です)
(2) リセットスイッチとして押釦スイッチを RA3(4), GND(8) 端子間に接続
(3) RA1(6) を MC6800:/RESET に接続
(4) RA0(7) を MC6800:CLK2 に接続

(V2.0 LED表示) 追加変更点
(5) R(10kΩ) を RA2(CLK1) と LED 間に接続
(6) LED(青) を R とGND 間に接続
(7) C(0.1uF) を LED と並列に接続
   C(0.1uF) を省くとクロック振幅に応じて明るさが変わります(後述)

リセットスイッチは必須ではありません(付ければハングした時でも、モニターに戻れます)

(V2.0 LED表示) 追加変更点

ハングした時の解析用に、NMI のスイッチも付けたくなりました(パタンカットとプルアップが必要ですが)





[3] ソフト変更  sbc6800_datapack 内の mc6800crgen.hex を変更
資料・データの所在
SBC6800技術資料   (sbc6800_techdata.pdf)
SBC6800データパック (sbc6800_datapack.zip)

私の場合は「C」は苦手なので、HEXファイルから ASMを起こし、変更してアセンブルし直しています

コンフィグレーションの変更
_FOSC_HS      (クリスタルオシレータとして設定)
_MCLRE_OFF (RA3をデジタル入力として使用する設定)

プログラム(主にコントロールレジスタ設定値)の変更
OSCCON        ;HS:Xtal=20MHz
ANSELA ;All Digital (変更無し)
TRISA ;All Output
OPTION_REG,7 ;WPUEN(RA3のプルアップを有効にする)
PR2 ;19に設定(1MHzの場合) 9に設定(2MHzの場合)
CCPR1L ;10に設定(1MHzの場合 450nS) 5に設定(2MHzの場合 200nS)
RA0 に割り当ててあったリセット入力を RA3に移動
電源 ON 時のリセット時間のループタイマーをクロックに応じて調整

プログラムは Download ページ に置いておきますので参考にして下さい




[4] 動作確認
周波数 1MHz では、パルス幅 450nS を実現できました
時間軸方向だけ参考にして下さい(波形のオーバーシュートやリンギングは安物のオシロのせいです)
オリジナルクロック信号 (1MHz、パルス幅:375nS)パワーオン・リセット信号 (黄:約200mS)
改良版クロック信号 (1MHz、パルス幅:450nS)倍速クロック信号 (2MHz、パルス幅:200nS)
クロック周波数が上がっているので、ループタイマのリセット時間も調整しました(赤:クロック、黄:リセット信号)
周波数 2MHz では、パルス幅 200nS になってしまいますが、MC68A00(1.5MHz版)が動きました





[5] 試作
(1)基板に直接細工をせずゲタを履かせてピンの変換を行いました
元々、無接続のピンもあるので 2, 3 番ピン以外は上下接続して固定しました

[反省点]今回は配線のし易さから PICを ICソケットの真上に置きましたが
     タクトスイッチがオフセットした位置なので強く押すとピンが抜けそうになります
     スイッチを ICソケットの真上に置くのがベストです
SBC6800基板に取り付けソケットとピンの接続の様子
(2)試作 Ver.2 SW と PIC(SOP)の載った基板を2枚重ねで手作り試作、真上から押すので安定した (2018/02/13)
左から、PIC12F1822(DIP)、連結ソケット、DIP化基板、SMTセラロック、PIC12F1822(SOP)
(3)試作 Ver.3 見栄えを良くして、試供用にするため基板を起こしてみた2018/03/25
DIP-8pin サイズに収めるため押ボタンスイッチと LEDを表面に、PIC12F1822とセラロックは裏面に配置
ピン配置はオリジナルに合わせました、もちろんシリアルプログラミングもできます

基板は fusionpcb 日本語HPのディスカウント品「$7.9基板セール」を試してみました
多少の制約はありますが、100x100mm 5枚 で送料込みのこの価格は魅力的だと思います
しかも、20mm以上の間隔ならこの価格のままで Vカット溝も入れてくれます
今回は、製造に 7日、Singapore Post(普通の書留便)で届くのに 10日かかりました
「通常の基板」で速達便の配送では 2日位で届きますが、基板の価格よりも配送費の方が高くなってしまいます
極小規模なので PCBE で設計


乾燥剤と一緒にエアーキャップでラミネートされてきた   10x10mmに分割
   

部品をハンダ付けしてプログラムを書き込めば完成     動作状態(左:CPU-Clock、右:通信用BRG)
   



[6] リセット信号改善
SBC6800 基板にリセットスイッチを付けてみましたが
リセットスイッチを操作すると、ターミナルソフトの画像の様に「文字化け・暴走する」場合が有ります
これはスイッチのチャタリングのために、リセット信号が不規則に振られる事が原因の様です
そこで、チャタリングキャンセル機能を持たせてリセット信号を改善します

元の、PIC12F1822 のプログラムは RA0(7pin)に外部リセット信号を受付ける様に書かれていますが
与える信号には整形した信号が要求されてます
(スイッチを直接接続した場合の、スイッチのチャタリングには配慮されていません)

また、いろいろと実験している内に(特にクロックアップした場合)
コールドスタート時に「文字化け・暴走する」場合が有りました
これに対しては、パワーオン・リセット時間の延長を行って改善してみました
(2018/02/02 追記)
  暴走ではなく、ACIA 初期化時のバッファ空読みがしてないためのゴミ表示でした(MIKBUGプチ拡張時に対策済)
  パワーオン・リセット時間の延長は、利点はあっても特に不都合はないので、延長したままとします

(2018/04/26 追記)
  初期化時の文字化けに付いて、テストを続けている内に得た感触からの推定ですが(あくまでも推定です)
  CPUクロックのパルス幅が足りないために、アクセスタイムが十分に取れないため
  ACIAを アクセスした時、ACIAからのデータが安定しない内に CPUが読み込んでしまう
  その根拠は
  (a) CPUクロックが速い(クロックのパルス幅が狭い)ほど文字化けしやすい
  (b) ACIAの A(1.5MHz)版 の方が B(2MHz)版 よりも文字化けしやすい
  (c) CPUが冷えている状態で電源ONすると文字化けしやすい
  などです


ターミナルソフトの画面スイッチによるリセット信号
 
 
プログラムの変更点
(1)パワーオンリセット時間の延長
  200mS ---> 1Sec
  ここでは、(2)でも共通に使う様に、20mSのループタイマーを作成して 50カウントしました

(2)リセットスイッチのオフディレー機能追加
  リセットスイッチを ONにした時は直ぐに SBC6800リセット信号を Loに落とし
  リセットスイッチを OFFにした時は、200mS後に SBC6800リセット信号を Highにします
  チャタリングキャンセル機能のために、スイッチの読込みは 20mS毎に行ないます
  スイッチの読込みと 200mSタイマーのカウントを同時に行います
  (今回は、割込みを使用せずにロジックを組んでみました)

プログラムは Download ページ に置いておきますので参考にして下さい

パワーオンリセット信号波形 赤:リセット信号(約1Sec)、黄:電源電圧

[赤] リセット信号、 [黄] リセットスイッチ信号波形 (左:約20mS) (右:約400mS)





[7] クロック可変機能
クロック周波数を変更したい時に、クロックジェネレータの PIC12F1822 を取り替えるのは面倒なので
スイッチでクロックの切換えができる様にしてみました[クロック可変機能]
切り替えた値は EEPROMに保存しておく様にしました[クロック記憶機能]

切換えは「リセットスイッチを押したまま電源 ON にする」だけです
1MHz(初期値)--> 1.666MHz --> 2.000MHz --> 2.500MHz --> 1MHz ... と変化します

オシロやカウンタが無い場合、クロック周波数を確認できないと不便なので LEDを付けました
LED回路の平滑コンデンサが有ると「1MHzに切り替わった時」だけ、リセットスイッチを離すまで LEDが点灯します

最初は、1MHzに切り替わった時だけ LEDを点灯していたのですが
常に点灯して置いた方が、状態が良く分かるので点灯したままにしています (消したい場合はコンデンサを付ける)
1MHzに切替った時(SW-ONの時デューティ100%)が最も明るく、
1MHz(SW-OFF時 45%)、1.6MHz(42%)、2.0MHz(40%)、2.5MHz(38%)と順番に暗くなります
この数字は、6800のクロックのパルス幅の比率そのものです

設定は下の表の値に設定可能ですが、1.000 / 1.666 / 2.000 / 2.500 MHz の4段階としました
ソースファイルの中には全て記述(コメント・アウト)していますので、好きな値に変更できます
実験の時はともかく、実際には 1MHz と、自分のシステムで安定に動作する最高周波数の 2段で十分でしょう
(2.5MHz の設定が有る理由は、MC68A00 でも 2.5MHz で動くためです)

プログラムは Download ページ に置いておきますので参考にして下さい


Clock設定PR2CCPR1LT1T2T1+T2
(MHz)nn-1n/2 (nS)(nS)(nS)
1.0002019104505501000
1.1111817 9400500 900
1.2501615 8350450 800
1.4291413 7300400 700
1.6661211 6250350 600
2.00010 9 5200300 500
2.500 8 7 4150250 400
CPUクロックを切り換える様子の動画 
リセットSWを押しながら、電源を ONする毎に
クロックが切り替わります

(リセットSW前の)LEDの明るさの変化は
動画では分かり難いですが、肉眼では区別できます

1.000MHz (パルス幅:450nS)1.666MHz (パルス幅:250nS)
2.000MHz (パルス幅:200nS)2.500MHz (パルス幅:150nS)




[8] 通信速度の変更
(1)ACIA 用のボーレートクロックも上げてみます
オリジナルは 9600bps ですが、ACIA のクロック最大周波数は 800kHz 最小パルス幅は 600nS となっています
そこで、この範囲内で簡単に変更できる 19200bps と 38400bps でテストしてみました
(これ以外ではクロックの精度が良い組み合わせは有りません)

変更点は、PR2 の設定値を 1/2, 1/4 と変えるだけです(その他の設定は変えません)
307,200Hz(19200bps) の場合は PR2:25、CCPR1L:13とします
614,400Hz(38400bps) の場合は PR2:12、CCPR1L:7とします

欲しい値(Bitrate*16)計算値設定値得られる値誤差   1/PWM周期=PWM周波数=614,400(Hz)
  PWM周期=1.6276(μS)
  (PR2+1)*4*Tosc*PS=1.6276(μS)
  Fosc:32MHz の時
  4*Tosc=0.125(μS), PS=1, (PR2+1)=13
  Duty:50% の時 CCPR1L=(PR2+1)/2=6
BitrateClock PR2 CCPR1LClock 
(bps)(Hz)nn-1n/2(Hz)(%)
9,600153,600525126153,8460.16
19,200307,200262513307,6920.16
38,400614,40013126615,3850.16

プログラムは Download ページ に置いておきますので参考にして下さい
38400bps (614,400Hz)版のソースコードは OSC6144.ASM です
(コンパイラが吐き出した割算ルーチンをコメントアウトしています)


vintagechipsさんは、Cで記述していて PR2 の値を 1/2 して CCPR1L の値としていますので
1Byte の値を 1/2 するためだけに、コンパイラは 割算ルーチンを組み込んでコードサイズが膨らんでいます
アセンブラで 8bit の値を計算する場合、上表の n の値から PR2 を計算(-1)するには DECF の1命令で済みますし
CCPR1L を計算(1/2)するには LSRF の1命令で済みます
ここでは直接 PR2=12 CCPR1L=6 に設定していますので、コードサイズは 1/5 位になります
オリジナルでは OSCTUNE に 63 をセットしていますが、(8MHz*4=32MHzで誤差+0.16%なので)不要です

(コードサイズが大きくても、どうと言う事はないのですが、ヘキサファイルを見てしまうと気になります)

通信速度を 38400bps に上げた効果
MIKBUG では、大きなサイズのプログラムをロード/パンチ(ダンプ)する時しか分かりません
TinyBASIC(2,128Byte) のロードに 9600bpsでは 11秒位かかりますが、38400bpsでは 3秒足らずで終わります

注意点
MIKBUGのロード/パンチ(ダンプ)では、MC6800の処理速度が問題にはなりませんが
BASICのソースファイルを「Send file」する時などは、処理が追い付かないので
TeraTermの Serial port setup で Transmit delay 0 msec/char 50 msec/line とします

(2)ボーレート可変 Ver.1 9600/19200/38400bps の切り替え版 (PIC:Clock=32MHz)2018/03/25
リセットSWを取り付けた「6800用 CPUクロック発振器基板」を流用して (1)の 3種類の通信速度を切り替えます
回路は下図の通りで、[5](3)の基板をソケットに挿すだけです (ソフトで内部クロック・外部Xtal を選択)


仕様は、押し釦SWを押す毎に 3段階の通信速度を切り替えるだけですが
制約として、基板を流用すると LEDはクロック出力端子に固定されています
基準の 9600bps の状態を表示するために少し工夫をしました

9600bps に切り替わったときは、押し釦SWを押している間 (100% の明るさで)LEDを点灯します
9600bps 以外のときは、押し釦SWを押している間 LEDを消灯します
押し釦SWを離すと、ボーレートクロックのデューティ比(50%)の明るさで点灯します

これで、基準の 9600bpsの状態が確認できますし、
そこから、1回押せば 19200bps、2回押せば 38400bpsとなります

プログラムは Download ページ に置いておきますので参考にして下さい

 

(3)ボーレート可変 Ver.2 9600/19200/38400/57600/115200bps の切り替え版 (PIC:Clock=80MHz)2018/03/25
115200bps の計算をしてみると、PR2, CCPR1L が小さ過ぎて、ボーレートの精度を確保できません
そこで「6800用 CPUクロック発振器」の場合と同様に PICのクロックアップで対応します
下表は計算結果です  38,400bps以上ではクロック誤差 -1.36%になります
1文字を 10bitで通信すると、スタートビットからストップビットまでの誤差は 1.3%*10=13% となりますが
通信には問題ない程度と思います
ボーレートの誤差が 5%(10bitで 1/2bitの誤差) 以上になるとフレーミングエラーとなって通信不能になります

 欲しい値Bitrate*16計算値設定値得られる値誤差   PWM周期=(PR2+1)*4*Tosc*PS
  CCPR1L=(PR2+1)/2 の時 Duty:50%
  Fosc:80MHz、PS=1 の時 4*Tosc=0.05(uS)
  (例)
  Bitrate=115,200bps(Clock=1,843,200Hz)
  PWM周期=1/PWM周波数=0.543(uS)
  (PR2+1)=0.543/0.05=10.86
  PR2=10, (PR2+1)/2=CCPR1L=5
Bitrate  Clock PR2 CCPR1LClock 
(bps)(Hz)nn-1n/2(Hz)(%)
9,600153,60013012965153,8460.16
19,200307,200656432307,6920.16
38,400614,400333216606,061-1.36
57,600921,600222111901,091-1.36
115,2001,843,200111051,818,182-1.36
プログラムは Download ページ に置いておきますので参考にして下さい
(Ver.2 は 20MHz-Xtal*4xPLL 80MHzです)


TeraTerm設定 (9600〜115200bps)9600bps (以下全て 500nS/Div)
19200bps38400bps
57600bps115200bps
通信速度を 115200bps に上げた効果と課題
(1)使える範囲(条件)が限定される
  MIKBUGのパンチ(ダンプ)では、MC6800の処理速度で制約されますが、十分に速くなります
  MIKBUGのロードは、
  MC6800-1MHzの場合、処理速度が間に合わずロードできませんでした
  MC6800-2MHzにして Transmit delay 0 msec/char 50 msec/line にするとロードできます

  同様に、TinyBASICのリスティングでは、MC6800の処理速度で制約されますが、十分に速くなります
  BASICのソースファイルを「Send file」する時は、処理が全く追い付きません
  Transmit delay 0 msec/char 50 msec/line にしても文字を取りこぼします
  Transmit delay 1 msec/char にすれば取り込めますが、これでは 9600bpsと変わらないので
  むしろ 38400bps、Transmit delay 0 msec/char 50 msec/line の方が速く取り込めます

(2)BASICのソースファイルをローディングする場合などの課題として
  送る側を、一時待たせるためのフロー制御が必要となります

  例えば、シリアル受信を割り込み処理にしてリングバッファに格納します
  バッファフルになったら RTS(送信要求)を下ろして相手の送信を止めます
  BASIC側がラインバッファから文字を取り出して、バッファに空きができたら
  RTS(送信要求)を上げて受信を再開します
  この様にすれば文字処理と受信を平行して行うことができて処理速度が上がります

  現状のシリアルインターフェイスは RTS, CTS とも信号が準備されていますが
  ソフト側でサポートしていないので機能しません
  できれば モニターの拡張を行って、フロー制御を実現したいと思います
 
 






inserted by FC2 system