STM32 USARTを使う。ピンのAlternativeFunctionを設定する

さて、前回はタイマという内部的な話でしたが、今回はシリアル通信をやってみましょう。

シリアル通信とは?

シリアル通信の内容はちょっと個々では省きます。知ってる人向けね。
一応概要だけ書くと、元々は”ちょっと離れた”マイコン同士が通信するための通信方式で、最低でも送信・受信・GNDの3本をつなげばお互いに通信できます。

もちろんこれ用のペリフェラルがあって、STM32F407にはUSARTペリフェラルというのが入っています。
これを使えばピンの設定や通信速度の設定をするだけで実際の通信がどうなっているのか気にしなくても送信と受信ができます。
今回はこれを使ってパソコンと通信してみましょう

配線する

今回はソフトだけでは作れなくて、回路も必要になります。
STMと通信するためにパソコンからUSART通信できるFTDIケーブルをつかいます。
これを使えばパソコンのソフトからUSARTを送受信できます。

stmftdi
出典: 秋月電子

あとはSTMのどこに繋げばいいのでしょうか。
普通ならUSARTの送信をするTXと受信をするRXのピンがあるはずですが、どこにUSARTのピンがあるんでしょうか。

GPIOのAlternativeFunction

実はUSART専用のピンはなくて、GPIOとの共有ピンになっていてGPIOの設定をすることでUSARTピンとして切り替えて使います。
切り替えると当然ながらGPIOとしては入力も出力も使えなくなるのですが、USARTのピンとして使えるようになります。
ただ、「じゃあPortAの0をTx(送信)にする!」みたいにどのピンでもUSARTのピンに出来るわけではありません。
まず、ピン1つに16種類までの機能が割り振られていて、その16種類のどれかに切り替えるという感じになります。
GPIOのこの機能の切り替えをAlternativeFunctionというのですが、
例えばGPIOAの0番ピンはAlternativeFunction1として設定するとタイマー用のピンとして使えて、AlternativeFunction8にするとUSART4のTXとして使えます。

stm_uart_af
AlternativeFunctionのどれが何なのかはハードウェアリファレンスに全て書いてあります。

stm32f4_uart

なので、USARTの送信を使いたい!と思ったらUSART_TXというのがUSARTの送信なのでこれがAFの中に入っているピンを探さないといけないです。PortAなんだったら、PA2のAF7がUSART2のTX(USARTは1~6まである)ですし、PA9のAF7もそうです。他にもありますね。

いろいろありますが、今回は僕がLEDなど他のものに何もつながってないのを確認したPA2とPA3をUSARTのTXとRXに切り替えて使いましょう。

配線する

先に配線しちゃいましょう。
PA2がTXでPA3がRXというのが決まったので、FTDIとつなぎます。

stm_uart_connect

こんな風に3本繋げばOKです。
僕はピンヘッダを使ってこんな風にしました。

stm_uart_photo

これで回路の準備は完了です。
プログラムに入りましょう。

UARTにピンを切り替える

では、実際にピンをUSARTに切り替えてみましょう。
GPIOペリフェラルで設定するだけです。
やることはモードをAFに切り替えて、AFの中でもUSARTがあるAF7に切り替えるだけです。
GPIOを初めて使った時の設定を思い出してみましょう。
AFへの切り替えはMODERレジスタです。
Screen Shot 2016-01-05 at 22.16.17

ピン1つ1つを入力にしたり出力にしたり出来るれジスタでしたね。
これの設定 10 がAlternative functionというもので、入力でも出力でもなく、他のペリフェラルに切り替えるというものです。
PA2とPA3をAlternativeFunction(10)にします。

次にAlternativeFunctionのどれなのかを選択します。
使うのはGPIOのAFRLかAFRHレジスタです。
stm_uart_af

4bitで指定します。
AFRLとAFRHの2つのレジスタがあるのは、1つのピンに設定が4bitもあり、レジスタに入りきらなかったので2つのレジスタに分かれています。
AFRLは ポートの0〜7
AFRHは ポートの8~16
に関する設定が入っています。
今回はPA2とPA3をAF7にしたいので、AFRLのAFRL2とAFRL3のところを 0111にすればOKです。

ここまでの設定をプログラムにするとこうなります

GPIOA-> MODER      = 0;
GPIOA-> AFR[0]     = 0;

GPIOA-> AFR[0]     |= GPIO_AF7_USART2 << 8;
GPIOA-> MODER      |= 0b10 << 4;

GPIOA-> AFR[0]     |= GPIO_AF7_USART2 << 12;
GPIOA-> MODER      |= 0b10 << 6;

まずAFRLとAFRHはAFR[0]とAFR[1]としてアクセスできるように用意されています。
また、AF7は0111という値ですが、
GPIOA->AFR[0] |= 0b0111 << 8;
としなくても見やすくなるようにGPIO_AF7_USART2として既に用意されていますのでこれを使います。

いよいよUSARTを使う

ここまで長かったですが、USARTをピンにつないだだけです。
ここからやっとUSARTを使います。
ちょっと長くなったので次回やりましょう。