PICで豆の1秒あたりのカウントプログラムについて

このQ&Aのポイント
  • PICの初心者です。回路図を見て、基板を作れる程度、プログラムは書いてあるのを打ち込める程度で、意味はまったくわかりません。
  • 質問は、1,このプログラムを直して、1秒間あたり、何粒落ちるかカウントしたいと考えました。どのように、すれば良いのか教えてください。2,合計のカウンタ-と秒速何粒落ちているかプログラムを1つのPICに入れて、動作の最初時に選 択できるようにしたいのですが、どのようにしたらよいでしょうか。
  • 問題点は、1、このプログラムでは1つずつカウントしているため、1秒間に何粒落ちるかを計測することはできません。2、合計のカウンターと秒速カウンターを1つのPICに組み込むためには、プログラムの一部を修正する必要があります。
回答を見る
  • ベストアンサー

PICで豆の1秒あたりのカウントプログラムについて

 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

質問者が選んだベストアンサー

  • ベストアンサー
  • paspas
  • ベストアンサー率52% (47/90)
回答No.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 とありますが、割り込みルーチンはここから記述します。 宿題がんばってください。

tomura12
質問者

お礼

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

関連するQ&A

  • PICで1秒間の豆の数をカウントするプログラム

     PIcの初心者です。回路図を見て、基板を作れる程度、プログラムは書いてあるのを打ち込める程度で、意味はまったくわかりません。  PIC16F84のPICでカウントする公開の回路を見つけて、光りセンサ-回路でON.OFFさせるかいろも作りました。プログラムは作成者のものです。 見て書き込んで、なんとか見事にカウントしました。合計数は、わかりました。 質問は、 1,このプログラムを直して、1秒間あたり、何粒落ちるかカウントしたいと考えました。  どのように、すれば良いのか教えてください。 2,合計のカウンタ-と秒速何粒落ちているかプログラムを1つのPICに入れて、動作の最初に選択 できるようにしたいのですが、どのようにしたらよいでしょうか。  PICの回路図とプログラム(テキスト形式)を添付しています。   お願いします。私の連休中の宿題で困っています。 7セグメントLED表示4桁カウンタ ; (クロック 4MHz) ; [ ご注意 ] ;PIC プログラムには秋月電子製のライター・キットを使用しているため、アセン ;ブルにはキットに付属のアセンブラを使用しています。 ;プログラム本体は PIC の基本命令だけでの構成に書き替えていますが、ヘッ ;ダー部分などが異なる場合がありますので、他のアセンブラを使用する場合は ;適宜変更してご利用下さい。 include 16f84.h .16f84 .osc hs .pwrt on .wdt off .protect off countsw equ rb.0 ;カウント入力ポート org 0ch d1 ds 1 ;カウント用 d2 ds 1 d3 ds 1 d4 ds 1 swlc ds 1 ;swait でのループ回数 sd ds 1 ;表示データ (0~9) lc ds 1 ;汎用、ループ用 org 0 goto start org 4 goto start start ;初期設定 bsf 3h,5 ;ページ 1 movlw 10000b movwf 85h ;ポート ra の初期化 movlw 00000001b movwf 86h ;ポート rb の初期化 bcf 3h,5 ;ページ 0 clrf d1 ;カウントデータの初期化 clrf d2 clrf d3 clrf d4 ct10: btfsc countsw ;入力が 0 なら次をスキップ goto ct12 call swait btfsc countsw ;入力が 0 なら次をスキップ goto ct12 ;確かでないなら戻る incf d1,1 ;加算 movlw 10 subwf d1,0 btfss 3h,2 goto ct11 clrf d1 incf d2,1 movlw 10 subwf d2,0 btfss 3h,2 goto ct11 clrf d2 incf d3,1 movlw 10 subwf d3,0 btfss 3h,2 goto ct11 clrf d3 incf d4,1 movlw 10 subwf d4,0 btfss 3h,2 goto ct11 clrf d4 ct11: call swait btfss countsw ;入力が 1 なら次をスキップ goto ct11 ;入力が 1 になるのを待つ call swait btfss countsw ;確かに入力が 1 に戻ったかを確認 goto ct11 ct12: movlw 11111110b movwf rb movlw 01101b movwf ra ;桁4へ表示 movf d4,0 movwf sd call l7ptset call wait movlw 11111110b movwf rb movlw 01110b movwf ra ;桁 3 へ表示 movf d3,0 movwf sd call l7ptset call wait movlw 11111110b movwf rb movlw 00111b movwf ra ;桁 2 へ表示 movf d2,0 movwf sd call l7ptset call wait movlw 11111110b movwf rb movlw 01011b movwf ra ;桁 1 へ表示 movf d1,0 movwf sd call l7ptset call wait goto ct10 ;********************************************************************* l7ptset: ;sd に指定された 0~9 の数字をセットする bcf 3h,0 ;キャリフラグのクリア rlf sd,1 ;4倍 rlf sd,1 movf sd,0 ;sd の値を w にコピー addwf pc,1 ;プログラム・カウンタに加算 movlw 00000010b ;0 movwf rb goto pt10 nop movlw 11100110b ;1 movwf rb goto pt10 nop movlw 10010000b ;2 movwf rb goto pt10 nop movlw 11000000b ;3 movwf rb goto pt10 nop movlw 01100100b ;4 movwf rb goto pt10 nop movlw 01001000b ;5 movwf rb goto pt10 nop movlw 00001100b ;6 movwf rb goto pt10 nop movlw 11100010b ;7 movwf rb goto pt10 nop movlw 00000000b ;8 movwf rb goto pt10 nop movlw 01100000b ;9 movwf rb pt10: return ;********************************************************************* swait: ;カウント入力時のウェイト・ルーチン movlw 6 ;6回のループ movwf swlc swt10 movlw 11111110b movwf rb movlw 01101b movwf ra movf d4,0 movwf sd call l7ptset call wait movlw 11111110b movwf rb movlw 01110b movwf ra movf d3,0 movwf sd call l7ptset call wait movlw 11111110b movwf rb movlw 00111b movwf ra movf d2,0 movwf sd call l7ptset call wait movlw 11111110b movwf rb movlw 01011b movwf ra movf d1,0 movwf sd call l7ptset call wait decfsz swlc,1 goto swt10 return ;********************************************************************* wait: ;ウェイトルーチン(1桁の表示時間) movlw 100 movwf lc wt10 decfsz lc,1 goto wt10 return

  • PICの誤動作についての質問です

    現在PIC18F24K20というPICを使用していて、2つの入力信号に対して、1ビットずつ判定を行いその2つの信号が間違っていればPORTBを+1してカウントしていくというプログラムを作っています。 RC0、RC2から信号を入力しています。Receive0でまずタイミングを合わせて、Receiveで間違っているかの判定を行うというプログラムです。 Receive0 BTFSS PORTC,0 ;RC0がHighなら次の命令をスキップ GOTO Receive0 NOP NOP NOP NOP NOP ;*** 入力信号の解析 Receive BTFSS PORTC,0 ;RC0がHighなら次の命令をスキップ GOTO ZERO BTFSS PORTC,2 ;RC2がHighなら次の命令をスキップ INCF PORTB,F ;PORTBを+1 NOP GOTO Receive ZERO BTFSC PORTC,2 ;RC2がLowなら次の命令をスキップ INCF PORTB,F ;PORTBを+1 NOP GOTO Receive (PORTの設定は省かせてもらっています) プログラムにおかしい点があれば指摘していただければうれしいです。 回路は入力をFPGAから直接RC0、RC2に入力して、PORTBも開放してロジアナで波形を観測しています。 ロジアナで見ると思っているような動作ではなく、PORTBが勝手にHighやLowになってしまっています。どのようなことが問題になっているのでしょうか?

  • PIC 初歩プログラムについて

    PICの初めてのプログラムを書いたのですがテキストのように動きません。 ORG 0 ; MAIN  BSF STATUS,RP0 MOVLW B'00000000' ;ポートB 出力 MOVWF TRISB ; MOVLW B'00001111' ;ポートA 0,1,2,3入力 MOVWF TRISA ; BCF STATUS,RP0 SW BTFSS PORTA,0 GOTO  LED1 BTFSS PORTA,1 GOTO LED2 GOTO SW LED1 MOVLW B'00000010' MOVWF PORTB GOTO SW LED2 MOVLW B'00000001' MOVWF PORTB GOTO SW END 入力SWを押していないときがHIです。したがって何もしなければSWのループになると思うのですが、LED2に行ってしまいます。BTFSC POARTA,1とすればSWループ状態ですがテキストとは違います。 何かおかしいのでしょうか?

  • PIC アセンブラ TMR0の使い方がいまいちわかりません。

    *文字数制限の為コメントや繰り返し処理プログラムの一部を省きました。解りにくくてすみません。ココに載せてくれとかあったらそっちに全部載せます。 目標としてはPICでデジタル時計を作りたいのですが、手始めに正確な1秒を作って7セグを0から9まで表示しそれを繰り返す。と言うものをやってみようと思いプログラムしましたがウンともスンとも言いません。 流れとしては 初期処理 ↓ TMR0割り込みが発生するまで無限ループ ↓ 割り込みが発生したら割り込み回数をカウントし(12,8MHzクロック、プリスケーラを256設定で1250回フラグをカウントすると1秒)1秒間分カウントが終わったら7セグの表示を切り替え無限ループに戻る どの数字まで表示したかは任意のレジスタに1を立てて判断する。PICはPIC16F628AなのでTMR1とかもあるんですが気分的にTMR0だけで時間を作ってみたかったのでTMR1とかは使ってません。で、3回くらいやり直してプログラムを作ったんですが全然動きません。 1、何処が悪いんでしょうか? 2、また、PIC16F628Aでは16番ピンがクロックの入力として使えますが その設定方法があってるかわかりません。 コンフィグ設定で OSCをHSにしてポートの設定でRA7を入力にしておけば良いんでしょうか?プログラム中の記述で合ってますでしょうか? 3,7セグをカウントアップするだけのプログラムなのに こんなに長くなる物なんですか? (プログラムが下手だから?アセンブラだから?) 4、1秒のカウント方法ですがプログラム中の記述で正確に1秒をカウントしてますか?(計算間違ってますでしょうか?) 以下、プログラムになります。 list p=pic16f628a include "p16f628a.inc" __CONFIG _LVP_OFF &_MCLRE_ON &_BODEN_OFF &_PWRTE_ON &_WDT_OFF &_HS_OSC time0 equ d'30' ;time4まで作る tcount equ d'43' count0 equ d'35' ;count7まで作る koko0 equ d'43' koko1 equ d'44' org 0 goto start org 4 goto wari start bcf intcon,gie movlw b'00000111' movwf cmcon bsf status,rp0 movlw b'00000111' movwf option_reg movlw b'10100000' movwf trisa clrf trisb bcf status,rp0 bcf status,z bcf intcon,t0if movlw b'00001000' movwf count0 ;この間に1から6の同じ処理が入ります。 movlw b'00000000' movwf count7 time movlw .30 movwf time0 bsf intcon,gie bsf intcon,t0ie clrf tmr0 roop btfsc tcount,0 call segout swapf count0,0 movwf portb swapf portb,0 movwf count0 ;この間に1から5が入ります swapf count6,0 movwf portb swapf portb,0 movwf count6 goto roop wari bcf intcon,t0ie bcf intcon,t0if incf time0,1 btfss status,z goto modori bcf status,z movlw .255 movwf time0 incf time1,1 bcf status,z goto modori bcf status,z movlw .255 movwf time0 movlw .255 movwf time1 incf time2,1 bcf status,z goto modori bcf status,z movlw .255 movwf time0 movlw .255 movwf time1 movlw .255 movwf time2 incf time3,1 bcf status,z goto modori bcf status,z movlw .255 movwf time0 movlw .255 movwf time1 movlw .255 movwf time2 movlw .255 movwf time3 incf time4,1 bcf status,z goto modori bcf status,z movlw .30 movwf time0 movlw b'00000001' movwf tcount modori bsf intcon,t0ie retfie segout clrf tcount btfss koko0,0 goto seg1 ;この中間にseg2からseg6が入ります。 btfss koko0,7 goto seg8 btfss koko1,0 goto seg9 nop goto seg0 seg1 bsfkoko0,0 movlw b'00000010' movwf count0 movlw b'00000100' movwf count1 movlw b'00000000' movwf count2 movlw b'00000000' movwf count3 movlw b'00000000' movwf count4 movlw b'00000000' movwf count5 movlw b'00000000' movwf count6 movlw b'00000000' movwf count7 nop return ;この中間にseg2からseg9が入ります seg0 clrf koko1 clf koko0 movlw b'00001000' movwf count0 movlw b'00000100' movwf count1 movlw b'00000010' movwf count2 movlw b'00000001' movwf count3 movlw b'10000000' movwf count4 movlw b'01000000' movwf count5 movlw b'00000000' movwf count6 movlw b'00000000' movwf count7 return end

  • PIC16F84Aで入力があるとスタートするプログラム

    PIC16F84Aで、アセンブリ言語でプログラムをしています。 RA4を入力端子とし、入力があればプログラムがスタートするということをしたいんですけどうまくいきません。 私の作ったプログラムはこのようになっています。  listp=16f84A   include <p16f84A.inc>  __CONFIG _HS_OSC & _PWRTE_ON & _WDT_OFF tim1   EQU  0x20      org  0x00      NOP      GOTO start start      BSF  STATUS,RP0      MOVLW B'00010000'      MOVWF TRISA      CLRF TRISB      BCF  STATUS,RP0      MOVLW B'00010000'      MOVWF PORTA      CLRF  PORTB main      MOVLW  001h      MOVWF  tim1 timlp1  BTFSC  PORTA,5      CALL   playball      GOTO   main playball      MOVLW  B'00001111'      MOVWF  PORTA      MOVLW  B'11111111'      MOVWF  PORTB      RETURN 修正点などありましたら教えて下さい。

  • PIC(デジタル電圧計のプログラム)について教えてください

    今回PIC16F819を用いてデジタル電圧計作成しています。 仕様は1点(0ch)0~5V  7セグメントLEDにより0.0~4.9まで表示。 というものです。 とりあえず考えてはみましたが、0.1単位で表示させるときはどうしたらよいのでしょうか。 右側の7セグメントLEDが9になったら左側を+1して、4.9になったら0にクリアする・・という部分はなんとかできる気がするのですが・・ (今このプログラムにその部分はありません) ちなみにできたプログラム内容はICに書き込み、ブレッドボード上の回路に入れて使用します。 その時2進の情報でも7セグメントで表示されるので、その部分のプログラムは必要ありません。 (0001は1,0010は2と表示される) __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF     TCNT    EQU    20H     ORG     0x000     GOTO    MAIN MAIN     BSF    STATUS,RP0     CLRF   TRISB     MOVLW   081H     MOVWF   OPTION_REG     MOVLW   00EH     MOVWF   ADCON1     MOVLW   001H     MOVWF   TRISA     BCF    STATUS,RP0 LOOP     MOVLW   081H     MOVWF   ADCON0     CALL   ADWAIT     BSF   ADCON0,GO WAIT     BTFSC   ADCON0,GO     GOTO   WAIT     MOVF   ADRESH,W     MOVWF   PORTB     CALL   ADWAIT     GOTO   LOOP ADWAIT     MOVLW   020H     MOVWF   TCNT     NOP TLOOP     DECFSZ  TCNT     GOTO   TLOOP     RETURN 初心者でテキストを見ながら必死でやっているので、 できれば解説もお願いします。 何か補足としてほしい情報があればまたご連絡ください。 よろしくお願いします。

  • PICでLEDを点滅させる

    16F628Aを使ってLEDが点滅するプログラム作ることはできたのですが、それを16F873A用に組み替えてみたのですが点滅せずに点灯したままになります。ハード的な問題なのかそれともプログラム問題なのかがわかりません。マイコンの勉強をはじめたばかりなのでお教えいただければたすかります。 ちなみにプログラムは以下のようになっています。クロックは10MHzです。 開発環境はMPLABをつかっていて秋月のキットを使って書き込んでいます。 ; ; ; list p=pic16f873a #include <P16F873A.INC> __CONFIG _WDT_OFF & _HS_OSC & _CP_OFF & _PWRTE_ON & _LVP_OFF COUNT EQU 20H COUNT1 EQU 21H ORG 0 MAIN BSF STATUS,RP0 CLRF TRISA CLRF TRISB CLRF TRISC BCF STATUS,RP0 MOVLW B'11111111' MOVWF PORTC CALL LA CLRF PORTC CALL LA GOTO MAIN LA MOVLW B'11111111' MOVWF COUNT LOOP2 MOVLW B'11111111' MOVWF COUNT1 LOOP NOP NOP NOP NOP NOP NOP NOP DECFSZ COUNT1,1 GOTO LOOP DECFSZ COUNT,1 GOTO LOOP2 RETURN END

  • PIC16F84Aから16F628Aの変換について

    以前PIC16F84Aで問題なく動作しているプログラムを 初期設定を変えて(これでいいのか?も疑問)16F628Aで動かそうとしていますが サブルーチンに入り「タイマー」のルーチンから抜け出せないみたいです。 BILD ALL ではエラーは出ません。 割込みは正常に動作します。 どこがいけないのでしょうか? よろしくお願いいたします。 プログラムはこちらです。 ;------------------------------------------------------------------------- ;     初期設定 list P=pic16f628a include "p16f628a.inc" __CONFIG _HS_OSC & _CP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _LVP_OFF & _MCLRE_OFF ORG 0 GOTO MAIN ;----------------------------------------------------------------------- ; 割り込み処理 ORG 4     ;割り込みアドレス CLRW CLRF PORTB     ;ポートBクリア GOTO MAIN ;----------------------------------------------------------------------- ; メインプログラム MAIN   BCF STATUS,RP0          MOVLW B'00000111'         MOVWF CMCON         BSF INTCON,INTE     ;割りこみ許可?          BSF STATUS,RP0     ;ポートAを全て入力に設定         MOVWF TRISA          MOVLW H'01'     ;ポートBは0(ゼロ)以外は出力に設定         MOVWF TRISB         MOVLW 90H     ;INT割り込み許可         MOVWF INTCON         BCF STATUS,RP0     ;ポートBをクリア         CLRF PORTB          CLRW ;---------------------------------------------------------------------- ; スイッチ入力チエック LOOP    BTFSS PORTA,0     ;オープンSWがONか?          GOTO OPEN      ;ONだったら OPENへ         GOTO LOOP ;----------------------------------------------------------------------- ; オープン動作 OPEN    MOVLW 010H      ;ポートB4番に5V出力(リレーON)          MOVWF PORTB        MOVLW D'250'      ;動作時間 '250'設定         MOVWF 0EH      ;アドレス0EHに250を入力          CALL LOOP3      ;サブルーチンLOOP3を呼び出す        GOTO MAIN      ;サブルーチンが終わったら MAIN に戻れ ;------------------------------------------------------------------------ ;----------------------------------------------------------------------- ; サブルーチン(タイマー) TIMER1    MOVLW D'220'           MOVWF 0CH LOOP1    NOP           DECFSZ 0CH,1           GOTO LOOP1         RETURN TIMER2     MOVLW D'100'      ;アドレス0DHに100を入力          MOVWF 0DH LOOP2    NOP           CALL TIMER1      ;TIMER1を呼び出し(行く)           DECFSZ 0DH,1      ;アドレス0DH から1を引き算する           GOTO LOOP2      ;結果が"0"でなかったら LOOP2に戻ってまた引き算          RETURN       ;引き算の結果が"0"になったら「CALL」した「次に(下)」へ戻る LOOP3    NOP      ;何もしない          CALL TIMER2      ;TIMER2を呼び出す(行く)         DECFSZ 0EH,1         GOTO LOOP3          RETURN END    END

  • このプログラムがどういう流れで動いてるか教えてください

    PICのプログラミングで以下の課題が学校ででました。 PB0~PB5まで1秒ごとに交互に点灯するプログラムを書くというものです。 CNT1 EQU 20H CNT2 EQU 21H main MOVLW B'00010101' MOVWF PORTB CALL TIM2 MOVLW B'00001010' MOVWF PORTB CALL TIM2 GOTO main TIM1 MOVLW 0F9H MOVWF CNT1 TIMLP1 NOP DECFSZ CNT1,F GOTO TIMLP1 RETURN TIM2 MOVLW 08H MOVWF CNT2 TIMLP2 CALL TIM1 DECFSZ CNT2,F GOTO TIMLP2 RETURN END 上記のプログラムで動きました。 だけど、このプログラムの流れがわからないため 説明できません。 誰かこのプログラムの流れをわかりやすく説明してください。 特にCALLとRETURN、DECFSZがどう動くかわかりません。

  • PICでのアップダウンカウンタについて

    以下のプログラムはポートAにアップカウントSWとダウンカウントSW付けて 8bitの2進数データをアップダウンさせるプログラムですが、下限と上限を決めて それ以上、以下カウントしないようにプログラムを変更したいのですが、どうすればいいと思いますか? ちなみにこのプログラムだと255(0)までカウントしたら0(255)に戻ります 下限は 0b00000000(0) 上限は 0b01100100(100) です。 コンフィギュレーション、CALL TIMELOOP1はチャタリング対策のプログラムなので省略して投稿します。 MAIN BTFSS PORTA,1;RA1のスイッチがOFF(1)なら次行をスキップ GOTO COUNTUP;カウントアップへ BTFSS PORTA,0;RA0のスイッチがOFF(1)なら次行をスキップ GOTO COUNTDOWN;カウントダウンへ BTFSS PORTA,2;RA0のスイッチがOFF(1)なら次行をスキップ GOTO MAIN;カウントダウンへ BTFSS PORTA,3;RA0のスイッチがOFF(1)なら次行をスキップ GOTO MAIN;カウントダウンへ GOTO MAIN COUNTUP BTFSS PORTA,1;RA1のスイッチがOFF(1)になったら次行をスキップ GOTO $-1;上の行へ戻る CALL TIMELOOP1;チャタリング対策 INCF COUNT,F;COUNT値を1増やして、 MOVF COUNT,W;Wレジスタに書き込み、 MOVWF PORTB;PORTBへ送る。 GOTO MAIN COUNTDOWN BTFSS PORTA,0 GOTO $-1 CALL TIMELOOP1 DECF COUNT,F;COUNT値を1減らして、 MOVF COUNT,W;Wレジスタに書き込み、 MOVWF PORTB;PORTBへ送る。 GOTO MAIN

専門家に質問してみよう