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の動作確認を行います。