質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.36%

  • C++

    4069questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Arduino

    615questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

EECR |= (1<<EEMPE)とは??

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 141

chy_farm

score 10

Arduino UNO で使われている ATmega328/P のマニュアルがあります。
https://www.microchip.com/wwwproducts/en/ATmega328

このマニュアルの「8.6.3」に
「 EECR – The EEPROM Control Register」という項があります。
このRegister「EECR」は 8 Bitで、アドレスは「0x1F」と記されています。 

この8 Bitの内容は、
–  –  EEPM1  EEPM0  EERIE  EEMPE  EEPE  EERE
となっています。

このうち、Least Significant Bit から3番目の Bit 2は「EEMPE」で、これは、 
• Bit 2 – EEMPE: EEPROM Master Write Enable
と説明があります。

これのほかのBit1,Bit0は以下のように、

• Bit 1 – EEPE: EEPROM Write Enable

• Bit 0 – EERE: EEPROM Read Enable

です。

さて、この「EEPE」RegisterのBit 2、すなわち「EEMPE」を使うコードのサンプルとして、次のようなCodingがあげられています。

// C Code Example
char cSREG;
cSREG = SREG; /* store SREG value */
/* disable interrupts during timed sequence */
_CLI(); 
EECR |= (1<<EEMPE); /* start EEPROM write */
EECR |= (1<<EEPE);
SREG = cSREG; /* restore SREG value (I-bit) */

//参考:CLIは、Grobal Interrupt Disableの意。


ここに記された

EECR |= (1<<EEMPE);
EECR |= (1<<EEPE);


の意味を知りたいのです。

When EEMPE is set, setting EEPE within four clock cycles will write data to the EEPROM at the selected address

と説明されています。

例えば一つ目の「EEMPE」、これは一つのBitのはずですから、その内容は「1」、又は「0」のはず。
するとこれが「Enable」で「1」になったとして、これを1つ「Left Shift」すれば「10」になる。
この「10」を「EECR」Registerに「Bit Or」したら、、、、
(おっと、ちょっとへんだぞ、、、)

という訳で、整理が付きません。
入門者向けの分かりやすいアドバイスが出来る方に、ご案内お願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

「このRegister「EECR」は 8 Bitで、アドレスは「0x1F」と記されています。 

この8 Bitの内容は、」で説明されている

–  –  EEPM1  EEPM0  EERIE  EEMPE  EEPE  EERE

で出てくる"EEPM1","EEPM0","EERIE","EEMPE","EEPE","EERE"というのは、各ビットに付けられた名前です。

それに対して、
"Bit 2 – EEMPE: EEPROM Master Write Enable"
[直訳] ビット2 - (別名) EEMPE: EEPROM Master Write Enable"
というように説明されている訳です。

こうした名前を付けることで
「EEPROMに書き込みをする場合には、EEMPEビットを1にする必要がある」というような説明がしやすくなります。

ーーー
一方、スケッチ(Arduinoのコード)に書かれた

EECR |= (1<<EEMPE);
EECR |= (1<<EEPE);


で使われている "<<" は左ビットシフトの演算子で、 "x << y"という式はxの値を左にyビット分シフトする(ずらす)という事を意味します。
yは何ビットシフトするかを指定するものなので整数(int)を与えます。

こうした演算子に関する知識があると、
・EEMPEやEEPEは整数のはずだな。
・でも、EEMPEやEEPEの値(整数)が何かコードに書かれていないよ。
・だったら、どこか別のところにヘッダファイル(拡張子が".h"のファイル)があって、それを使っているんだろうな。
・じゃぁ、ヘッダファイルの読み込みを指示する "#include "で始まる行を探そうか、、、
というように考えていって、

#include <iom328p.h>


に辿り着けるようになりますよ。

ーーー
『例えば一つ目の「EEMPE」、これは一つのBitのはず』のように考えていくのは大切です。
そして、それで行き詰まった時は、『xxのはず』という思い込みを見直して、ほかの解釈もありうるのではと周りを見回すと良いですよ。

プログラムをうまく作れるようになるには、知識と慣れが必要です。
がんばってください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/13 10:09

    お世話になります。

    >使われている "<<" は左ビットシフトの演算子で、 "x << y"という式はxの値を左にyビット分シフトする(ずらす)という事を意味します。

    すると、私が例示した;
    (1<<EEMPE)
    は、EEMPEの値(0 or 1)を、左に「1」つ移動するのではなく、
    「1」を左に「EEMPEの値」分移動する、
    という意味になりますか。

    キャンセル

  • 2019/02/13 10:20

    そのとおりです。EEMPEは2だとiom328p.hで定義されていますから、(1<<EEMPE)は、1を左に2ビットシフトするという意味になります。
    (1<<x)は、1を左にxビットシフトするという意味なので、ビットxだけが1で、他のビットが0になっている値になります。それとORを取ると、ビットxが1になるので、特定のビットを1にするという意味になります。

    キャンセル

  • 2019/02/13 10:42 編集

    なるほど、そういうことですか!

    もう一つお願いします。
    >EEMPEは2だとiom328p.hで定義されていますから、
    ということの定義の意味に、Bit number 2 の 「EEMPE」が、このBit numberの「2」と同じに定義されているのとは、相関がありますか?

    キャンセル

  • 2019/02/13 10:50

    観てみました。
    180 - 186 に;
    #define EECR _SFR_IO8(0x1F)
    #define EERE 0
    #define EEPE 1
    #define EEMPE 2
    #define EERIE 3
    #define EEPM0 4
    #define EEPM1 5
    とありますが、意味づけはまだ見つかりません。

    キャンセル

  • 2019/02/13 11:13

    このようにわざわざ記述する意義は、
    Bit number 2 の EEPMEをhighにするときに、
    00000100
    を入力するより、
    EEPMEを「2」とDefineしておいて、この単語を使用して入力するほうが、入力の際の人為的ミスが減る、
    ということに思えます。
    だから、
    (1<<EEMPE)をもって「 00000100」としておいて、さらにこれをBit orすることにした、と推定しました。
    こんなところでしょうか。

    キャンセル

  • 2019/02/13 11:37

    「EECR |= (1<<EEMPE);」というような使い方を想定してEEMPEなどが定義されている事と、「Bit number 2 の 「EEMPE」が、このBit numberの「2」と同じに定義されている」事が密接に関係しています。 プログラムを作るときには初期段階で『こういう事がしたい、こうゆう場合に使いたい』という構想を練ります。そうした思いがプログラムのコードから読み取れるようになるとコードを読むことが楽になりますよ。

    キャンセル

  • 2019/02/13 11:48 編集

    なるほど、おかげ様でAVRがより好きになってきました。
    PICでAssemblerから初めて、ちょっとばかり複雑になると、しまいには頭の中にMneumonicが入り乱れてしまい、何がなんだか分からなくなって、苦労してたときとは違って、楽しい感じがします。

    キャンセル

