デジタル電圧計作成についての質問

このQ&Aのポイント
  • デジタル電圧計作成において、0.1単位で表示させる方法について質問です。
  • 現在作成中のデジタル電圧計は、PIC16F819を使用し、1点(0ch)0~5Vの範囲を7セグメントLEDで表示するものです。
  • また、プログラムの一部の処理についても疑問があるようです。
回答を見る
  • ベストアンサー

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 初心者でテキストを見ながら必死でやっているので、 できれば解説もお願いします。 何か補足としてほしい情報があればまたご連絡ください。 よろしくお願いします。

noname#46996
noname#46996

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

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

プログラムで書くと長くなりそうなので考え方だけ書きます。 ・少数を扱うと面倒なので内部電圧値として0から49の数値として扱います。 ・ADコンバートして得れる値は10ビットですから0から1023までの値をとります。これを21で割ると内部電圧値として0から48までの数値になります。誤差多いですかね?(割り算は、いちばん簡単な引ける回数をカウントする方法で計算します) ・上位桁と下位桁は、内部電圧値を10で割ったら上位桁で、下位桁は余りです。これをそれぞれのLEDに表示すれば0.0vから4.8vまで表示可能です。 [+α案] (1)遅くなるが精度を上げる方法。 ・ADコンバートで入力された値を10倍して、これを204で割ります。これで0から50の値を得ることができます。この値の方が精度が高くなります。 (2)とてもアセンブラな方法。 ・ADコンバートした値をADとします。 ・ADを右へ1ビットシフトして1/2にします。これをAD05とします。 ・ADとADとADを足してAD3を作ります。 ・AD3とAD3を足してAD6を作ります。 ・AD6とAD6を足してAD12を作ります。 ・AD12とAD05を足して、AD125を作ります(12.5倍したことになります)。 ・AD125を右へ8ビットシフトして1/256にします。これで0から49の数値が得られます。これが一番精度が高くて高速な方法です。 疑問があったら質問してください。

noname#46996
質問者

お礼

お返事ありがとうごぜいます。 お礼が遅れてごめんなさい。 たくさん書いていただいたのですがよく理解できないのでまた質問させていただいてもいいでしょうか?? 初歩的なものばかりで申し訳ないのですが・・ [+α案]の(2)についてなのです。 何がわからないかがうまく説明できないので質問が難しいのですが。 ・なぜ1/256するのですか?256=2^8ですよね。出力のビット数で割ると何がわかるのでしょうか?? ・なぜ1/256するのにまず12.5倍するのですか? ・ポートBの8ビットを7セグメントの上位下位に分けて出力するときに、どのようにすれば00~49という値が手に入るのでしょうか。 ・・なんだか質問もあいまいになってしまいましたが・・ よろしかったらまたお答お願いします。

その他の回答 (16)

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.17

大事なことは、まずハードの動作を確認することです。 次の事は一回でも、試しましたか? (1)2つのLEDにそれぞれ、0,1,2,4,8が表示できることを確認する。全部の結線が正しいかこれで確認できる。 (2)AN0からちゃんと入力されているか?ADRESHの値をそのままPORTBに出力して電圧でLEDの表示が変化することを確認する。もちろん16進の値を与えるのでLED表示はデタラメだが、とりあえずAN0に反応していることは確認できる。 これらをクリアしたら、初めてソフトの検証に入りましょう。 ソフトの方は、合っているように見えますがシミュレートしてみないと分かんないですね。

noname#46996
質問者

お礼

ありがとうございます。 おかげ様でなんとかうまく走らせることができました。 いろいろとお世話になりました。 何度も何度もご迷惑をおかけしてごめんなさい。 本当にありがとうございます!

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.16

