アプリ版:「スタンプのみでお礼する」機能のリリースについて

 PICの初心者です。回路図を見て、基板を作れる程度、プログラムは書いてあるのを打ち込める程度で、意味はまったくわかりません。
 PIC16F84のPICでカウントする公開の回路を見つけて、光りセンサ-回路でON.OFFさせるかいろも作りました。プログラムは作成者のものです。 見て書き込んで、なんとかカウントしました。合計数は、わかりました。
質問は、
1,このプログラムを直して、1秒間あたり、何粒落ちるかカウントしたいと考えました。
 どのように、すれば良いのか教えてください。
2,合計のカウンタ-と秒速何粒落ちているかプログラムを1つのPICに入れて、動作の最初時に選 択できるようにしたいのですが、どのようにしたらよいでしょうか。
 PICの回路図とプログラム(テキスト形式)を下に添付しています。
  お願いします。私の連休中の宿題で困っています。
7セグメントLED表示4桁カウンタ
;(クロック 4MHz)
; [ ご注意 ]
;PIC プログラムには秋月電子製のライター・キットを使用しているため、アセン
;ブルにはキットに付属のアセンブラを使用しています。
;プログラム本体は PIC の基本命令だけでの構成に書き替えていますが、ヘッ
;ダー部分などが異なる場合がありますので、他のアセンブラを使用する場合は
;適宜変更してご利用下さい。

include16f84.h

.16f84
.oschs
.pwrton
.wdtoff
.protect off

countswequrb.0;カウント入力ポート

org0ch

d1ds1;カウント用
d2ds1
d3ds1
d4ds1

swlcds1;swait でのループ回数
sdds1;表示データ (0~9)
lcds1;汎用、ループ用

org0
gotostart
org4
gotostart

start;初期設定
bsf3h,5;ページ 1
movlw10000b
movwf85h;ポート ra の初期化
movlw00000001b
movwf86h;ポート rb の初期化
bcf3h,5;ページ 0

clrfd1;カウントデータの初期化
clrfd2
clrfd3
clrfd4

ct10:btfsccountsw;入力が 0 なら次をスキップ
gotoct12
callswait
btfsccountsw;入力が 0 なら次をスキップ
gotoct12;確かでないなら戻る

incfd1,1;加算
movlw10
subwfd1,0
btfss3h,2
gotoct11
clrfd1
incfd2,1
movlw10
subwfd2,0
btfss3h,2
gotoct11
clrfd2
incfd3,1
movlw10
subwfd3,0
btfss3h,2
gotoct11
clrfd3
incfd4,1
movlw10
subwfd4,0
btfss3h,2
gotoct11
clrfd4

ct11:callswait
btfsscountsw;入力が 1 なら次をスキップ
gotoct11;入力が 1 になるのを待つ
callswait
btfsscountsw;確かに入力が 1 に戻ったかを確認
gotoct11

ct12:movlw11111110b
movwfrb
movlw01101b
movwfra;桁4へ表示
movfd4,0
movwfsd
calll7ptset
callwait

movlw11111110b
movwfrb
movlw01110b
movwfra;桁 3 へ表示
movfd3,0
movwfsd
calll7ptset
callwait

movlw11111110b
movwfrb
movlw00111b
movwfra;桁 2 へ表示
movfd2,0
movwfsd
calll7ptset
callwait

movlw11111110b
movwfrb
movlw01011b
movwfra;桁 1 へ表示
movfd1,0
movwfsd
calll7ptset
callwait

gotoct10

;*********************************************************************
l7ptset:;sd に指定された 0~9 の数字をセットする

bcf3h,0;キャリフラグのクリア
rlfsd,1;4倍
rlfsd,1
movfsd,0;sd の値を w にコピー
addwfpc,1;プログラム・カウンタに加算

movlw00000010b;0
movwfrb
gotopt10
nop
movlw11100110b;1
movwfrb
gotopt10
nop
movlw10010000b;2
movwfrb
gotopt10
nop
movlw11000000b;3
movwfrb
gotopt10
nop
movlw01100100b;4
movwfrb
gotopt10
nop
movlw01001000b;5
movwfrb
gotopt10
nop
movlw00001100b;6
movwfrb
gotopt10
nop
movlw11100010b;7
movwfrb
gotopt10
nop
movlw00000000b;8
movwfrb
gotopt10
nop
movlw01100000b;9
movwfrb
pt10:
return

;*********************************************************************
swait:;カウント入力時のウェイト・ルーチン

movlw6;6回のループ
movwfswlc

swt10movlw11111110b
movwfrb
movlw01101b
movwfra
movfd4,0
movwfsd
calll7ptset
callwait

movlw11111110b
movwfrb
movlw01110b
movwfra
movfd3,0
movwfsd
calll7ptset
callwait

