PIC/「Label」に対応するアドレス重複

このQ&Aのポイント
  • PICのプログラムで「Label」に対応するアドレスが重複している問題が起きています。
  • 特定の「Label」には特定のアドレスが一つ与えられると思っていたので、重複していることに混乱しています。
  • この問題をどのように理解すれば良いのかわかりません。
回答を見る
  • ベストアンサー

PIC/「Label」に対応するアドレス重複

PICのプログラムを学んでおります。 Include fileの中の「pic16f84a.inc」を見ると、下記のように「Label」に対応するアドレスが重複しているものがあります。 ある特定の「Label」には特定のアドレスが一つ与えられるのだとばかり理解していたので、このように重複していて、さっぱり混乱しています。 これはどのように理解したらよいのでしょうか? よろしくお願いいたします。 -------------------- // Register: TMR0 TMR0 equ 0001h // Register: PCL PCL equ 0002h // Register: STATUS STATUS equ 0003h // bitfield definitions STATUS_C_POSN equ 0000h STATUS_C_POSITION equ 0000h STATUS_C_SIZE equ 0001h STATUS_C_LENGTH equ 0001h STATUS_C_MASK equ 0001h STATUS_DC_POSN equ 0001h STATUS_DC_POSITION equ 0001h STATUS_DC_SIZE equ 0001h STATUS_DC_LENGTH equ 0001h STATUS_DC_MASK equ 0002h STATUS_Z_POSN equ 0002h STATUS_Z_POSITION equ 0002h STATUS_Z_SIZE equ 0001h STATUS_Z_LENGTH equ 0001h ---------------------------

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.5

PICに詳しくはないですが、資料をざっと見る限り、これらは、只の定数と思われます。 C言語風に書くなら f = (STATUS >> STATUS_Z_POSITION ) & STATUS_Z_MASK として、STATUSレジスタから、特定のフラグを0ビット目にシフトして、不要なビットを0にする、やるための定数です。 こういうマクロを記憶しているのは、アセンブラです。 アセンブリする際には、ソースコードの該当箇所を、数値に変換します f = (STATUS >> STATUS_Z_POSITION ) & STATUS_Z_MASK だったら f = (STATUS >> 0002h ) & 0001h 0001hが、元がSTATUS_Z_MASKだったのかSTATUS_C_MASKだったのか、などと、CPUは考えません。

chy_farm
質問者

お礼

おかげさまでおとといより理解がだいぶましになりました。 ありがとうございました。

その他の回答 (4)

  • ts3m-ickw
  • ベストアンサー率43% (1248/2897)
回答No.4

単に変数に値を設定しているだけって考えればいいと思う。 A、B、Cそれぞれの変数に同じ値を設定したって、何も困ることはないでしょ? ラベルだとしても同様。 例えば同じアドレスにSubA、SubBって2つのラベルを割り当てたとして、 call SubAもcall SubBもまったく同じ処理をするけど、それで困ることはない。 人間(プログラマ)がそれを把握しておけばいいだけのことです。 jmp命令と、jp命令と、br命令がまったく同じ動作をするのも同様。 同じ命令コードが割り当てられているだけなのでCPUからすれば違いはなく、区別するのはプログラマです。

chy_farm
質問者

お礼

おかげさまです。ありがとうございました。

chy_farm
質問者

補足

すみませんねぇ、お手間かけますよ、、、みなさんのおかげでだいぶイメージがとれてきたような気がします。 アドレス空間ということをいいますけど、何かの変数を宣言しておいて、その変数のためのアドレス空間を作った、というような意味と同じ??

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

「PIC が」という観点でいくなら そもそも PIC は「TMR0」や「STATUS_C_POSN」なんてものを知らない としか言いようがない. PIC にとって「TMR0」や「STATUS_C_POSN」なんてものはなく, ただ「0」とか「1」とかの数字があるにすぎない. ただ, そうすると人間にとって困るかもしれない (単に「0」と書いてあって, 意味を理解できますか?) ので, そ~いうひとのために「TMR0」とか「STATUS_C_POSN」とかの名前を付けているだけ.

