HOME >> 鉄道模型自動運転システム > 新ATSに挑戦 12F635 を使用する
■ はじめに
この制御システムに使用している8ピンPICマイコンは、当初は12F635 を使用予定であった。 しかし、教則本の例題は機能の豊富な 12F683 を使用していた。 このため安全を見て、両方のタイプを入手して工作を始めた。 最初は 12F635 を使い、使教則本に示されたサンプルプログラムを打ち込んでみたのであるが、アッセンブルエラーばかり出て素人にはお手上げであった。 そこで、教則本の通りの 12F683 に変えてプログラム構築を進めてきたいきさつがある。
しかし、同じ仲間の 12F635 が使いないのは何故なのか、疑問のままでは見過ごすことができなかったので、再度挑戦することにした。
■ 12F635 エラーの内容と対策
プログラム記述のためのエディタとアッセンブラは、MPLAB IDE を使用している。 このバージョンは v8.53 である。 教則本で紹介されているものと同じと認識しているのだが・・・・・。 そして、マイコンに書き込むためのライターとしてPICkit 3 を使用している。
◆ _INTOSCIO がエラーになる
何故だか、アセンブル時に _INTOSCIO が定義されていないとエラーになってしまい、前に進まないのである。 そこで、このコンフィグの意味をあちこちの情報を探して探ってみた。 すると、内部クロックか外部クロックかの選択と、クロック信号を出力するかしないかを決める大切なコンフィグであることが分かった。 さらに、これらに関するポートは GP4 と GP5 を I/O ポートとして使用するのかどうかも設定しているのである。
ちなみに、このコンフィグ部分を消してアッセンブラを掛けると、問題無く通るのであるが、マイコンの作動はダンマリであった。 何故 12F683ではOKなのに、12F635 ではNGとなるの・・・・・・・・・?。
Informations about the PIC microcontrollers にてPIC12F635とPIC12F683の仕様を比較してみた。 PIC12F635 と PIC12F683 の表を見ながらその違いを見てみたが、両方とも同じ様に、FOSC = INTOSCIO として定義されているようだ。 それぞれの仕様を見ていてもよく理解できないので、結局は、このソフトのバグとではないかと疑るようになった。
しかし、それでは対策にならないので、ソフトのあちこちの項目を探っていたら、下記の項目を見つけた。 注目したのは、Configuration Bits という項目の Configuration Bits set in code とあるチェックボックスが、デフォルトでチェックされている点であった。 このチェックを外すと、下の欄の項目が選択できるのである。
Field の欄の WDT を見て、ウオッチドックタイマーの項目だと理解し、ここの欄にて、コンフィグが手動で設定できることを理解した。 そして、他の項目の内容を猛(?)勉強してその意味を理解出来たので、下の図のような選択を設定した。 オッシレータの項目は、Internal RC No Clock を選択した。
1 #include P12F635.INC ; PIC12F635用のヘッダファイルの読み込み 2 3 ; コンフィグレジスタの設定 4 ; __config _BOD_ON & _WDT_OFF & _MCLRE_OFF & _INTOSCIO 5 6 ;ファイルレジスタの割り当て 7 CT_DELAY1MS equ 0x40 8 CT_DELAY100MS equ 0x41 9 10 ; 初期設定 11 bcf STATUS, RP0 ; バンク0 12 clrf GPIO ; GPIO の出力が0になるよう設定 13 movlw 0x7 ; W ← 7 14 movwf CMCON0 ; CMCON0 ← W = 7 : コンパレータをオフ 15 bsf STATUS, RP0 ; バンク1 16 ; clrf ANSEL ; ANSEL ← 0 : A/Dコンバータをオフ 17 movlw B'101000' ; W ← '101000' 18 movwf TRISIO ; TRISIO ← W : GPIO を出力に設定 19 bcf STATUS, RP0 ; バンク0 20 21 bcf GPIO,0 ;信号赤を消灯 22 bcf GPIO,1 ;信号橙を消灯 23 bsf GPIO,2 ;信号緑を点灯 24 25 ; プログラムの主要部分 26 LOOP 27 bcf GPIO,0 ;信号赤を消灯 28 bcf GPIO,1 ;信号橙を消灯 29 bsf GPIO,2 ;信号緑を点灯 30 bcf GPIO,4 ;リレーをOFFして通電する 31 btfss GPIO,5 ;S!をチェック、ONを待つ 32 goto $-1 33 btfss GPIO,5 ;S!をチェック、ONを待つ 34 goto $-3 35 36 STAGE0 37 call delay100ms ;列車が来た、時間待ち 38 bcf GPIO,2 ;信号緑を消す 39 bsf GPIO,0 ;信号赤を点灯 40 btfsc GPIO,5 ;S!をチェック、OFFを待つ 41 goto $-1 42 btfsc GPIO,5 ;S!をチェック、OFFを待つ 43 goto $-3 44 call delay100ms ;列車が通過した、時間待ち 45 46 STAGE1 ;チェックポイント通過 47 btfsc GPIO,5 ;S1をチェック、後続の列車は来ていないか? 48 goto STAGE4 ;列車を停止させる 49 btfss GPIO,3 ;S2をチェック、前方のチェックポイントに来たか? 50 goto STAGE1 ;来るまで待て 51 52 STAGE2 ;前方のチェックポイントに来た 53 bcf GPIO,0 ;赤を消灯 54 bcf GPIO,2 ;緑を消灯 55 bsf GPIO,1 ;橙を点灯 56 57 STAGE3 58 btfsc GPIO,5 ;S1をチェック、後続の列車は来ていないか? 59 goto STAGE6 ;列車を停止させる 60 btfsc GPIO,3 ;S2をチェック、前方のチェックポイントを通過したか? 61 goto STAGE3 ;通り過ぎるまで待て 62 goto LOOP ;先頭に戻る 63 64 STAGE4 65 bsf GPIO,4 ;リレーをONさせて通電を切り列車を止める 66 btfss GPIO,3 ;S2をチェック、前方のチェックポイントに来たか? 67 goto $-1 68 btfss GPIO,3 ;S2をチェック、前方のチェックポイントに来たか? 69 goto $-3 70 bcf GPIO,0 ;赤を消灯 71 bcf GPIO,2 ;緑を消灯 72 bsf GPIO,1 ;橙を点灯 73 74 STAGE5 75 btfsc GPIO,3 ;S2をチェック、前方のチェックポイントを通過したか? 76 goto $-1 77 btfsc GPIO,3 ;S2をチェック、前方のチェックポイントを通過したか? 78 goto $-3 79 bcf GPIO,0 ;信号赤を消灯 80 bcf GPIO,1 ;信号橙を消灯 81 bsf GPIO,2 ;信号緑を点灯 82 bcf GPIO,4 ;リレーをOFFして通電し、列車を発車させる 83 goto STAGE0 ;列車は次の区間を走行中 84 85 STAGE6 86 bsf GPIO,4 ;リレーをONさせて通電を切り列車を止める 87 goto STAGE5 ;列車停止中 88 89 ; delay10us サブルーチン 90 delay10us 91 goto $+1 92 goto $+1 93 goto $+1 94 goto $+1 95 goto $+1 96 goto $+1 97 goto $+1 98 goto $+1 99 return 100 ;delay1ms サブルーチン 101 delay1ms 102 movlw D'256' 103 movwf CT_DELAY1MS 104 delay1msL 105 call delay10us 106 decfsz CT_DELAY1MS, f 107 goto delay1msL 108 goto $+1 109 goto $+1 110 goto $+1 111 goto $+1 112 goto $+1 113 goto $+1 114 goto $+1 115 goto $+1 116 return 117 ; delay100ms サブルーチン 118 delay100ms 119 movlw D'10' 120 movwf CT_DELAY100MS 121 delay100msL 122 call delay1ms 123 decfsz CT_DELAY100MS, f 124 goto delay100msL 125 return 126 127 ; プログラムの主要な部分の終わり 128 end ; プログラム終了
そして、プログラムをアッセンブリしてPIC に書き込み、制御ユニットにセットしたのだが、結果は期待外れで・・・・・・緑LEDが点灯したままであった。
◆ 教則本のサンプルプログラムを走らせてみる
もし、コンフィグが正常にセットされているのであれば、教則本に示された簡単なプログラムは作動するはずであると考えて、教則本に紹介されているプログラムを最初から実施してみた。 この推定はまさに正解であった、
リスト4-1、リスト5-1は問題無く作動したので意を強くしたのであるが、リスト6-1では途中で止まったままであった。 このプログラムはLEDを時間をおいて点滅させるもので、タイマーの設定を使用しているのである。 そのタイマー設定は、汎用レジスターを使用しているものであった。
右のプログラムは、今回作動させようとしているプログラムの完成状態ですが、そのタイマー作動部分は、教則本の内容をそっくり活用しています。
教則本のプログラムも動かない! これは、PIC12F635とPIC12F683 の差異に違いないと判断して、そのポイントはタイマー部分にあると推測した。 そして、このタイマーのカウントを記憶する部分は、汎用レジスターを使用しているので、ここが怪しいと睨んだ。
そして、PIC12F635とPIC12F683 のレジスタ・ファイル一覧表を比較した。
見つけたぞ! PIC12F635とPIC12F683 の違いを!
そうです。
汎用レジスタのアドレスは、PIC12F683 は 0x20 〜であり、 PIC12F635 は40h 〜と記されていました。 40h は16進数の表示方法なので、0x40 と同じです。 レジスタのアドレスが違っていたのです。
そこで、右のプログラムの7行目と8行目のように、アドレス指定を変更して、再度機能チェックを実施してみました。
大成功でしたね!
これで、安心して、PIC12F635 の石を使用する事が出来るようになりましたので、プログラムのチューニングに集中できるようになりました。
結論としては、PIC12F635 と PIC12F683 とはレジスタのアドレスが異なっているので注意すること。
■ センサーのダブルチェック
もう一つの課題であったロジック飛びについて、センサー信号のダブルチェックをプログラム上で考えてみた。
単純に考えて、チェックを2回実施すれば良いとして、情報待ちの部分を右のリストの 33行目と 34行目の様に、もう一度同じチェックを繰り返す様に追加した。 本来なら間に時間を置くのが良いと考えるが、当面はこれでテストしてみることにする。
また、情報待ちのチェック部分ではなくて、47行目と 48行目の様に分岐する部分は繰り返しチェックさせると前に進まなくなるので、分岐後に後戻りするロジックを考えなけらばならない。 これは複雑になりそうなので今回は見送ることにした。
そして、右のプログラムを使って機能チェックを行かった。 ダブルチェックの効果かどうかは確認できなかったが、 今のところ不具合は見られなかった。 当面は良しとしておこう。
赤字の部分は作動を停止させた部分を示し、青字の部分は、PIC12F635 のためと、ダブルチェックのために変更した部分です。
(注意) 右のプログラムの記述は、そのままコピーしても機能しないはずです。 このページに記載するため、行番号を追記している事、行頭スペースとしての空白を入れていることなど、アセンブラの記述には合致していないからです。
2018/9/24 作成