RA4M1マイコンのレジスタ解説① PCNTR1とPODRとPDR 

 

 今からこの記事を読もうとしているそこのあなた、もちろんRA4M1マイコンのユーザーマニュアルを手元にありますよね?

まさかとは思うが、もし万 万が一無いって人は、即刻入手すること。

ここからダウンロードできる。

https://www.renesas.com/jp/ja/document/mah/renesas-ra4m1-group-users-manual-hardware?r=1054146

 

 開いてその量に臆することはない。 順番に理解していけばいいのだから。

まずは、最も基本で最もよく使うであろう汎用入出力端子についてのレジスタから解説していこうと思う。 さぁマニュアルを開いてみよう。

416ページから汎用入出力端子の説明が書かれている。

 

 「19. I/O ポート」という章のボリュームはそれほど多くはなく、必要なところだけを絞ればもっと理解するのは簡単だろう。

全てを読むのは大変だし、解説するのも大変なので、その必要なところを一つひとつ解説していこうと思う。

 

 418ページの「19.2.1 ポートコントロールレジスタ1(PCNTR1/PODR/PDR)」の所から始めよう。

ここには、PCNTR1とPODRとPDRという3つの名前が書かれている。 これは3つのレジスタと思うかもしれないが、実はPCNTR1という32ビットのレジスタの中にPODRとPDRという2つの領域があるのだ。 なので、この3つで1つのレジスタである。 まさに三位一体。

 

 詳しく書くと、PCNTR1内の上位16ビット(16~31ビット)がPODRで、下位16ビット(0~15ビット)がPDRとなっている。

なんでこのような構造になっているかはわからないが、Arduino DUEマイコンボードで使われているAtmel製 SAM3X8Eプロセッサとは仕様が全然違う。 同じArmプロセッサなのに。
正直、このRA4M1マイコンのように32ビットレジスタを16ビットと16ビットに分ける方式は使いづらくてあまり好きになれない。 と思うのは私キャッスルだけか?

理由はわからないが、もともと16ビットマイコンの設計を流用しているのではないかと勘繰ってしまう。

 

 PDR

 これは汎用入出力端子の方向を指定するビットである。 個々の端子を入力端子にするか、出力端子にするかを設定できる。 入力端子にしたければ'0'を、出力端子にしたければ'1'を設定すればいい。

 個々の端子って何じゃい、って思う人はマニュアルの67ページ「1.7 端子一覧」を参照してもいいし、62ページの「図 1.5 64-pin LQFP のピン配置図(上面図)」を見てもいいし、Arduino UNO R4の回路図を見てもいい。

Arduino UNO R4の回路図はここからでもたどれるようになっている。

 

 

回路図を読むのが苦手なら、Arduino UNO R4の公式サイトのピンアウトの図を見てもいいだろう

Arduino UNO R4のピンアウトはここからでもたどれるようになっている。

 

情報が散らばり過ぎてよくわからん、ってなるなら、キャッスルが作成した端子機能一覧を参照されたし。

それはここの記事に書いてある。

 

上記の資料を参照すれば、個々の端子がどこにあるかわかるだろう。

 

 例えば、Arduino UNO R4のD0ポートの端子はP301、D1ポートがP302、D9ポートがP303、D8ポートがP304となっているので、PORT3のPDRに16進数で"1e"(b00011110)を代入すれば、D0, D1, D9, D8のポート全てが出力設定となる。

Arduino IDEでの記述ではこうなる。

  R_PORT3->PDR |= 0x1e;

これは、

  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);

と記述するのと同じ結果となる。

 

  R_PORT3->PDR &= ~0x1e;

もしこのように記述したら、D0, D1, D9, D8のポート全てが入力設定となる。

  pinMode(0, INPUT);
  pinMode(1, INPUT);
  pinMode(9, INPUT);
  pinMode(8, INPUT);

これと同じ結果となる。

 

 

 PODR

 これは出力に設定された汎用入出力端子の状態を指定するビットである。 個々の端子の出力をHIGHにするかLOWにするかを指定する。 HIGHというのは、端子の電圧を5Vにすることで、LOWとはGNDと同じにすることだ。

 

 例えば、Arduino UNO R4のD0, D1, D9, D8のポート全てが出力設定となっている前提で、PORT3のPODRに16進数で"1e"(b00011110)を代入すれば、D0, D1, D9, D8のポート全てが5V出力状態となる。

Arduino IDEでの記述ではこうなる。

  R_PORT3->PODR |= 0x1e;

これは、

  digitalWrite(0, HIGH);
  digitalWrite(1, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(8, HIGH);

と記述するのと同じ結果となる。

 

  R_PORT3->PODR &= ~0x1e;

もしこのように記述したら、D0, D1, D9, D8のポート全ての出力が0Vになる。

  digitalWrite(0, LOW);
  digitalWrite(1, LOW);
  digitalWrite(9, LOW);
  digitalWrite(8, LOW);

これと同じ結果となる。

 

 

 PCNTR1

 先にも言ったとおり、PCNTR1レジスタの中にはPDRとPODRを内包している。 なので、PORT3のPCNTR1レジスタに直接値を代入すると、入出力指定と出力状態を同時に制御することができる。 そんな使い方をわざわざする必要はないとは思うが。

例えば、

  R_PORT3->PCNTR1 = 0x1e1e;

このように記述すると、D0, D1, D9, D8のポート全てを出力設定して同時に5V出力もする。 この1行だけで。

ちなみに、

  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  digitalWrite(0, HIGH);
  digitalWrite(1, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(8, HIGH);

この8行のプログラムが上の1行で済んでしまうのだ。

でも、設定と出力を同時にって、普通しないよね。

なので、設定だけの32ビットレジスタや出力だけの32ビットレジスタのように独立した設計にしてほしかった。