• ベストアンサー

アセンブラによる16f84のプログラミング

次の3つのプログラムを作成したいのですが、どうにも分からないので皆さんの知恵を分けていただきたく思います。 (1)PORTAの下位4ビットをPORTBの上位4ビットに転送するプログラム (2)PORTAのビット0、ビット1に入力された値の論理積をPORTBのビット0に出力するプログラム (3)PORTAのビット0、ビット1の内容が両方1になるまで待ち続け、両方1になったらPORTBにB'10010110'を出力するプログラム この三つです。このうちの一つでも二つでも結構ですので、分かる方お教え願います。

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

  • ベストアンサー
  • kabasan
  • ベストアンサー率44% (264/588)
回答No.2

(1)その他のピンに影響を与えないようなコードならこうなります。 SWAPF PORTA,W ;PORTAの上位4ビットと下位4ビットを入れ替え IORLW H'0F' ;いらない下位4ビットをクリア MOVWF RAM1 ;RAM1に保存 ; *** 割り込みを使っているならココで割り込み禁止する *** MOVLW H'F0' ;PORTBを読み込み、同時に下位4ビットクリア IORWF PORTB,W IORWF RAM1,PORTB ;PORTAから取り込んだデータと合成して出力 ; *** 割り込みを使っているならココで割り込み許可する *** 割り込み禁止をかけるのはPORTBを読み込んで書き戻すまでの間に割り込み処理に入ってPOTRBが書き換えられる可能性があるからです。割り込みを使用していてもそんなコードが無いなら禁止する必要は有りません。 また、冗長で汚いプログラムになりますが、1ビットずつチェックしてBCFとBSFで出力を書き換えるなら割り込みは気にしなくて良くなります。 (2)PORTAがXXXXXX11ならPORTBのビット0をセット、違えばクリア。 COMF PORTA,W ;PORTAを反転して読み込み IORLW B'00000011' ;上位6ビットをクリアして結果が0なら両ビットが1だった(=論理積1) BTFSS STATUS,2 ;論理積=1なら次の命令はスキップ GOTO LABEL1 BSF PORTB,0 ;論理積=1なのでPORTBのビット0をセット GOTO LABEL2 LABEL1 BCF PORTB,0 ;論理積=0なのでPORTBのビット0をクリア LABEL2 (3)条件部分は(2)と同じなので、PORTBへの出力処理が違うだけ LABEL1 COMF PORTA,W ;PORTAを反転して読み込み IORLW B'00000011' ;上位6ビットをクリアして結果が0なら両ビットが1だった(=論理積1) BTFSC STATUS,2 ;論理積=1なら次の命令はスキップ GOTO LABEL1 ;論理積=0だったので、何もせず先頭へ戻る MOVLF B'10010110' MOVWF PORTB ;PORTBへ出力 GOTO LABEL1 ;先頭へ戻る こんなところでしょう。 あ~!タブがスペースに変換されるから見づらいだろうなぁ。

ZZR1200
質問者

お礼

御回答ありがとうございます。何か自分の考えていたのと方向から違いました(笑)参考にさせていただきます。

ZZR1200
質問者

補足

あっ、(2)にPORTBのビット0以外のビットはすべて1を出力するものとする。という条件を付け加えると、どこか変わりますか?アホみたいなことかもしれませんが…。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • kabasan
  • ベストアンサー率44% (264/588)
回答No.3

>(2)にPORTBのビット0以外のビットはすべて1を出力するものとする。という条件を付け加えると、どこか変わりますか? 私の書いたソースですとPORTBの他のビットは変化しませんが、結果出力時に明示的に1を出力するなら、 ;*** 4行目までは同じ *** MOVLW B'11111111' ;論理積=1なので全ビットをセット GOTO LABEL2 LABEL1 MOVLW B'11111110' ;論理積=0なのでビット0以外のすべてをセット LABEL2 MOVWF PORTB ;データを出力 こうですね。

ZZR1200
質問者

お礼

あっ、なるほど!わかりました。ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
  • paspas
  • ベストアンサー率52% (47/90)
回答No.1

