こんにちは。shuji4649です。
この記事は Tuton Advent Calender 2025 の6日目の記事です。
はじめに
STM32をPlatformIO・Arduino言語で開発する際のUARTについて、去年このような記事を書きましたが、その時に未解決だった課題がありました。
STM32では、大体一つのUARTに対してTXとRXがそれぞれ複数のピン用意されているのですが、どのTXとRXの組み合わせでも使えるわけではなく、同じ系統のUARTのTXとRXでも使えない組み合わせがあります。
これはSTM32全体の問題なのかArduinoフレームワークの問題なのかPlatformIOの問題なのかよくわからないのですが、PlatformIOのArduinoフレームワークで開発しようと考えている人は、基板で実装したりする前にNucleoボード等で確認してみることをおすすめします。
基本的にピンが隣り合っている組み合わせだとうまくいって、そうでない場合はうまくいかないようです。
もし原因や解決策のわかる人がいらっしゃいましたら教えていただきたいです。
これです。
これに対する解決策を見つけたのでご紹介します。
PeripheralPins.cを見よう
こちらのGitHubリポジトリからArduino for STM32のコードが見られます。
ここに、各STM32マイコンのピン機能を保存しているPeripheralPins.cが公開されています。
これはSTM32F446REの例です。
これのUARTのところを見ると以下のように記述されています。
//*** UART ***
#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_TX[] = {
{PA_0, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
{PA_2, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PA_9, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PB_10, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{PC_6, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
{PC_10, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
{PC_10_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{PC_12, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
{NC, NP, 0}
};
#endif
#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_RX[] = {
{PA_1, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
{PA_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PA_10, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PB_7, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PC_5, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{PC_7, USART6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
{PC_11, UART4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
{PC_11_ALT1, USART3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{PD_2, UART5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
{NC, NP, 0}
};
#endif
UARTを使用する際は、ここに書いてある通りのピン名で指定しなければなりません。
つまり、PC10とPC11でUART3を使いたいときは、
HardwareSerial uart(PC_11, PC_10);
では動かず、
HardwareSerial uart(PC_11_ALT1, PC_10_ALT1);
としなければなりません。
これはUART以外でも同様なので、困ったらこのPeripheralPins.cを見るようにしましょう。
さいごに
Arduino言語でのSTM32開発は分かりやすくて便利ですが、ネットに情報はあまりないので、困ったらこのリポジトリを除いてみるのがよさそうです。