>あと、また質問で申し訳ないのですが、 >入力を0chと1chの2つにして、1秒ごとにそれぞれの値を出力することってできますかね?? >その場合、どういったプログラムを追加すべきですか?? >交互に表示っていうのは無理でしょうか? 切り替えることは全然問題ありません。追加するの物。 (1)どちらを表示しているかを覚えておくメモリ。1秒毎に値をXORなどで反転してやる。その値をみてAN0かAN1かをADCON0で切り替える。 (2)タイマーを使って1秒を計測する処理。タイマー1を使います。クロックからタイマーの周期を自分でちゃんと計算しましょう(PICの回路図がわからないのでアドバイスできませんです)。 参考↓ http://www.page.sannet.ne.jp/ja1hwo/pic/pic_25.htm って参考先を見て思い出しました。 8ビットのPICってSFRのバンク切り替え制御をする必要がありました。最近16ビットのdSPICばっかりだったので忘れてましたよ。 16ビット計算の方でADRESLを使うときは BSF STATUS,RP0 と BCF STATUS,RP0 を追加してください。

noname#46996
質問者

お礼

ありがとうございます。 また考えてみますね。 あと、今リファレンス電圧5.1で走らせてみてるんですけど・・ 7セグメントの表示が変わりません; 電圧をあげていってもいっこうに0のままです。 考えられる原因はなんですかね? 参考までに現在のプログラムです↓ LIST P=PIC16F819 #INCLUDE<P16F819.INC> __CONFIG _HS_OSC & _CP_OFF & _WDT_OFF & _PWRTE_ON & _MCLR_ON & _LVP_OFF     CNT EQU 020H     SHOU EQU 021H     AMARI EQU 022H     TMP EQU 023H ORG 0H MAIN     BSF STATUS,RP0     MOVLW 01H     MOVWF TRISA     MOVLW 00H     MOVWF TRISB     MOVLW 00DH     MOVWF ADCON1     BCF STATUS,RP0     MOVLW 081H     MOVWF ADCON0     CLRF PORTA     CLRF PORTB     CLRF SHOU ADSTART     CALL TIME20U     BSF ADCON0,GO ADLOOP     BTFSC ADCON0,GO     GOTO ADLOOP     MOVF ADRESH,W     MOVWF TMP     MOVLW 5     CALL WARI     MOVF SHOU,W     MOVWF TMP     MOVLW 10     CALL WARI     CALL LED     GOTO ADSTART WARI     SUBWF TMP     BTFSS STATUS,C     RETURN     INCF SHOU     GOTO WARI LED     ADDWF TMP SWAPF SHOU,W     IORWF AMARI,W     MOVWF PORTB     RETURN TIME20U     MOVLW 020H     MOVWF CNT     NOP LOOP     DECFSZ CNT,F     GOTO LOOP     RETURN     END お時間があればまたよろしくお願いします。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.15

>MOVLW 00DH >MOVWF ADCON1 >の部分で左詰めにしたつもりなんですが・・違ってましたか? 00DHなら左詰め、08DHなら右詰ですので正解です。 >それから、シミュレータやってみたんですけどエラーがでてしまって・・; >また時間のあるときにゆっくり読んで試してみますね。 >どうもありがとうございます。 アセンブルは出来てますよね? アセンブルが通らないとシミュレーションできませんよ。 >シミュレーション前で申し訳ないのですが、もしおかしなところがあればご指摘おねがいします。 惜しいです。 CALL LED のあと、 GOTO ADSTART が抜けてます。 あとは大丈夫に見えますので、ぜひ走らせて見てください。

noname#46996
質問者

お礼

ありがとうございます。 今日か明日にでも走らせて見ますね。 あと、また質問で申し訳ないのですが、 入力を0chと1chの2つにして、1秒ごとにそれぞれの値を出力することってできますかね?? その場合、どういったプログラムを追加すべきですか?? 交互に表示っていうのは無理でしょうか?

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.14

