IoT装置としてSTM32(STM32ファミリー STM32L476RG)を利用していたときに、装置に対する設定指示にシリアル(UART)を利用していたのですが、うまく動作しないケースが発生していました。原因を調査したところ、UARTの受信データの取りこぼしが発生している事がわかりました。
当初、UARTの通信速度は、9600bps(それほど早くない)でしたので、UARTの受信による割り込み処理内で、受信データの取込み処理を行う設定としていました。受信割込の処理を時短しても取りこぼし現象が改善しなかったため、以下の様な対応としたところ、問題を解決する事が出来ました。同様な課題をお持ちの方の参考になればと思います。
(UART RX)
・受信割り込みをやめる
(DMA)
・DMA機能を用いる
DMA Request Setting
Mode:Circular
Increment Address:Memory
Data Width:Byte
・テーブルと容量を設定
(例)HAL_UART_Receive_DMA(&huart1,シリアル受信テーブルアドレス, 1000);
→これによって、シリアル受信テーブルに受信データが自動的に登録される
また、1000バイトになったら、0に戻って登録が行われる
(TIMER)
・タイマの割込設定
10msごとに割込み
・タイマ割込処理にて、シリアル受信テーブル内のデータ処理を実行する
DMAによる書き込み位置は、以下から取得できます(UART2の場合)
(例)huart2.hdmarx->Instance->CNDTR
※ここは、自動生成されたテーブル(構造体)となります。
機種ごとに生成されるコードが微妙に違うようです。
<前提>
・C言語を利用しました
・シリアル受信がシステム上でどの程度連続して発生するかによって、テーブルサイズやタイマの周期を変更する必要があります
シリアル受信が途切れなく受信する場合には、この方法は使えません。シリアルを遅くするしかありません。
(本記事にたいする質問やお問合せ・IT改善のご相談はこちら)