記事ディレクトリ
最近、STM32のSPIスレーブモードを使って、他のボードからSPIデータを読み込んでシンクホールを2つ踏んで、その過程を記録してみます。
(halライブラリは3つの関数を提供しているので、ブロック、割り込み、DMAを順にデバッグ・学習するのがデバッグ手順です。このコードはDMAを使用したコードです。 )
ソフトウェア:keil5、STM32CubeMX
ハードウェア: STM32F103C8T6 最小システム 2 つ
実現された機能: マスターとスレーブの 2 つのボードが SPI1 を使用して SPI 通信を実行します。
コードのダウンロード github : https://github.com/wyfroom/SPI_Master_Slave_STM32 (最初のプログラミング プロセス中にコードを管理するには git を使用します)
コードダウンロード Lanzout Cloud : https://wwzr.lanzout.com/b04885ouf パスワード: 372j
強調!!!!!!!!!!!強調!!!!!!!!!!!!強調!!!!!!!!!!!!!
SPI は接続されているが、送信できるか受信できないかなど、データが不可解に文字化けしている場合は、何もせず、まずDupont ワイヤーを新しいものと交換します (合計 5 本のワイヤー、1 つの共通アース)ワイヤ、および 4 本の SPI ワイヤ。
1. SPIホスト構成
基本的なプロジェクト構成については、ここにはマップはありません。詳細な手順は、http://t.csdn.cn/Wpcpk で確認できます。
spi の構成を直接見て、主に次の点に注意してください。
- SPIモードの選択
- チップの選択
- ビッグエンディアンリトルエンディアン選択
- 通信速度
- サンプリングモード設定(CPOL、CPHA)
- CRCの選択
SPI割り込みを使用する場合は、割り込みにチェックを入れてください。
DMA を使用する場合は、DMA を設定する必要があります。
補足:チップの選択が必要です。選択しないと高速伝送に問題が発生します。
2. SPIスレーブ構成
スレーブマシンのモード選択のみがマスターマシンと異なり、その他は同じであり、同じである必要があります。
割り込みを使用する場合は、次のチェックボックスをオンにします。
DMA 構成: (ホストと同じ)
補足:やはりチップの選定は必要です、そうしないと高速伝送時に問題が発生します。
三、双机通信
HAL ライブラリには 3 つの SPI 呼び出しメソッドが用意されています。すべて試してみましたが、最終的に効率的で簡潔な DMA を選択しました。
//阻塞方式使用SPI
HAL_SPI_Transmit()
HAL_SPI_Receive()
HAL_SPI_TransmitReceive()
//中断方式使用SPI
HAL_SPI_Transmit_IT()
HAL_SPI_Receive_IT()
HAL_SPI_TransmitReceive_IT()
//DMA方式使用SPI
HAL_SPI_Transmit_DMA()
HAL_SPI_Receive_DMA()
HAL_SPI_TransmitReceive_DMA()
1ポーリング+割り込み(低速)
マスターがポーリングし、スレーブが割り込みます。
ここではこれについては説明しません。通常のプロセスだけを説明します。注意して、メインで割り込みを開始し、割り込み関数で再度割り込みを開始します。
//main里启动中断
HAL_SPI_TransmitReceive_IT(&hspi1, sendData, receiveData, 8);
//中断回调函数
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
// 数据发送完成回调函数
if (hspi == &hspi1)
{
HAL_SPI_TransmitReceive_IT(&hspi1, sendData, receiveData, 8);
}
}
2 ポーリング + DMA (低速)
マスターはブロッキング機能を使用し、スレーブは DMA 機能を使用します。(その理由は、マスターとスレーブの両方で DMA を使用しようとすると、速度が速すぎてスタックし、データ送信が文字化けしてしまうためです。これは解決されました。問題 1 がわかりますが、この部分はまだ未解決です。ポーリング+DMAのデモ)
ホスト:
スレーブ:
デバッグテスト:
3 DMA+DMA (高速)
高速使用前はプログラムが固まってデータ化けていました。(高速使用:遅延なくブロッキング機能を使用、マスターとスレーブの両方で割り込みを使用、マスターとスレーブの両方でDMAを使用)
解決策は次のとおりです。
- 1 チップセレクトをオンにします。2枚のボードのハードウェアチップセレクトを直接オンにし、双方ともDMAを使用して全二重で送信と読み取りを行ったところ、データ化けはしませんでしたが、最初に受信したデータが最初に送信したデータとは限りませんでした。
- 2 スレーブはマスターより先にプログラムを開始します。前の手順でデータの順序が正しくない問題を解決します。ホスト DMA プログラムが開始する前に 2 秒の遅延を追加します。
ダイレクト デバッグ: (実際の電源をシミュレートします。デバッグは、最初にスレーブをクリックして開始し、次にホストをクリックして開始します)
4 CRC チェックを有効にする (オプション)
CRC計算により生成されるチェック値は、送信時や保存時にデータの誤りや破損を検出するために使用できます。
CRC を有効にした後、DMA 機能を使用する場合は、SIZE を 1 つ増やす必要があります。
HAL_SPI_TransmitReceive_DMA(&hspi1, sendData, receiveData, 8+1);
4. 発生した問題
1 高速で使用するとプログラムが固まったり、データが間違ったりする(解決済み)
-
マスタ割り込みモードで送信、スレーブ機割り込みモードで受信、連続してクリアフラグを送受信するとデータが乱れます、送信が速すぎるのでしょうか?? フルスピードで送受信していると思いますか? ホストはポーリング方式を使用して 1ms 程度の間隔で読み取る必要がありますが、SPI 速度はどのように計算しますか?
-
ホスト マシンが DMA を送信し、スレーブ マシンが DMA を受信すると、直接クラッシュします。DMA 割り込みが最大値に達します。その間、プログラムは実行する機会がありません。DMA 割り込みをシールドできます。プログラムはクラッシュしませんが、データは失われます。めちゃくちゃになります。
-
CRCを追加すると少しは改善されるようですが、まだ文字化けが多く、運が良かっただけです。これは機能しますか?SPIってそういう用途じゃないの?それとも高速通信によくある問題なのでしょうか。
-
最終的に解決しました:
- 1 チップセレクトをオンにします。2枚のボードのハードウェアチップセレクトを直接オンにし、双方ともDMAを使用して全二重で送信と読み取りを行ったところ、データ化けはしませんでしたが、最初に受信したデータが最初に送信したデータとは限りませんでした。
- 2 スレーブはマスターより先にプログラムを開始します。前の手順でデータの順序が正しくない問題を解決します。ホスト DMA プログラムが開始する前に 2 秒の遅延を追加します。
- 3 CRC、オンかどうかは関係ありません。
2 原因不明のデータ化け、ホストは正常に送信、受信は文字化けなど。
- Dupont ワイヤーは本当に問題を引き起こすので、新しいものに交換し、5 本すべてのワイヤーを新しいものに交換します。再試行する