>ただ、上位8ビットだけを使って計算することってできるんですか? >私は、0~255ではなくて、0~1023だと思ってました。(勝手に10ビットに割り当てられるのかなと・・) ADCON1のADFMビットでADコンバートの右詰/左詰を切り替えることができます。左詰にするとADRESHに上位8ビットが割り当てられますので、そこを見る限りは0~255の値です。最初のプログラムはそうなってますよね? 逆に右詰にするとADRESHとADRESLで合わせて0~1023の10ビットの値を扱うことができます。細かい精度がほしくなければ8ビットで十分ですから。 >プログラムはシミュレータにかけていません。 >MPLABの入ってないパソコンで作っていたので; >ごめんんさい。 >次からは注意します。 PICマイコンが無くてもMPLABは使えますので、ぜひインストールしてください。シミュレータで動作を確認することが理解の早道です。PICマイコンが無くても動作を確認できるなんてすごく便利なんですから。

noname#46996
質問者

お礼

お返事ありがとうございます。 左詰めにするとADRESHに上位8ビットが割り当てられるんですね。 分りました。どうもです。 ひとつ前に書いたプログラムも MOVLW 00DH MOVWF ADCON1 の部分で左詰めにしたつもりなんですが・・違ってましたか? それから、シミュレータやってみたんですけどエラーがでてしまって・・; また時間のあるときにゆっくり読んで試してみますね。 どうもありがとうございます。 とりあえず5で割ることの意味がやっとわかりました。 サブルーチン化したほうがよいとのことだったので、 ADLOOP     ・     ・     ・    MOVWF  TEMP    MOVLW  5    CALL  WARI    MOVF  SHOU,W    MOVWF  TEMP    MOVLW  10    CALL  WARI    CALL  LED WARI    SUBWF  TEMP    BTFSS  STATUS, C    RETURN    INCF   SHOU    GOTO   WARI としてみました。 シミュレーション前で申し訳ないのですが、もしおかしなところがあればご指摘おねがいします。 本当に何度も何度もごめんなさい。 ありがとうございます。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.13

>ADRESHだけを取り出して割っていくのでよかったですか?? 5で割り忘れてます。250を10で割っていますよ。0~9の間の値しかLEDには表示できません。 それと2回割り算するので、TIME20Uの様に割り算をサブルーチン化したほうが良いでしょう。 このプログラムは、ちゃんとシミュレータで走らしてみましたか? 走らせていれば問題に気づいたはずです。 私の言う通り作っていても理解したことになりませんよ。VDDが5.12Vは間違ってましたが、この間違いを指摘できるぐらいの理解度を目指してくださいね。 理解しないでプログラムを作っても今後の応用が利きませんから、理解するのことを最優先でやりましょう。

noname#46996
質問者

お礼

ありがとうございます。 何で5.1Vに設定すればよいのかも分りました。 ただ、上位8ビットだけを使って計算することってできるんですか? 私は、0~255ではなくて、0~1023だと思ってました。 (勝手に10ビットに割り当てられるのかなと・・) プログラムはシミュレータにかけていません。 MPLABの入ってないパソコンで作っていたので; ごめんんさい。 次からは注意します。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.12

>なんでVDDを5.12にすれば5VのときにADRESHの値が250になるんですか?? 上位8ビットを利用する設定でかつリファレンス電圧がVDDの設定でADコンバータを動かす前提で話します。 ADコンバータは、リファレンス電圧を基準に電圧を数値化します。ADRESHは0から255の間を取りますが、VDDと同じ電圧のとき255の値をとります。 あっと、しまった。今気づきましたがVDDは5.1Vが正しいですね。訂正します。 例を書きます。 ADRESHが255←AN0の入力電圧が5.1V ADRESHが250←AN0の入力電圧が5.0V ADRESHが200←AN0の入力電圧が4.0V となります。 電圧の変化と数値の変化は等比例することが、5.0Vで250だと言い切れる理由です。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.11