+2

EEMPEは2で、EEPEは1ですね
どっかにそう定義してありませんか

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/13 09:45

    さっそく観てみます。

    キャンセル

  • 2019/02/13 09:49

    質問に下記引用のように記載した件、すなわち;
    「このうち、Least Significant Bit から3番目の Bit 2は「EEMPE」で、これは、
    • Bit 2 – EEMPE: EEPROM Master Write Enable
    と説明があります。
    これのほかのBit1,Bit0は以下のように、
    • Bit 1 – EEPE: EEPROM Write Enable
    • Bit 0 – EERE: EEPROM Read Enable
    です。 」
    のことですか?

    キャンセル

  • 2019/02/13 10:23 編集

    定義場所を探せないなら、EEMPEやEEPEをプリントアウトしてみればどうでしょう

    ああ、シフト演算子がわからないというはなしなのかな?

    キャンセル

  • 2019/02/13 10:37 編集

    PICでRLF(意:Rotate Left Fr throuh C) を使っていたときは、8Bitを例えば、
    00000100
    のように並べて、これを<<して
    00001000にしてから
    Bit or する、というのをやっていました。
    なので、この例示の記述↓にまだ不慣れで、それで分かりません。
    ((value) |= (1UL << (bit)))

    キャンセル

  • 2019/02/13 10:47

    1UL ってのは1ですから(1のunsigned long)、bit分左にずらした数値をvalueにORするという意味になります
    1は、0000001(2進数) ですんで、1<<2 は、00000100 になりますね
    ということで、
    (1<<EEMPE)は 00000100
    (1<<EEPE)は 00000010
    のことを表してるってことになります

    キャンセル

  • 2019/02/13 10:53

    んで、
    value |= (1<<EEMPE);
    という式は、
    value = value | (1<<EEMPE);
    とおなじことなので、
    value のEEMPE目のビットを1にしている、って動作になりますね

    キャンセル

  • 2019/02/13 10:55

    お世話になります。
    coco_bauerさんからも先ほど詳細にご案内いただきました。おかげでやっと分かって来ました。

    キャンセル

+1

arduino.h にて定義
#define bitSet(value, bit) ((value) |= (1UL << (bit)))

bitSet と同じです
EECR レジスタの EEMPE , EEPE ビットを1にするだけです

iom328p.h にて定義
#define EECR _SFR_IO8(0x1F)
#define EERE 0
#define EEPE 1
#define EEMPE 2
#define EERIE 3
#define EEPM0 4
#define EEPM1 5


EECR |= (1<<EEMPE) は、
EECR = EECR | ( 0b00000001 << 2 )
EECR = EECR |   0b00000100
と同等です

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/13 09:44

    お世話になります。
    なるほど、Arduino.hの178行めにありますね。
    #define bitSet(value, bit) XX でbitset() と同じなのは分かりました。
    しかし、私が提示した疑問がまだ分かりません。
    つまり、
    「1つ Left Shift して、bit or する」というところです。
    この部分を分解して詳しくご案内いただけませんか?

    キャンセル

  • 2019/02/13 09:58

    bitset() でいう bit set は、おなじ Microchip社 の PIC で使う BSF(つまり Bit Set Fr) とはちがいますね.
    混同してました。
    すると、 ((value) |= (1UL << (bit))) の bit は bit numbering のことですね。
    まだいまいち分かりませんが、さっきよりは進みました、、、、

    キャンセル

  • この投稿は削除されました

  • 2019/02/13 11:12

    このようにわざわざ記述する意義は、
    Bit number 2 の EEPMEをhighにするときに、
    00000100
    を入力するより、
    EEPMEを「2」とDefineしておいて、この単語を使用して入力するほうが、入力の際の人為的ミスが減る、
    ということに思えます。
    だから、
    (1<<EEMPE)をもって「 00000100」としておいて、さらにこれをBit orすることにした、と推定しました。
    こんなところでしょうか。

    キャンセル

  • 2019/02/13 11:14

    失礼しました、上、投稿2件うっかりkoujikuuさんに宛ててしまいました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C++

    4069questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Arduino

    615questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。