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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C++

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

Arduino

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

Q&A

解決済

3回答

337閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

C++

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

Arduino

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

0グッド

0クリップ

投稿2019/02/12 15:24

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があげられています。

code

1// C Code Example 2char cSREG; 3cSREG = SREG; /* store SREG value */ 4/* disable interrupts during timed sequence */ 5_CLI(); 6EECR |= (1<<EEMPE); /* start EEPROM write */ 7EECR |= (1<<EEPE); 8SREG = cSREG; /* restore SREG value (I-bit) */ 9 10//参考: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」したら、、、、
(おっと、ちょっとへんだぞ、、、)

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

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

投稿2019/02/12 15:29

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/02/13 00:45

さっそく観てみます。
退会済みユーザー

退会済みユーザー

2019/02/13 00: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 です。 」 のことですか?
y_waiwai

2019/02/13 01:24 編集

定義場所を探せないなら、EEMPEやEEPEをプリントアウトしてみればどうでしょう ああ、シフト演算子がわからないというはなしなのかな?
退会済みユーザー

退会済みユーザー

2019/02/13 01:37 編集

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

2019/02/13 01:47

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

2019/02/13 01:53

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

退会済みユーザー

2019/02/13 01:55

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

0

ベストアンサー

「この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 00:59

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/02/13 01:09

お世話になります。 >使われている "<<" は左ビットシフトの演算子で、 "x << y"という式はxの値を左にyビット分シフトする(ずらす)という事を意味します。 すると、私が例示した; (1<<EEMPE) は、EEMPEの値(0 or 1)を、左に「1」つ移動するのではなく、 「1」を左に「EEMPEの値」分移動する、 という意味になりますか。
coco_bauer

2019/02/13 01:20

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

退会済みユーザー

2019/02/13 01:43 編集

なるほど、そういうことですか! もう一つお願いします。 >EEMPEは2だとiom328p.hで定義されていますから、 ということの定義の意味に、Bit number 2 の 「EEMPE」が、このBit numberの「2」と同じに定義されているのとは、相関がありますか?
退会済みユーザー

退会済みユーザー

2019/02/13 01: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 02:13

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

2019/02/13 02:37

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

退会済みユーザー

2019/02/13 02:53 編集

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

0

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/12 16:32

編集2019/02/13 01:28
koujikuu

総合スコア401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/02/13 00:44

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

退会済みユーザー

2019/02/13 00:58

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

退会済みユーザー

2019/02/13 02:12

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

退会済みユーザー

2019/02/13 02:14

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問