chy_farm
質問者

お礼

ありがとうございました。

chy_farm
質問者

補足

わざわざご回答いただいたのに、ちょっと意味がわかりません。もう少しわかるようにお願いできませんかねぇ、、、

  • uruz
  • ベストアンサー率49% (417/840)
回答No.2

ラベル equ 数値 これは、ラベルに数値を設定(定義)するものでアドレスとは限らない。 アドレス、データ、ビット位置、データインデックスなど何を意味する数値なのかは、どういう意図を持って定義したかによります。 したがって、数値の重複はいくらでもありえます。

chy_farm
質問者

お礼

おかげさまです。ありがとうございました。

chy_farm
質問者

補足

そんなにたくさんの数値をInclude fileで決めておいて、それをIncludeしてきてもどれがどれだかわからなくなる(PICが)、ということは無いのですか? うううーー、どこが理解できていないのでしょうか? どこにしぼって読み直せばここが理解できるか?教えてくださいませんか。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

? ある特定の「Label」には特定のアドレスが一つ与えられる という点では, 何も困るところはないと思うが? そもそも「アドレス」じゃないだろうけど.

chy_farm
質問者

補足

ご教示いただいたフレーズが私の理解には短すぎてわかりにくいです。 「そもそも「アドレス」じゃない」のですか? いったいどこにフォーカスして学べばここがわかるのか???わかりません。