>RA3に最高電圧を定める媒体をおいて、RA2はグランドにいれればなるかなぁって思ったんですけど違いますか?? それでもできます。ただし、電圧がVDD+0.3Vを超えると壊れる可能性があるので注意してください。 >VDDが5.12という整数以外の数にできるかはわかりませんが・・ データシートを見るとわかりますが、PIC16F819は電源電圧(VDD)が4.0V~5.5Vの間の電圧なら何Vでもかまいません。だから、可変電圧レギュレータICで5.12Vを電源電圧にできます。デジタルテスターで計るとわかりますが電圧なんて正確に5.00Vが出ている可能性はほとんどZEROですよ。5Vの電源レギュレータICを通していても正確に5Vじゃないのを知識として知っておいてください。 >あと、そうするとなぜすべて8ビットで計算できるのかを詳しく教えていただいてもよろしいですか?? AN.07で答えてますよ。

noname#46996
質問者

お礼

お返事どうもです。 前答えていただいたのって >5Vの時にADRESHの値が250になる様にハード的に調整します。 >250を5で割ると50ですから、5Vの時50という値が得られるようになります。 >あとは、10で割った値と余りをLEDに表示するだけです。 ですよね。 なんでVDDを5.12にすれば5VのときにADRESHの値が250になるんですか??

noname#46996
質問者

補足

あと、一応書いてみたのですが・・ LIST P=PIC16F819 #INCLUDE<P16F819.INC> __CONFIG _HS_OSC & _CP_OFF & _WDT_OFF & _PWRTE_ON & _MCLR_ON & _LVP_OFF     CNT    EQU   020H     SHOU   EQU   021H     AMARI   EQU   022H     TMP    EQU   023H          ORG    0H MAIN     BSF    STATUS,RP0     MOVLW   01H     MOVWF   TRISA     MOVLW   00H     MOVWF   TRISB     MOVLW   00DH     MOVWF   ADCON1     BCF    STATUS,RP0     MOVLW   081H     MOVWF   ADCON0     CLRF   PORTA     CLRF   PORTB ADSTART     CALL   TIME20U     BSF   ADCON0,GO ADLOOP     BTFSC   ADCON0,GO     GOTO   ADLOOP     MOVF   ADRESH,W     MOVWF   TMP     CLRF   SHOU     MOVLW   10 LOOP1     SUBWF   TMP     BTFSS   STATUS,C     GOTO   LED     INCF   SHOU     GOTO   LOOP1 LED     ADDWF  TMP     SWAPF  SHOU,W     IORWF  AMARI,W     MOVWF  PORTB     GOTO   ADSTART TIME20U     MOVLW  020H     MOVWF  CNT     NOP     LOOP     DECFSZ CNT,F     GOTO  LOOP ADRESHだけを取り出して割っていくのでよかったですか??

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.10

>何[V]を1024で割るかを決められるようで、考え方によってはもう少し楽なプログラムができるんじゃないかなと思ってるんですけど・・ そんな制御ができるレジスタは聞いたことが無いです。 何レジスタのどのビットの事でしょうか? ADコンバータの変換クロックと勘違いしていませんか? 私としては、VDDを5.12Vにしてやるのが一番簡単だと思いますけど。そうすれば5Vの時にADコンバータの上位8ビットの値が250になるので、全て8ビットで計算できます。

noname#46996
質問者

お礼

いつも素早い返答をありがとうございます。 ADCON1の設定を00CHにすればなりませんかね? ADCON1の下位は以下のようになっていています。 PCFG AN4 AN3 AN2  AN1 AN0 VREF+ VREF- C/R 1101 D VREF+ VREF-  A  A   AN3  AN2  2/2 1110 D  D    D   D  A   AVDD AVSS 1/0 (RA3/AN3/VREF+,RA2/AN2/VREF) RA3に最高電圧を定める媒体をおいて、RA2はグランドにいれればなるかなぁって思ったんですけど違いますか?? VDDが5.12という整数以外の数にできるかはわかりませんが・・ あと、そうするとなぜすべて8ビットで計算できるのかを詳しく教えていただいてもよろしいですか??

