LSI Jiu-Jitsu

電子工作とブラジリアン柔術

STM32で遊ぶ (6) - GPIO AFモード

STM32F446REでI2Cなどの機能を使用する際に設定が必要となるGPIOのAFモードについて理解した点を纏めてみました。

ポートに各機能を割り当てるには、該当ポートを「Alternate function mode(オルタネート・ファンクション・モード)」(以下AF)で使用します。
AFは16種類ありポートに割り当て可能なAFは予め決められています。
ポートとAFの関係は下記のデータシート(stm32f446re.pdf)に記載されています。

https://www.st.com/ja/microcontrollers-microprocessors/stm32f446re.html
f:id:mohran:20200313233539j:plain


I2C1を使用する際は、Table.11よりPB8と PB9をAF4に設定する必要があります。

f:id:mohran:20200313233704j:plain

設定するレジスタはGPIOB_MODERとGPIOB_AFRHの2つになります。
MODERレジスタでモードをAFに設定して、AFRHレジスタでAF番号「4」を指定します。
今回はPB8とPB9の設定なのでAFRHレジスタとなりますが、PB0~7のAFを設定する際はAFRLレジスタになります。

f:id:mohran:20200313233754j:plain
f:id:mohran:20200313233803j:plain

I2Cで使用する際にはオープンドレインと、内部Pull-upも設定しておきます。
f:id:mohran:20200319225135j:plain

f:id:mohran:20200313233821j:plain


SPLを使用した記述はこんな感じになりました。

GPIOB->MODER  |= ((0x2 << 18) | (0x2 << 16));
GPIOB->AFR[1] |= ((0x4 <<  4) | (0x4 <<  0));
GPIOB->OTYPER |= ((0x1 <<  9) | (0x1 <<  8));
GPIOB->PUPDR  |= ((0x1 << 18) | (0x1 << 16));

または

*(volatile unsigned int *)(GPIOB_BASE + 0x00) |= ((0x2 << 18) | (0x2 << 16));  // MODER
*(volatile unsigned int *)(GPIOB_BASE + 0x24) |= ((0x4 <<  4) | (0x4 <<  0));  // AFRH
*(volatile unsigned int *)(GPIOB_BASE + 0x04) |= ((0x1 <<  9) | (0x1 <<  8));  // OTYPER
*(volatile unsigned int *)(GPIOB_BASE + 0x0c) |= ((0x1 << 18) | (0x1 << 16));  // PUPDR


これでI2C1が使用できました。
NUCLEO-F446REのピンは下記の位置になります。

f:id:mohran:20200313233844j:plain

ちなみにPB6, PB7もI2C1に割り当てられています。
こちらでも使用できましたが、PB8, PB9と両方同時にAF4に設定すると動作しませんでした。

[参考記事]