関連するQ&A

  • PICのプログラミングについて

    PICのSTATUSレジスタのz〔ゼロ〕フラグとC〔キャリー〕が同時に1になることはあるのでしょうか?以下のようなときのことなのですが・・・ movlw b'00000001' sublw b'00000001' このような時のZフラグとCフラグはどうなるのでしょう? PIC活用書等を読んでみたのですが、あまりわかりませんでした。 初心者な質問ですが宜しくお願いします。

  • PIC18FのSTATUS

    PIC18FのSTATUSレジスタ(N,OV,Z,DC,C)の内Z,DC,Cは16Fと同じだと思いますがN,OVが部分的にわかりません OV:7ビット越えのオーバーフローフラグということですが8ビットオーバーすればC=1と思いますがなぜ7ビットなのでしょう? どういった時に使えるものなのでしょうか?(符号付とは?) N:演算の負フラグ 16Fの時はCで兼用だったのが分離したものだと思いますが、実際にマイナスになると=1になります。が足して7ビット越えした状態でも=1になっていますがそういうものなのでしょうか?

  • PIC16F877について

    PIC16F877を使っているのですがBポートとCポートの中でマイクロスイッチの入力ができるポートとできないポートがありますコフィングの問題だとおもいますが原因がわかりません __CONFIG _HS_OSC & _PWRTE_ON & _WDT_OFF & _LVP_OFF ;__CONFIG _HS_OSC & _RC_OSC & _PWRTE_ON & _WDT_OFF & _LVP_OFF ORG 0 ; リセットベクタ(0番地)を指定する GPR_1 EQU 020h ; GPRの1バイト目にGPR_1と言う名前を付ける 88移行 GPR_2 EQU 021h ; GPRの2バイト目にGPR_2と言う名前を付ける 88移行 GPR_3 EQU 022h ; GPRの3バイト目にGPR_3と言う名前を付ける 88移行 GPR_4 EQU 023h ; GPRの4バイト目にGPR_4と言う名前を付ける 88移行 GPR_5 EQU 024h ; GPRの5バイト目にGPR_5と言う名前を付ける 88移行 GPR_6 EQU 025h MAIN CLRF PORTA ;初期クリア 0クリア CLRF PORTB ;初期クリア 0クリア CLRF PORTC CLRF PORTD CLRF PORTE BSF STATUS,RP0 ;ファイルレジスタSTATUSのRP0(ビット5)をセット(1)する → バンク1 MOVLW 07H MOVWF ADCON1 MOVLW B'00000000' MOVWF TRISA ; ポートA全出力 MOVLW B'11111111' MOVWF TRISB ; ポートB全入力 MOVLW B'11111111' MOVWF TRISC ; ポートC全入力 MOVLW B'11111111' MOVWF TRISD ; ポートD全入力 MOVLW B'11111111' MOVWF TRISE ; ポートE全入力 BCF STATUS,RP0 ;STATUSのRP0をクリア(0) → バンク0

  • PICのEQUでつまづいてしまいました

    PICを習い始めた者です。EQUの理解でつまづいてしまいました。どなたか入門者向けの説明が上手な方、宜しくお願いします。なお、勉強させていただいているページは↓こちらです。 http://www.k3.dion.ne.jp/~digikoma/swf/flpic.html PICの「EQU」と「equ」は、 「大小文字の違いだけで、BULIDしたときは同じ働き」 と理解していたのですが、下記の記述でこんがらかってしまいました。 ;;(ここから引用→ http://www.k3.dion.ne.jp/~digikoma/shoho/shoho11.html#top);; INDF   EQU 0x00 TMR0  EQU 0x01 PCL   EQU 0x02 STATUS EQU 0x03 FSR   EQU 0x04 TRIS_A EQU 0x05 TRIS_B EQU 0x06 TRIS_C EQU 0x07 PORT_A EQU 0x08;PORT_A,4がマイクロ SW4 PORT_B EQU 0x09;7セグメント表示器へ(Hで点灯) PORT_C EQU 0x0A;PORTC_0=LED1を点滅用にする FLG equ PORT_C+1 ;Bit0をSW4の検知状態フラグとして使用する ;↓↓ SW4のON期間の経過値 C_CNT equ FLG+1 ;↓↓ スイッチが押して離した回数 SW_CNT equ C_CNT+1 ;↓↓ LEDタスクへの侵入カウンター LED_RC equ SW_CNT+1 ;↓↓ LEDの点灯(ON)期間のカウンタ LED_ON equ LED_RC+1 ;↓↓ LEDの消灯(OFF)期間のカウンタ LED_OF equ LED_ON+1 ;;(ここまで引用 );; ↑ここでは「INDF」~「LED_OF」のラベルにアドレスを与えているわけですね。(質問1) で、次のところからがわからないんです。 ;;(ここから引用);; CHAT equ 0x07;チャタリング時間(0xFD) JOBCNT equ 0x04;点滅タスク侵入カウンタ(0x00) ON_TIM equ 0x02;LEDの点灯期間(0x25) OF_TIM equ 0x08;LEDの消灯期間(0x60) ;;(ここまで引用 );; ↑ここであたかもラベルのようにみえる「CHAT」~「OF_TIM」にはアドレスが与えられなくてもいいんでしょうか? 小文字の「equ」の後に16進数がありますけど、これはSFRの領域をしてるのではないんでしょうか?(質問2) この後に↓次の記述が来てます・・・ ;;(ここから引用);; ; *** SW4検知の初期化  bcfFLG,0  clrfSW_CNT;スイッチ検知初期化  clrfC_CNT;チャタ検知用のカウンタ初期 ; *** LED点滅の初期化(CPU速度で調整必要)  movlwON_TIM;点灯期間の時間をセット  movwfLED_ON (略) ;;(ここまで引用 );; ↑この部分に相当するところをBULIDの後、逆コンパイラで確認すると、次のようになっています。 0x008  0x018D clrf  SW_CNT 0x009  0x018C clrf  C_CNT 0x00A  0x3002 movlw  0x02 0x00B  0x008F movwf  LED_ON つまり「ON_TIM」に「equ」をつかって「0x02」を代入しているから、 上の「0x00A  0x3002 movlw 0x02」のところでは自動的に16進数「0x02」が入っているのですね。 EQU,equ はアドレスを指定したり、数値を指定したりと、両方が出来るのですか?(質問3) このこんがらかりをナンとか直してください。お願いします!

  • 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

  • PICのプログラム

    PICのテストプログラムを作ったのですが、LEDの点灯が、順々に動くプログラムのはずがすべてのLEDが同時に着いてしまいます。なぜですか???? とても困っています。誰か教えてくれたらありがたいです。 PICは、16F877Aです。 ポートDにLEDがついています。 TITLE "QUARK Test1 PICUN1" LIST p=PIC16F877A __CONFIG _HS_OSC & _CP_OFF & _LVP_OFF & _BODEN_ON & _PWRTE_ON & _WDT_OFF & _WRT_OFF & _DEBUG_OFF #INCLUDE "P16F877A.inc" __IDLOCS D'1' matu EQU 020H matu2 EQU 021H matu3 EQU 022H main ORG 0 clrf STATUS clrf INTCON bsf STATUS,RP0 clrf TRISA clrf TRISB clrf TRISC clrf TRISD clrf TRISE clrf STATUS clrf PORTD clrf matu clrf matu2 clrf matu3 mainloop bsf PORTD,2 call matuloop3 bcf PORTD,2 call matuloop3 goto mainloop ;この後にmatuloop1~3が続く。 END よろしくお願いします。

  • PIC 8このLEDの点灯 左から右 右から左

    ↓のコードで 8つのLEDを右から左に一つずつ順番に点灯したあと左から右に順番に点灯させるプログラムをつくりたい そして下のコードに ~~~~ここに1行~~~~と書いているところがあります。 そこになにか一行書くとできるらしいのです。 でもどうやってもできません。 loop1: btfsc PORT_A,1 goto loop1 多分、↑に書いたコードの箇所がずっと無限に回ってるからだとおもいます。 この↓のコードで~~~~ここに1行~~~~の場所に本当になにか一つつけくわえるだけでできるのであれば教えてほしいです。 また、この問題が間違ってるというのであればどこが間違っているかを教えてほしいです。 少しだけならコードをかきかえても大丈夫だそうです。 わかるかたもしいましたら、おねがいします。 INDF EQU 0x00 TMR0 EQU 0x01 PCL EQU 0x02 STATUS EQU 0x03 FSR EQU 0x04 TRIS_A EQU 0x05 TRIS_B EQU 0x06 TRIS_C EQU 0x07 PORT_A EQU 0x08 PORT_B EQU 0x09 PORT_C EQU 0x0A org 0x00 ;ここから↓ MOVLW 0x3F MOVWF TRIS_A CLRW MOVWF TRIS_B MOVWF TRIS_C MOVWF PORT_B MOVWF PORT_C loop1: btfsc PORT_A,1 goto loop1 ~~~~ここに1行~~~~ loop2: btfss PORT_A,0 goto  loop2 goto loop1 -----------------------------------------

  • PIC12F683 TMR2の割込がうまくいきませ

    タイトルのPICを使ってTMR2の割込動作を確認しているのですが、割込が全く掛かりません。 TMR2は単独で割込を掛けないで動作することは確認できましたがエラーもあるわけでもなく あれこれやっても解決せず迷走中です。また、割込ルーチンはこれまで動作が確認できたプログラムを埋め込んで使っているので問題はないと思っています。 何方かお助け頂けませんでしょうか。宜しくお願い致します。 ;******************************************* ; PIC初期設定 ;******************************************* START_INI BCF STATUS,RP0    ;BANK【0】 MOVLW 07h MOVWF CMCON0 ;GP0-2はデジタルIO BSF STATUS,RP0    ;BANK【1】 MOVLW B'0000000' MOVWF ANSEL ;A/D変換クロックF/2 デジタルI/O BCF OPTION_REG,7 ;GPIO端子をプルアップ MOVLW B'001000' ;RESET端子有効 MOVWF TRISIO ;GP0,1,2,4,5:OUT GPO3:IN MOVLW B'1000000' ;40h MOVWF OSCCON ;クロック=1MHz ;******************************************* ; TMR2の設定 ;******************************************* BCF STATUS,RP0    ;BANK【0】 MOVLW B'000101' ;ポス=1:1 TMR2=ON プリ=1:4 MOVWF T2CON ; BCF PIR1,TMR2IF    ;Timer2 割込み検出フラグをクリア BSF STATUS,RP0    ;BANK【1】 BSF PIE1,TMR2IE    ;Timer2 有効 MOVLW H'FA' ;250 MOVWF PR2    ;TRM2カウントSET ;******************************************* BCF STATUS,RP0     ;BANK【0】 CLRF TMR2 BSF INTCON,GIE     ;割り込み全体を有効

  • PICのSleepからの復帰に関して

    INTピンを使ってsleepから割り込み復帰したいのですが、 思ったとおり動いてくれません。 メインをSLEEPにし、割り込みが入ると割り込み側の プログラムを実行し、終わるとメインのSLEEPに もどってINTの割り込みに備えるようにしたいのです。 現段階では割り込みをするとSLEEPから割り込み には行くのですが、そのまま割り込み側のプログラムを 永遠に繰り返してしまいます。 list p=12f629 include p12f629.inc RELOOP1 equ 0x20 CT_DELAYNMS equ 0x21 PCLATH_TEMP equ 0x2a W_TEMP equ 0x2b STATUS_TEMP equ 0x2c stu equ 0x2d org 0x0 goto start org 0x4 ;レジスタの退避 movwf W_TEMP swapf STATUS,W clrf STATUS movwf STATUS_TEMP movf PCLATH,W movwf PCLATH_TEMP clrf PCLATH ;割り込み要因のチェック btfss INTCON, INTF goto INT_NEXT1 ;ここから割り込みプログラム 省略 INT_NEXT1 ;レジスタの復帰 movf PCLATH_TEMP,w movwf PCLATH swapf STATUS_TEMP,W movwf STATUS swapf W_TEMP,F swapf W_TEMP,W retfie ;初期設定 start: ;aLED単独の輝度 bcf STATUS, RP0 clrf INTCON clrf GPIO bsf STATUS, RP0 clrf OSCCAL clrf TRISIO bsf TRISIO,2 movlw B'01000101' movwf OPTION_REG bcf STATUS, RP0 ;割り込み許可する movlw B'11010000' movwf INTCON nop sleep nop goto $-3 end こんな感じのプログラムなのですが、INTピンからの割り込みと いうことでプリスケーラなどは使っていません。 データシートも読んだのですが今市理解ができていない状況です。 お願いします。

  • PICの「SWAPF」の意味について

    PICを学びはじめたばかりの初学者です。混乱してしまい、バイト命令「SWAPF」の意味がわかりません。 質問1: 「SWAPF」という命令は「ファイルレジスタfの上位4ビットと下位4ビットを入替えた結果を(d)に入れる」と出ています。 http://homepage3.nifty.com/mitt/pic/pic42_1.html この「上位4ビットと下位4ビットを入替え」というのは例えば次のようにすることを言うのですか? ----------- (SWAPF前) 上位4ビット 下位4ビット △△△△   □□□□ (SWAPF後) 上位4ビット 下位4ビット □□□□   △△△△ ----------- 質問2: 質問1が正しいとしたら、次の記述の訳はどのようなことなのですか? こちらのページを拝見しますと、下記引用のようになっています。 http://www.picfun.com/arch09.html ----ここから引用-------------------- 【スワップ命令の使い方】 SWAP命令を有効に使う例は、下記のような場合です。 例1 割り込み時のレジスタの待避、復帰     SWAP命令がSTATUSに影響しないことを利用しています。 PUSH  MOVWF  W_TEMP    ;Wレジスタ待避     SWAPF  STATUS,W  ;STATUS取り出し     MOVWF  ST_TEMP   ;STATUS待避 ----ここまで引用-------------------- ↑この中の「;STATUS取り出し」のところですが、「SWAPF」を使って「上位4ビットと下位4ビットを入替え」てからでないとSTATUSのHとLを取り出すことが出来ないのでしょうか? 質問3: もし、 「SWAPF」を使って「上位4ビットと下位4ビットを入替え」てからでないとSTATUSのHとLを取り出すことが出来ない、 のだとしたら、それはPICの仕組み上のことなのでしょうか? 初学者の質問で馬鹿らしいかもしれません。ご解答が面倒で無い方がいらしたら、どうぞご教示よろしくお願いいたします。

専門家に質問してみよう