noname#46996
質問者

補足

↓ごめんなさい。表がずれましたね。 また00DHにすれば・・の間違いでした。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.9

補足事項。 MPLABにソフトシミュレーション機能があるのを知っていますか? この機能を使うと1ステップづつ命令動作を確認することが出来ます。 http://www.picfun.com/mplab00.html 勉強になりますので、ぜひ使ってみてください。 私に質問する前に、これで動作確認した上で疑問があったら聞いてもらえると効率良く作業を進めることが出来ると思います。

noname#46996
質問者

お礼

今調べたところ、PIC16F819の設定でリファレンス電圧を決めることができるみたいです。 何[V]を1024で割るかを決められるようで、考え方によってはもう少し楽なプログラムができるんじゃないかなと思ってるんですけど・・ そんなことないですかね??

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.8

チェックが遅くなりましたが、まだ問題が何点かあります。 あくまで目検で見つけただけの問題なので、実際に走らせると別の問題がでるかもしれません。 問題点のある周辺のソースだけをコメントしました。 ; 3回を一度に足すのは駄目。キャリー(C)値が正常ではなくなるため。 BCF STATUS,C ;これは意味が無いです。RRFの時は意味あり。 MOVF ADRESL ;AD→AD? MOVF ADRESL,Wが正解。 ADDWF ADRESL ;AD+AD→AD? ADDWF ADRESL,Wが正解。 ; ここで上位の桁の処理を先にすること。今の流れだとキャリー値が壊れます。 ADDWF ADRESL ;AD+AD+AD→AD MOVWF AD3L ;W→AD3L ADDWF AD3L,F ;AD3L+W→AD3Lで意味不明?横にコメント書くとミスに気づきやすいですよ。 ; この計算は全てやり直しのこと。 MOVF ADRESH BTFSC STATUS,C INCF ADRESH,W ADDWF ADRESH BTFSC STATUS,C INCF ADRESH,W ADDWF ADRESH MOVWF AD3H BTFSC STATUS,C INCF ADRESH,W ADDWF AD3H,F ; MOVFのWの書き忘れが多いです。 BCF STATUS,C ;不要です。 MOVF AD3L MOVWF AD6L ADDWF AD6L,F MOVF AD3H BTFSC STATUS,C INCF AD3H,W ADDWF AD6H,F ;AD6Hの値が不定のまま、AD3Hに加算されています。 ; MOVFのWの書き忘れが多いです。 BCF STATUS,C ;不要です。 MOVF AD6L MOVWF AD12L ADDWF AD12L,F MOVF AD6H BTFSC STATUS,C INCF AD6H,W ADDWF AD12H,F ;上と同じです。 ; ん?AD12H,AD12Lの内容は足しこまれていません。 BCF STATUS,C MOVF AD05L MOVWF AD125L ADDWF AD125L,F MOVF AD05H BTFSC STATUS,C INCF AD125H,W ADDWF AD125H;Wに残さないと。 MOVWF TMP ;上位8bitを移動。W→TMPと転送する場合はWに最終値が必要です。 ; AD3,AD6,AD12,AD125は全て同じメモリにまとめた方が転送の無駄が減って楽かもしれません。どちらがプログラム的に分かりやすいか検討して決めてください。 ; 割り算ルーチン。OKかな。 CLRF SHOU MOVLW 10 LOOP1 SUBWF TMP BTFSS STATUS,C GOTO LED INCF SHOU GOTO LOOP1 LED ADDWF TMP SWAPF SHOU,W IORWF AMARI,W ;あまりはTMPに入っています。AMARIは未使用。 MOVWF PORTB GOTO ADSTART

