LEDとスイッチの確認ができたので、次はSTEP2 UART通信&printf関数になります。UART通信は前回やりましたが、printf関数を使えるようにします。
既に先達が出しているので、それを行います。




回路図
回路図を見て、どのポートを使っているかを見直します。Tx(送信ポート)はPC10、Rx(受信ポート)はPC11にしています。
STM32CubeMX
CubeMXで設定を行います。不具合が起こったときの切り分けのため、前回のプロジェクトに追加・編集せず、新規でプロジェクトを作成していきます。
最初に、Pinout viewのPC10とPC11のピンを、左クリックでそれぞれUSART3_RXとUSART3_TXを設定してから、UART3 Mode and ConfigurationでAsynchronous(非同期)を選択します。
USART3は他のピンにも割り振ることができるため、別のところが選択されることがあります。予めピンを直接設定してあげると、やり直す手間が減ります。
通信速度の設定を行うので、Parameter Settingsタブをクリックして、Baud Rateを入力します。デフォルトでは115200 Bits/sになっていますが。端末エミュレータのTera Termで簡単に設定できる上限である最大ボーレート921600 Bits/sにします。
ただし、そのままだとエラー率が+2.12%になるぞとワーニングが出てきます。CPUや周辺回路の通信速度がデフォルトだと遅すぎるため、そちらも編集します。ここはSTEP1と同じように設定します。
UARTに関わるクロックは、「USARTクロック(FCK)は、いくつかの供給源から選択することができる:システムクロック、ペリフェラルクロック(APBクロック)、HSI 16 MHzクロック、LSE 32.768kHzクロック。 」とのこと。
APB peripheral clocksはAPB1とAPB2の2つあるのですが、データシートのBlock Diagramを見ると、APB1の方が接続されているようです。
プログラム
最初に、stdio.hをmain.cにインクルードします。
/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> /* USER CODE END Includes */
UART通信を標準出力に設定することができるように__io_putcharと__io_getcharという関数を定義します。鉄鼠はUSART3にしているので、HAL関数内の引数も変更しています。
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int __io_putchar(int ch) {
HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 100);
return ch;
}
int __io_getchar(int ch) {
HAL_StatusTypeDef Status = HAL_BUSY;
uint8_t Data;
while(Status != HAL_OK)
Status = HAL_UART_Receive(&huart3, &Data, 1, 10);
return(Data);
}
/* USER CODE END 0 */
setbuf関数でバッファのリセットをします。あと、変数も用意。
/* USER CODE BEGIN 2 */
setbuf(stdout, NULL);
setbuf(stdin, NULL );
printf("Started!\n\r");
int32_t val = 0;
float a = 0.0;
/* USER CODE END 2 */
ループ内に、printf関数とscanf関数、演算を入れます。
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
printf("Input integer val = ");
scanf("%d", &val);
printf("%d\n\r", val);
printf("Input float a = ");
scanf("%f", &a);
printf("%f\n\r", a);
val = val * val;
a = a * a;
printf("val^2 = %d, a^2 = %f\n\r", val, a);
/* USER CODE END WHILE */
これでRunを押すと、Floatのフォーマットサポートに問題があると注意されて、チェックを入れるよう指示をされます。
実際にTera Termで入力してみると、Integerであるvalの入力はうまくいきますが、floatのaの入力で暴走します。
なので、Propertiesで下記のようにチェックを入れて、printfとscanfでfloatを使えるようにします。
実行
実行すると、出力と入力の両方ができるようになりました。
次は、ADCの動作確認を行います。








