基本設定
PA9をUSART1に,PA2をUSART2に設定します。
PA9とPA2をジャンパー線で接続しました。
UART1/2 を Half-Dulex にします。
Pin設定が Open Drain の Pull-Up であることを確認します。
上の画像にもありますが,Half-Duplex にすると RX ピンの設定は不要になりました。
一文字 UART1 と UART2 の両方から送ってみます。
char msg[]="1";
HAL_UART_Transmit(&huart1, (uint8_t *)msg, sizeof(msg), 1000);
uint8_t r1 = USART1->RDR; // maybe "1"
uint8_t r2 = USART2->RDR; // maybe "1"
HAL_Delay(1000); // break here
msg[0]='2';
HAL_UART_Transmit(&huart2, (uint8_t *)msg, sizeof(msg), 1000);
HAL_Delay(1000); // break here
r1 = USART1->RDR; // maybe "2"
r2 = USART2->RDR; // maybe "2"
HAL_Delay(1000); // break here
複数バイト受け取る
定義部分
/* USER CODE BEGIN 0 */
#define BUFFER_SIZE 32 // must be 2^n
uint8_t UART1_RX_Buffer[BUFFER_SIZE];
uint8_t UART1_RX_Count=0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
UART1_RX_Count = (UART1_RX_Count + 1 ) & (BUFFER_SIZE - 1);
HAL_UART_Receive_IT(&huart1, UART1_RX_Buffer+UART1_RX_Count, 1);
}
}
/* USER CODE END 0 */
main関数にて
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, UART1_RX_Buffer+UART1_RX_Count, 1);
char msg1[]="1a";
HAL_UART_Transmit(&huart1, (uint8_t *)msg1, 2, 1000);
HAL_Delay(10);
char msg2[]="2b";
HAL_UART_Transmit(&huart2, (uint8_t *)msg2, 2, 1000);
HAL_Delay(10);
char msg3[]="3c";
HAL_UART_Transmit(&huart1, (uint8_t *)msg3, 2, 1000);
HAL_Delay(10);
char msg4[]="4d";
HAL_UART_Transmit(&huart2, (uint8_t *)msg4, 2, 1000);
HAL_Delay(10);
/* USER CODE END 2 */
Half-Duplex では TX と RX が接続されているため,複数バイト送ったらその分も自分自身で受信処理しないとそのあとの受信ができなくなってしまいます。バッファを用意して,割り込みで直ちに受信するように仕掛けました。
送信が続くと受信に失敗するようで,上記では HAL_Delay(10); を入れています。8MHzで動作させていることも影響していると思われます。
いろいろ試してわかったのですが,とにかく受信割り込みで1データずつきちんと受信処理をするのがいいようです。
参考 感謝!
DMAですと,用意したバッファが全部いっぱいになった時点で割り込みが発生します。
受信数は愚直に数えるようにしてみましたが,以下の方法を使えばレジスタから知ることができるようです。こちらも感謝です。
おしまい
Harf-Duplex は勤務先の製品内で使われていて,STM32だとどのようにうごくのか調べてみました。STM32では設定するだけで本当にピン1つだけで実現できるのがいいですね。
久しぶりに使いましたが,Nucleo と STM32CubeIDE であればデバッガで動きがよくわかって助かります。