関連するQ&A

  • PIC16F819とMAX232Cについて困っています。

    まだ駆け出しでわからないことだらけで、以下のプログラムをふまえてPIC16F819とMAX232C(RS232C?)を接続したいのですが、どうプログラム(アセンブラ)を追加したら、また回路的にどうしたらいいのかわからないので教えてください。以下のプログラム(コメント省略)は、電圧変化により出力(LEDの点灯数の変化)を行ったものです。 LIST p=PIC16F819 #include <P16F819.inc> __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _LVP_OFF AD_DATA_H EQU 20h AD_DATA_L EQU 21h WAITCOUNT EQU 22h ORG H'00' GOTO START ORG H'04' GOTO START ;------------------------------ ; 初期設定 ;------------------------------ START BSF STATUS, RP0 BCF ADCON1, ADFM BCF ADCON1, ADCS2 BSF ADCON1, PCFG3 BSF ADCON1, PCFG2 BSF ADCON1, PCFG1 BCF ADCON1, PCFG0 MOVLW B'00000001' MOVWF TRISA MOVLW B'00000000' MOVWF TRISB BCF STATUS, RP0 CLRF ADCON0 CLRF PORTA CLRF PORTB ;------------------------------- ; メインルーチン ;------------------------------- MAIN CALL AD_CONVERT MOVLW b'10000000' SUBWF AD_DATA_H, W BTFSC STATUS, C GOTO V_UPPER_HALF GOTO V_LOWER_HALF V_UPPER_HALF MOVLW b'11000000' SUBWF AD_DATA_H, W BTFSC STATUS, C GOTO V_3_4 GOTO V_1_2 V_LOWER_HALF MOVLW b'01000000' SUBWF AD_DATA_H, W BTFSC STATUS, C GOTO V_1_4 GOTO V_ZERO V_3_4 MOVLW b'00000111' MOVWF PORTB GOTO MAIN V_1_2 MOVLW b'00000011' MOVWF PORTB GOTO MAIN V_1_4 MOVLW b'00000001' MOVWF PORTB GOTO MAIN V_ZERO MOVLW b'00000000' MOVWF PORTB GOTO MAIN ;--------------------------------- ; A/D 変換サブルーチン ;--------------------------------- AD_CONVERT MOVLW B'10000001' MOVWF ADCON0 CALL WAIT_100U BSF ADCON0, GO BTFSC ADCON0, GO GOTO ADLOOP MOVF ADRESH, W MOVWF AD_DATA_H MOVF ADRESL, W MOVWF AD_DATA_L RETURN ;------------------------------------------------------------ ; 100usec ( 100usec = 0.2u/Cycle at 20MHz x 500 ) ;------------------------------------------------------------ WAIT_100U MOVLW D'165' MOVWF WAITCOUNT WAIT_100UL DECFSZ WAITCOUNT,F GOTO WAIT_100UL RETURN END 長くなりましたがご教授どうかお願いします。

  • PICのスイッチのプログラムについて

    基本的な事なのですが、よろしくお願いします。 以下のアセンブラのソースでPICを作ってみました。プログラムを変えてみたり、回路を変えてみたりしましたが、改善されませんでした。回路の構成は、LED(仮に、A・Bとします)2個、スイッチ1個、PIC、抵抗器など・・・これを交互にスイッチのオンオフで切り替える。としています。現状の問題点は、スイッチ入力で、LEDAは光るときは綺麗に光りますし、消えるときは綺麗に消えます。問題は、LEDBのほうで、光るときに高速で点滅します。理由と対策が解りません。どなたか教えてください。よろしくお願いします。 list p=16f628a #include<p16f628a.inc> __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF ORG 0x000 goto main ORG 0x004 main bcf STATUS,RP0 bcf STATUS,RP1 clrf INTCON clrf PORTA movlw 0x07 movwf CMCON bsf STATUS,RP0 bsf PCON,OSCF clrf TRISB movlw 0x03 movwf TRISA bcf STATUS,RP0 clrf PORTA clrf PORTB main_loop btfsc PORTA,0;この辺りがよくわかりません。 goto loop2 bsf PORTB,0 bcf PORTB,1 goto main_loop loop2 bcf PORTB,0 bsf PORTB,1 goto main_loop END

  • 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、USART USART送信ができません

    下記のプログラムでUSART接続してPICマイコンからPCに送信しようとしています。 PICマイコンはP16F877 アプリにはTera Term というアプリケーションを使用しています。 このプログラムはUSARTの送信とステッピングモータを交互に動作させるプログラムです。 このプログラムを実行したところ、ステッピングモータが微小に動作したままとまってしまいました。 Tera Termにも文字は出力されませんでした。 そのため、1周目だけTXREGレジスタにデータを格納するところまでは出来ていると思います。 しかし、データ送信が行われないため、2週目以降はTSRレジスタがBUSY状態となりプログラムが進行しないのだと考えています。 以下のサイトを参考に模索しましたが、原因が分かりませんでした。 http://www.kimurass.co.jp/pic/0625p.htm http://www.picfun.com/pic19.html どのように対処したらよろしいでしょうか? 原因やアドバイスなど教えていただけたら幸いです。 ~~プログラム~~ list p=16F877 #include <p16F877.inc> __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF& _LVP_OFF w_temp EQU 0x0C status_temp EQU 0x0D ;変数 cblock 020h CNT15mS ;15mSカウンタ CNT5mS ;5mSカウンタ CNT1mS ;1mSカウンタ CNT50uS ;50μSカウンタ USART_TEMP ;USARTのワークレジスタ POINT ;point of table BUFFER ;buffer endc ;*************************割り込み退避************************** ORG 0x000 goto MAIN ORG 0x004 movwf w_temp movf STATUS,w movwf status_temp movf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;************************************************************* MAIN ;-----------------------------設定---------------------------- ;BANK1 Setting bsf STATUS,RP0 clrf TRISA movlw B'11110000' clrf TRISB movlw B'01000000' movwf TRISC ;RXピンを入力に設定 movlw B'00100000' movwf TXSTA ;SET TX MODE movlw 0FH ;Set Baud Rate 19Kbps movwf SPBRG ;Set BRG ;BANK0 Setting bcf STATUS,RP0 clrf INTCON movlw 07H movwf ADCON1 ;------------------------------------------------------------ ;----------------------------初期化--------------------------- clrf PORTA clrf PORTB bcf STATUS,C bcf STATUS,Z ;------------------------------------------------------------ ;===========================MAIN_LOOP======================== MAIN_LOOP bsf STATUS,RP0 READY_CHECK btfss TXSTA,TRMT goto READY_CHECK bcf STATUS,RP0 movlw 'A' movwf TXREG call STEPPING_MOTTER goto MAIN_LOOP ;============================================================ ;================= STEPPING MOTORE ========================== STEPPING_MOTTER call wait1ms call wait1ms movlw B'00000001' movwf PORTB call wait1ms call wait1ms movlw B'00000010' movwf PORTB call wait1ms call wait1ms movlw B'00000100' movwf PORTB call wait1ms call wait1ms movlw B'00001000' movwf PORTB RETURN ;================= 15mS WAIT ================================ wait15ms MOVLW d'3' MOVWF CNT15mS wait15ms_loop CALL wait5ms DECFSZ CNT15mS,F GOTO wait15ms_loop RETURN ;================= 5mS WAIT ================================= wait5ms MOVLW d'100' MOVWF CNT5mS wait5ms_loop CALL wait50us DECFSZ CNT5mS,F GOTO wait5ms_loop RETURN ;================= 1mS WAIT ================================= wait1ms MOVLW d'20' MOVWF CNT1mS wait1ms_loop CALL wait50us DECFSZ CNT1mS,F GOTO wait1ms_loop RETURN ;================= 50μS WAIT ================================ wait50us ; 1サイクル(4クロック):0.2μS ; 50μS=0.2μS×250サイクル MOVLW d'82' ;1 MOVWF CNT50uS ;1 wait50us_loop DECFSZ CNT50uS,F ;1 GOTO wait50us_loop ;2 RETURN ;2+1 ;============================================================ ;------------------------------------------------------------ END

  • PICの条件分岐について

    お世話になります。PICについて質問があります。ボタンを押せば、PORTBのLEDに対する出力が変わるという物ですが、意図したようになりません。PORTに対する設定は間違っていないと思うのですが、チャタリングを考慮したプログラムになっており、上手く条件分岐してくれません。条件というのは、PORTAに入力があれば、25ms待機して再度PORTAを見に行きます。そのときにもPORTAに入力があれば、変数に格納した数値を一つずつ減らしていき、そのときに0であればPORTBを設定したとおりに出力するというものです。以下がソースですが、ここがおかしいということだけでも教えてくださると助かります。よろしくお願いします。 list p=16f628a #include<p16f628a.inc> __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF SWI equ 0x21 SWI2 equ 0x22 CNT1 EQU 0x20 CNT2 EQU 0x21 ORG 0x000 goto main ORG 0x004 main bcf STATUS,RP0 bcf STATUS,RP1 clrf INTCON clrf PORTA movlw 0x07 movwf CMCON bsf STATUS,RP0 bsf PCON,OSCF clrf TRISB movlw 0x03 movwf TRISA bcf STATUS,RP0 clrf PORTA clrf PORTB clrf SWI main_loop btfss PORTA,1 goto flase_wait_routine goto trues_wait_routine flase_wait_routine goto main_loop trues_wait_routine call DLY_25 btfss PORTA,1 goto main_loop incf SWI,f movf SWI,W movwf SWI2 decfsz SWI2,f goto a_loop_1 bsf PORTB,0 bcf PORTB,1 bcf PORTB,2 bcf PORTB,3 goto main_loop a_loop_1 decfsz SWI2,f goto a_loop_2 bcf PORTB,0 bsf PORTB,1 bcf PORTB,2 bcf PORTB,3 goto main_loop a_loop_2 decfsz SWI2,f goto a_loop_3 bcf PORTB,0 bcf PORTB,1 bsf PORTB,2 bcf PORTB,3 goto main_loop a_loop_3 decfsz SWI2,f goto a_loop_4 bcf PORTB,0 bcf PORTB,1 bcf PORTB,2 bsf PORTB,3 clrf SWI goto main_loop a_loop_4 goto main_loop ;Delay Routine DLY_25 ; 25ms movlw d'25' movwf CNT1 DLP1;1ms movlw d'20' movwf CNT2 DLP2 nop nop decfsz CNT2,f goto DLP2 decfsz CNT1,f goto DLP1 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 修正点などありましたら教えて下さい。

  • マイコンPIC16F84Aについて

    BSF STATUS,RP0 BSF TRISA,0 CLRF TRISB BCF STATUS,RP0 LOOP MOVLW05h MOVWF,PORTB MAIN BTFSC PORT,0 こんな感じです。 入力にセンサーを使用してオンしたらLEDが点灯する回路にしたいのですがプログラムに詳しい方がいましたら教えていただけないでしょうか?

  • PIC12F683 AD変換について

    PIC12F683のアセンブラの設定についてご教授ください。 以下のように設定したところGP4ピンにてAD変換できませんでした。 init MOVLW   07h MOVWF   CMCON0 BSF     STATUS,RP0 MOVLW   b'00111000' MOVWF   TRISIO MOVLW   070h MOVWF   OSCCON MOVLW   018h MOVWF   ANSEL BCF     STATUS,RP0 MOVLW   b'10001101' MOVWF   ADCON0 「MOVLW 018h」の行を削除すると問題なくAD変換動作します。 しかしその場合「ANSEL」に070hが入るのでGP4がデジタル 入出力になり動作しない用に感じますが、なぜか動作します。 動作するので問題はないのですが、なぜかすっきりしません。 原因が分る方がおられましたら教えていただけますでしょうか? .

  • 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で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

専門家に質問してみよう