movlw11111110b
movwfrb
movlw00111b
movwfra
movfd2,0
movwfsd
calll7ptset
callwait

movlw11111110b
movwfrb
movlw01011b
movwfra
movfd1,0
movwfsd
calll7ptset
callwait

decfszswlc,1
gotoswt10

return

;*********************************************************************
wait:;ウェイトルーチン(1桁の表示時間)

movlw100
movwflc
wt10decfszlc,1
gotowt10
return

「PICで豆の1秒あたりのカウントプログラ」の質問画像

A 回答 (1件)

>回路図を見て、基板を作れる程度、プログラムは書いてあるのを打ち込める程度で、意味はまったくわかりません。



この状態では正直つらいですね。

まず、回路図ですが、RA0-RA3は表示する4桁の7セグメントLEDを選択するようになっています。
瞬間的には1桁ずつの7セグメントLEDを点灯していますが、高速に桁を切り替えることで全桁点灯しているように見えます。(目の残像です)
2SA1015はPNPトランジスタですので、RA0-RA2の各ビットを0にすることによりトランジスタがONします。(ct12やswt10でRA0-RA2を順番に1ビットだけ0を出力しているのはそのためです)
トランジスタがONすると7セグメントLEDのコモンに+5Vが供給されます。
RB1-RB7に電流制限抵抗を通して各セグメントのa-gのカソードが接続されています。
RB1-RB7を0にすることにより、コモンに供給された電流をPICに吸い込み、各セグメントが点灯します。
7セグメントLEDは複数セグメントを同時に通電し、数字パターンを表示します。
l7ptsetで各数字に対応したパターンが登録されています。
b0をのぞくb1-b7の0の部分が各数字に対する点灯するセグメントです。
rlf命令を2回繰り返し4倍しているのは、その後の各セグメントのデータを出力するプログラムが4ワードなので、4の倍数ごとに各桁のプログラムを作っているためでしょう。
それをプログラムカウンタに足すことにより各桁出力プログラムにジャンプしているのですね。


また、RB0は光センサが入力されると、0になるようになっています。(見てのとおりですね)
ct10, ct11でbtfsc, btfss でどちらの状態か確認しています。


質問文のプログラムですが、
start部分は、コメントにもあるように初期設定で、RA, RBポートの入出力関係の設定と変数のクリアを行っています。

ct10はセンサの入力を確認しています。
btfsc は countswが0の時は次の命令をスキップという命令で、
countsw = 0 のとき call swaitへ
countsw = 1 のとき goto12へ
となります。
再度センサの入力を確認し、明らかにセンサの入力が入っていれば、カウンタをアップ(d1-d4をカウントアップ)します。
その後、センサの入力がなくなるまで待って、各桁を表示するようになっています。

センサの入力がなければ、各桁の表示を繰り返します。

>1,このプログラムを直して、1秒間あたり、何粒落ちるかカウントしたいと考えました。
> どのように、すれば良いのか教えてください。

このような場合は、一般的にはタイマ割り込みで1秒間をカウントします。
その間に何回入力があったかをカウントします。
1秒たつと、そのカウントを別の変数(仮にpps)に記録し、カウンタはクリアします。
表示は、その変数(pps)を表示します。

通常ルーチンで今と同じようにカウントします。
割り込みルーチンで、1秒を検知したらカウント値の保存とクリアを行います。
16F84は8ビットタイマしかないので、内部タイマー割り込みを使い、何回かタイマー割り込みがかかったら1秒になるかをカウントして、その回数になったときに処理します。

クロックは4MHz(基本命令は4サイクルで1命令)で計算すれば、タイマー割り込みルーチンのカウントすうは近い値で計算できるでしょう。


>2,合計のカウンタ-と秒速何粒落ちているかプログラムを1つのPICに入れて、動作の最初時に選
> 択できるようにしたいのですが、どのようにしたらよいでしょうか。

RA4があいているので、そこにSWをつけて、表示を変えるのがかんたんでしょうね。
カウントは、合計用と1秒用と両方カウントすればいいと思います。


PIC16F84は有名なチップで日本語マニュアルもありますので、しっかり読んでください。
タイマー割り込みについても検索すれば、いろいろと見つかると思います。

org 4
goto start
とありますが、割り込みルーチンはここから記述します。

宿題がんばってください。
    • good
    • 0
この回答へのお礼

 このたびは、ご指導をいたただきありがとうございました。
おかげさまで、これがいかに大変かがわかったような気がします。
とても、1週間でなんとかなるものではありません。よほど気を入れないと大変です。
これは、ギブアップです。
 いつの日にか、機会があればがんばります。
 

お礼日時:2011/05/02 22:02

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!