(1)PORT B = (PORT A AND 0FH) OR (PORT B AND 0F0H) (2)PORT A のデータをXに記録し、AND 01H をした結果をX1とします。Xを1ビット右シフト(右ローテート)しAND 01Hします。これをX2とします。 X3 = X1 AND X2 X3の状態によりPORT B bOの出力をBCFまたはBSFで出力すればよいと思います。 (3)(PORT B AND 03H) - 03Hを実行し、ZEROフラグの変化をみてループすればできます。 ご参考になれば幸いです。

ZZR1200
質問者

お礼

ありがとうございます。参考にさせていただきます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 【pic】ビットを取り出して、足し算、出力

    問 PORTB に信号を入力する。この信号のうち、上位4ビットと下位4ビットを取り出し、それぞれを足し算して、PORTAに出力するプログラムを作成せよ。以下を参考にせよ。 参考 #include <pic.h> void main(void) { int x, y, z; TRISA = 0x00; TRISB = 0xFF; for(;;) { x = (0b11000000 & PORTB) >> 6; y = (0b00111000 & PORTB) >> 3; PORTA = x; } } ということで、実際に作っては見たのですが、あっているかどうかも不明です。特に苦手な分野ですので詳しい解説の方よろしくお願い致します。 自身で書いてみたプログラム↓ #include <pic.h> void main(void) { int x, y, z; TRISA = 0x00; TRISB = 0xFF; for(;;) { x = (0b11000000 & PORTB) >> 4; y = (0b00111000 & PORTB) << 0; z = x + y; PORTA = z; } }

  • picマイコンのプログラムについて

    上位4bitと下位4bitを取り出してそれぞれを足して出力するプログラム #include<pic.h> void main(){ int x,y,z; TRISA=0x00; TRISB=0xFF; for(;;){ x=(0b11110000 & PORTB)>>4; y=(0b00001111 & PORTB)>>0; z=x+y; PORTA=z; } } pulseを読み取り、カウントするプログラム portaの第0bitからpulseを読み込んで信号が変化したとき、数を数えて、現在のカウントをportbに出力する #include <pic.h> main() { unsigned char before,after; TRISA=0xFF; TRISB=0x00; before=PORTA&1; PORTB=0; for(;;) { after=(PORTA &8)>>3; if(before==0&&after==1) { PORTB=1; } else { PORTB=0; } before=after; } } どのように変更・付け加えをしたらいいでしょうか?どなたかわかる方はお願いします。

  • PICアセンブラ、これって変?

    PIC16F84でのアセンブラなのですが、下記のプログラムで・・・。 MAIN     MOVLW B'00000000'     MOVWF PORTB     BTFSC PORTA,3     GOTO  FINISH     GOTO  MAIN FINISH     MOVLW B'11111111'     MOVWF PORTB     END PortAが入力、Bが出力なのですが、MAINでループしながら待機、 PortAの3bitめがHになったらPortBをすべて立てて終了という感じに なると思いますが、上手くいかないんです。 3bit目にあらかじめ+5Vを印加しておくと、一瞬でPortBがすべて立つのですが、 ループ中にやっても何も変化がありません。 ループしていないか、判定ができていないかのどちらかなのですが・・・。 デバッグしてみても、きちんとループ・判定できているのですが いざ焼いてみると動作しません。わかりますでしょうか。

  • PIC16F84Aで出力が反転してしまう

    PIC16F84Aを用いて、矩形波を出そうとしています。 下記のようなプログラムを動かそうとしているのですが、 PORTA,1をONした時、出力がすべて反転してしまいます。 原因はどのような事が考えられますでしょうか? PORTA,0:矩形波の波長 PORTA,1:入力トリガが立ち上がりか立ち下がりか? PORTA,2:矩形波を立ち上がりにするか、立ち下がりにするか? PORTA,3:LED用出力 PORTA,4:手動トリガスイッチ PORTB,4~7:出力 で行っています。 ラベルL_Hの所で、出力はBCFで0になっているはずですが、 すべて1出力になります。 トリガを入れた時の出力も反転された状態になります。 ----------------------- LIST P=PIC16F84A ; LIST宣言で使用するPICを16F84Aと定義する。 INCLUDE P16F84A.INC ; 設定ファイルp16f84a.incを読み込む。 __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF ; ;変数の設定(タイマ用カウンタ)********************* CNT1 EQU 0CH CNT2 EQU 0DH CNT3 EQU 0EH CNT4 EQU 0FH CNT5 EQU 10H CNT6 EQU 11H ;リセット************** ORG 0 ;リセット ;初期設定************* CLRF PORTB ;PORT-Bをオール0 BSF STATUS,RP0 ;バンク1へ MOVLW B'00001111' ;00001111 MOVWF TRISB ;PORT Bを0-3を入力、4-7を出力として設定 MOVLW B'10111' ;00010111 MOVWF TRISA ;PORT Aを0-3を入力、4を出力として設定 NOP BCF PORTB,4 ;PORTB,4~7をオール0 BCF PORTB,5 ;PORTB,4~7をオール0 BCF PORTB,6 ;PORTB,4~7をオール0 BCF PORTB,7 ;PORTB,4~7をオール0 BSF PORTA,3 ;PORTA,3を1 CLRF CNT1 CLRF CNT2 CLRF CNT3 CLRF CNT4 CLRF CNT5 CLRF CNT6 ;入力が1か0か?************************ Trig_Direc NOP BTFSS PORTA,1 ;入力判定が立ち上がりの時 GOTO Diec_Hight GOTO Direc_Low ;入力立ち上がり、出力判定******************* Diec_Hight BTFSS PORTB,2 ;連続波出力の時 GOTO H_Comti BTFSS PORTA,2 ;出力判定が立ち上がりの時 GOTO H_H ;入力立ち上がり、出力立ち上がり GOTO H_L ;入力立ち上がり、出力立ち下がり ;入力立ち下がり、出力判定***************************************** Direc_Low BTFSS PORTB,2 ;連続波出力の時 GOTO L_Comti BTFSS PORTA,2 ;出力判定が立ち上がりの時 GOTO L_H ;入力立ち下がり、出力立ち上がり GOTO L_L ;入力立ち下がり、出力立ち下がり ;入力立ち上下がり、出力立ち上がり トリガ入力判定と出力************ H_H BCF PORTB,4 ;Trig出力1 OFF BCF PORTB,5 ;Trig出力2 OFF BCF PORTB,6 ;Trig出力3 OFF BCF PORTB,7 ;Trig出力4 OFF BSF PORTA,4 ;LED点灯 off ~正常出力 ・ ・ ・ ;入力立ち上下がり、出力立ち上がり トリガ入力判定と出力*************** L_H BCF PORTB,4 ;Trig出力1 OFF BCF PORTB,5 ;Trig出力2 OFF BCF PORTB,6 ;Trig出力3 OFF BCF PORTB,7 ;Trig出力4 OFF BSF PORTA,3 ;LED点灯 off L_H_ON BTFSS PORTB,0 ;トリガ入力1に入力があった場合 GOTO L_H_Time BTFSS PORTB,1 ;トリガ入力2に入力があった場合 GOTO L_H_Time BTFSS PORTA,4 ;手動トリガ入力に入力があった場合 GOTO L_H_Time GOTO Trig_Direc ;トリガ入力がなかった場合、初期判定に戻る L_H_Time BCF PORTA,3 ;トリガ判定LED点灯 BTFSS PORTA,0 ;パルス幅が50ms指定の場合」 GOTO L_H_50 GOTO L_H_200 L_H_50 BSF PORTB,4 ;Trig出力1 ON BSF PORTB,5 ;Trig出力2 ON BSF PORTB,6 ;Trig出力3 ON BSF PORTB,7 ;Trig出力4 ON CALL Timer_50ms BCF PORTB,4 ;Trig出力1 OFF BCF PORTB,5 ;Trig出力2 OFF BCF PORTB,6 ;Trig出力3 OFF BCF PORTB,7 ;Trig出力4 OFF CALL Timer_50ms GOTO L_H_Loop L_H_200 BSF PORTB,4 ;Trig出力1 ON BSF PORTB,5 ;Trig出力2 ON BSF PORTB,6 ;Trig出力3 ON BSF PORTB,7 ;Trig出力4 ON CALL Timer_200ms BCF PORTB,4 ;Trig出力1 OFF BCF PORTB,5 ;Trig出力2 OFF BCF PORTB,6 ;Trig出力3 OFF BCF PORTB,7 ;Trig出力4 OFF CALL Timer_200ms GOTO L_H_Loop L_H_Loop BTFSC PORTB,0 ;トリガ入力1が出力状態だった場合 GOTO L_H_Loop BTFSC PORTB,1 ;トリガ入力2が出力状態だった場合 GOTO L_H_Loop BTFSS PORTA,4 ;手動トリガ入力に入力があった場合 GOTO L_H_Loop BSF PORTA,3 ;トリガ判定LED消灯 GOTO Trig_Direc ;初期へ戻る ・ ・ ・ 以下略

  • PIC16F88の使い方?に関する質問(アセンブラ)

    現在PICの16F88に書きこむプログラムをアセンブラで書いてます。4番ピンのMCLRをRA5として使いたいのですが、MPLABのWATCHの機能を使って、ポートAの動きを見てみると、ポートAが出力になっているはずなのに、何をしてもポートAの0~4がHにならず、ポートAのRA5はBSF,BCFの命令が利きません。コンフィグの設定が怪しいと思うのですが、自分には理由が分からないので、誰か教えてください。お願いします。(下に書いたプログラムはテスト用に書いたプログラムなので特に目的はありません) ;外部発振,セラロック20MHz使用 LIST P=PIC16F88 INCLUDE P16F88.INC __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF BSF STATUS,RP0 MOVLW B'000000' MOVWF TRISA MOVLW B'00000000' MOVWF TRISB BCF STATUS,RP0 MAIN CLRF PORTA MOVLW B'11111111' MOVWF PORTA MOVWF PORTB BSF PORTA,0 BCF PORTA,0 BSF PORTA,1 BCF PORTA,1 BSF PORTA,2 BCF PORTA,2 BSF PORTA,3 BCF PORTA,3 BSF PORTA,4 BCF PORTA,4 BSF PORTA,5 BCF PORTA,5 GOTO MAIN END

  • PICアセンブラを出来る方、教えてください!

    初めに、カテゴリー間違ってたら、ごめんなさい。 大学の授業でライントレースロボットのアセンブラプログラムをやっています。 「以下のプログラムをセンサ入力をPORTA、モータドライブをPORTBとしプログラムを完成させよ(本講義で用いる装置はそのような回路になっていないので実行できない)。」 という問題なんですが分かる方居ますでしょうか? ;改造するプログラム ーーーーLIST P=PIC16F628A ーーーーinclude "P16F628A.inc" ーーーー__CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF & _CP_OFF STATUS EQU 3 RP0 EQU 5 PORTA EQU H'05' PORTB EQU H'06' TRISA EQU H'85' TRISB EQU H'86' LR EQU D'7' LL EQU D'0' FRONT EQU B'00011000' RIGHT EQU B'00001000' LEFT EQU B'00010000' ーーBSF STATUS,RP0 ーーCLRF TRISA ーーMOVLW B'11000011' ーーMOVWF TRISB ーーBCF STATUS,RP0 ーーCLRF PORTA ーーCLRF PORTB LINE BTFSC PORTB,LL ーーGOTO MIGI ーーBTFSC PORTB,LR ーーGOTO HIDARI ーーGOTO MAE MAE MOVLW FRONT ーーIORWF PORTB,1 ーーMOVLW B'11011011' ーーANDWF PORTB,1 ーーGOTO LINE MIGI MOVLW RIGHT ーーIORWF PORTB,1 ーーMOVLW B'11001011' ーーANDWF PORTB,1 ーーGOTO LINE HIDARI MOVLW LEFT ーーIORWF PORTB,1 ーーMOVLW B'11010011' ーーANDWF PORTB,1 ーーGOTO LINE ーーEND 私が今、予想しているのは MOVLW B'11111111' MOVWF TRISA CLRF TRISB とするのではないかな、くらいです。(合ってるか分かりませんが) この問題を解ける方、いましたらお願いします。 (注)プログラムがスペースが分かりにくくなっていますが、本当のプログラムはちゃんとスペースが空いて、列も揃っています。行の先頭に付いているーは強制的に左寄せになるのを、すこしでも見やすくするための物で、意味はありません。

  • 基本情報のCASLIIの平成18年春の問13

    基本情報のCASLIIの平成18年春の問13の問題です。 32ビットの2進数(被乗数)と15ビットの符号なし二進数(乗数)の乗算を行うプログラムなのですが、解説を読んでもわからない点があったので質問させていただきます。 32ビットの被乗数の方は上位16ビットと下位16ビットにそれぞれGR1,GR0に分けて格納しています。 ここで、GR1,GR0をGR3ビットだけ論理左シフトします。そうすると、上位16ビットの左端からGR3ビットはみ出します。解説のここまでは理解できたのですが、次からの文章が理解できませんでした。 「シフト前の下位(16-GR3)ビットがシフト後の上位(16-GR3)ビットとして残る。したがって下位語の上位GR3ビットを(16-GR3)ビット,つまりGR4ビット論理右シフトして,上位語の下位GR3ビットに転送する必要がある。」 というものです。 シフト前の下位(16-GR3)ビットというのはどこのことを指しているのか不明ですし、シフト後の上位(16-GR3)ビットも同様です。 また、なぜGR4ビット論理右シフトするとなぜ上位語に反映されるのかもわかりません。右シフトすれば上位語も右シフトされて反映下位から上位へビットが転送されないと思うからです。 ちなみに、GR3+GR4=16という関係を持っています。 それと、解説の画像は添付しておきます。

  • プログラムについて pic

    第3bit目がマスクし取り出した信号で、この信号を第0bit目に移す場合 x=(0b00001000)〉〉3 これで合っていますか? pulseを読み取り、カウントするプログラム portaの第0bitからpulseを読み込んで信号が変化したとき、数を数えて、現在のカウントをportbに出力する #include <pic.h> main() { unsigned char before,after; TRISA=0xFF; TRISB=0x00; before=PORTA&1; PORTB=0; for(;;) { after=(PORTA &8)>>3; if(before==0&&after==1) { PORTB=1; } else { PORTB=0; } before=after; } } どのように変更・付け加えをしたらいいでしょうか?どなたかわかる方はお願いします。

  • 基本情報処理技術者試験 

    下記の問題の説明がどうしても理解出来ませんので、ご教授いただけますと幸いです。 https://www.fe-siken.com/kakomon/15_aki/q6.html この問題では8ビットのデータの下位7ビットを取り出したいので、最上位ビット以外を「1」としたビット列「0111 1111」との論理積をとることで下位7ビットを取り出すことができます。  ⇒ どういう並びの数字(XXXX XXXX)が、「0111 1111 」と論理積を取って、下7桁を抽出する事が出来るのでしょうか? 理解出来ていないので、質問内容自体がおかしいかもしれません。 よろしくお願い致します。

  • PIC16F88のアナログコンパレータ使用について

         LIST    P=PIC16F88 #INCLUDE<P16F88.INC> __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF &                    _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF &                    _PWRTE_ON & _WDT_OFF & _HS_OSC __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF VAR1 EQU 0x20 VAR2 EQU 0x21 ORG 0 start      BCF       STATUS,RP1      BSF       STATUS,RP0   ;bank1へ移動      CLRF      TRISB       ;PORTBをすべて出力      MOVLW     0xff      MOVWF     TRISA       ;PORTAをすべて入力      MOVLW      x05        ;コンパレータ1つのみ使用      MOVWF     CMCON      BCF       STATUS,RP0   ;bank0へ移動      CLRW      MOVWF     PORTB      MOVLW     0xff      MOVWF     PORTA 18ピンのPIC16F88の内蔵アナログコンパレータ(RA1/AN1とVINRA2/AN2/CVREFが入力、C2OUTが出力の1つのみ利用する設定)を使用しPORTBからLEDへ出力し電圧の大小の判定を行いたく、上記のような設定でプログラムをつくりコンパイルは通ったのですが動作せず、 MPLABのデバッグにて確認したところ『MOVWF PORTA』の部分でPORTAのレジスタ値が0x00から変化しておりませんでした。 『BCF STATUS,RP0』まではレジスタ値は変化しており、 STATUSは0x1cでbank0、TRISAは0x3fで入力、ANSELはデフォルトで0x7fでアナログ入力 になっているのですが、何故PORTAが値を入れても変わらないのか原因が分かりません。 分かる方、ご教授頂けますと幸いです。 宜しくお願い致します。