目次
前
次
センサー処理
Forthインタプリタ基板で、外界の状態をセンサーから
入力するには、2つ方式があります。
デジタル入力の場合、ピン数の物理的制約から最大8ビット
程度が妥当でしょう。
アナログ入力では、A/D変換器を使うので、用意されている
チャネル数だけとなります。
センサーからの入力数を増やすことを考えてみます。
デジタルでは、1ビット入力でマルチプレクサで切替える
方法があります。次のようなICを外付けすれば、4ビット
で、8ビットのデジタル入力が可能になります。
この回路では、3ビット出力、1ビット入力になりますが
デフォルトでGPIOに指定されているポートの入出力を設定
した後に、セレクト出力とビット入力をすれば充分。
\ SFR
$50008000 constant GPIO0_DDR
$50003FFC constant GPIO0_DR
\ set data direction
$380 GPIO0_DDR ! \ P0.7 - P0.9 outputs , others inputs
\ define word
: get_v
7 lshift GPIO0_DR bis! \ send selector signal
GPIO0_DR @ 64 and 6 rshift \ get target bit and shift
1 and hex . \ mask and show
;
: GET.S 8 0 do i get_v loop ;
ポート0の7から9ビットを出力、6ビット目を入力に設定。
その後、ワードを定義して、指定したピンの論理値を取得し
表示。
ビット位置をハードウエアに合わせるために、左、右の
論理シフトを利用して対応。
テストするために、選択信号を0から7にしてワードを
呼び出しています。インタプリタでの操作でハードウエア
を動かせます。
マルチプレクサだけでは、時間差でセンサー出力が変化して
しまうので、ラッチとマルチプレクサを1パッケージとした
ICを利用すればよいでしょう。
センサー情報を入力したいタイミングで、nLOADで記憶させます。
さらに、 shift clock を使い、1ビットずつ datum から入力と
すれば、最大8ビットの入力が可能。
Forthのスクリプトでは、以下。
\ SFR
$50018000 constant GPIO1_DDR
$50013FFC constant GPIO1_DR
\ set data direction
$300 GPIO1_DDR ! \ P1.9 and P1.8 outputs , others inputs
\ define word
: get_sensor
\ lacth 8 bits
1 8 lshift GPIO0_DR bis! \ H
1 8 lshift GPIO0_DR bic! \ L
1 8 lshift GPIO0_DR bis! \ H
\ clear
0 TMP !
\ get 8 bits
8 0 do i
7 - abs \ calculate 7-i
GPIO0_DR @ 16 and 4 rshift \ get datum ans shift to LSB
swap lshift TMP or TMP ! \ store result to variable
\ send shift clock
1 9 lshift GPIO0_DR bis!
1 9 lshift GPIO0_DR bic!
loop
TMP @ hex .
;
get_sensor
ポート1の0ビットを入力、他のビットを出力に設定しておきます。
ワードで、74HC165を制御するコードをまとめています。
アナログ入力で、A/D変換器を使う場合、次の回路で
該当信号が印加されたか否かを検出できます。
A/D変換器が使えるピンを、図面から拾います。
PIO01_11を利用して、変換値を入力するなら
Forthコードは、以下。
$40048080 constant SYSAHBCLKCTRL
$40048238 constant PDRUNCFG
$40044074 constant IOCON_PIO0_11
$4001C000 constant AD0CR
$4001C004 constant AD0GDR
: analog_init
1 13 lshift SYSAHBCLKCTRL bis! \ Enable Clock for ADC
1 4 lshift PDRUNCFG bic! \ Clear Power-down for ADC
$42 IOCON_PIO0_11 ! \ Select Analog input mode for P0.1
;
: analogRead ( -- measurement )
1 0 lshift \ select AD0
11 8 lshift or \ CLKDIV = 12 --> 12 Mhz / 12 = 1 MHz when SYSTEM_CLOCK 12MHz
0 16 lshift or \ Burst off
0 17 lshift or \ 11 clock cycles - 10 Bit accuraccy
1 24 lshift or \ Start conversion now.
AD0CR !
\ wait for DONE=1
begin 1 31 lshift AD0GDR bit@ until
\ shift
AD0GDR @ 6 rshift $3FF and
;
: analogScan ( -- )
analog_init
\
begin
analogRead u. cr
key? until
;
LPC1114では、1ピンに複数の機能を割り当てしている
関係上、A/D変換器に対してのクロックと電力供給の他
A/D変換器で利用すると指定が必要です。
Forthの組込みワードに、「begin ... flag until」がある
ので、特定レジスタの指定ビットの変化をモニタしてコード
を簡潔に記述できます。
flagは、0でFalse(偽)であり、それ以外の値はTrue(真)と
みなします。
Trueの値として、−1が使われることが多いです。
「begin ... flag until」では、flagが0になれば、その
反復を終了します。
センサーの値をリードして、入力論理値でのウエイトを作る
場合は、次のコードでよいでしょう。
\ SFR
$50018000 constant GPIO1_DDR
$50013FFC constant GPIO1_DR
\ set data direction
$01C GPIO1_DDR ! \ P1.2 - P1.4 outputs , others inputs
\ wait PIO1_9 = '1'
: swait begin PIO1_DR @ 9 rshift 1 and 1 xor until ;
レジスタの内包値を、シフトを使って取得し、論理積で
マスクするのが、メモリマップドI/Oでモジュールを扱う
場合の定石になります。
目次
前
次