STM HAL 同一SPIバス上ICのモード切り替え
SPI接続するICを2つ制御する場合、一番簡単なのは、SPIのバスを変えて2つ使う事。
これは簡単だが、場合によっては配線をその分必要とするので面積や、余剰のピン次第。
SPIのバスを1つにカスケードされたもののモードを動作中に変えられるか?
Can SPI clk polarity and clk phase be changed on the fly?
とかでも質問があがっており、”これは実践的なテストであり、ドキュメントで保証されるものではありません。”と言われている・・・・
HandleSpiBMP.Init.CLKPolarity = SPI_POLARITY_HIGH;
HandleSpiBMP.Init.CLKPhase = SPI_PHASE_2EDGE;
を変えられるか?という事を試した。
結論:変えられる。
ただし、一筋縄ではいかない。ICの素性にもよる。
必ずロジアナが手元にあって波形を見ながらいろいろ試して初めてできるという事が結論である。
When controlling two SPI-connected ICs, the easiest way is to use two different SPI buses.
This is easy, but in some cases it requires more wiring, so it depends on the area and the extra pins.
Can the mode of the cascaded SPI buses be changed during operation?
In other words, is it possible to change the mode of a cascaded SPI bus during operation?
HandleSpiBMP.Init.CLKPolarity = SPI_POLARITY_HIGH;
HandleSpiBMP.Init.CLKPhase = SPI_PHASE_2EDGE;
Can I change the I tried.
Conclusion: It can be changed.
However, it is not a simple task. It is possible only when you have a logic analyzer and try various things while watching waveforms.
【回路の作製】
ブレッドボードでジャンパーワイヤーを使って接続するとモジャモジャに!
ロジアナへのひっぱり出すと・・・さらにモジャモジャ!接続の詳細は割愛するが、SPIをカスケードして接続(マイコンのSCKの線からDACのSCKへ、そこからADCのSCKにと接続して、CCだけはマイコンからDAC用のGPIO(PA4)と、ADC用のGPIO(PA3)。DACはMISOを使わないので、この線はマイコンからADCへ)
【コード例】
やり方は、例えば、EDGE2をコードを自動生成させている場合、別のエッジを認識するSPIの設定を自分の関数として、自動生成されるMX_GPIO_Initをコピーして作り、EDGEの所だけ変える。
static void MX_SPI1_Init_EDGE1(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
これを関数を呼び出したら、呼んであげる。(毎回初期化するようなもの)
もう一つの関数側は、自動生成されるMX_GPIO_Initをコールする。つまり、
DACはMX_GPIO_Initのままで
ADCは関数冒頭で、MX_SPI1_Init_EDGE1(自作関数)を呼ぶ。
ちゃんとDACも動いて、ADCも動く・・・がしかし、一つ目のチャンネルが電圧が出てない。テスターを当てても出ていない。
https://moons.link/post-356/
に一番最初だけ動かないという時の対処が載っていたのを覚えていたので、対処してみた。
コメント
コメントを投稿