static uint16_t SPI_Baud = 0; static void SPI_BaudLow(void) { SPI_Baud = SPI1->CR1 & 0x0038; SPI_Cmd(SPI1, DISABLE); SPI1->CR1 = (SPI1->CR1 & 0xFFC7) | 0x0038; SPI_Cmd(SPI1, ENABLE); } static void SPI_BaudHigh(void) { SPI_Cmd(SPI1, DISABLE); SPI1->CR1 = (SPI1->CR1 & 0xFFC7) | SPI_Baud; SPI_Cmd(SPI1, ENABLE); }
SPI_BaudLowではSPIを最低の速度で駆動する。72MHzなら281.25kHzとなる。またSPI_Baudに速度をバックアップする。
SPI_BaudHighではバックアップされたボーレートをレジスタに書き戻す。これはSPI_Initで設定した値になる。またSPI_BaudLowを呼ばれていない場合はSPI_Baudには0が入っており、これは分周比2となる。
それとボーレートの設定は通信中に変更してはいけないらしいのでSPI_Cmdでペリフェラルを終了させている。
ちなみにSPI_Cmdの中ではCR1のSPEを変更するだけなので、本来のSPI停止方法ではない。STM32F1のリファレンスマニュアルによると、RXバッファに値が入るまで待つ→RXバッファを読む→TXバッファが空になるまで待つ→ビジー状態でなくなるまで待つ→SPIを無効にする、という手順を踏む必要がある。ただこの方法は結構手間なのと、そもそも通信中にSPIを停止させるための手段なので、非通信時に変更したいのでSPI_Cmdだけで問題ないと判断した。
SDカードをSPIで使用するには、初期化時には100-400kbaudにする必要があるらしい。とりあえず36MHzでも問題なく初期化できているが、どうせ初期化するには200msecほどかかるので280kbaudでも36Mbaudでも大して変わりはない。
0 件のコメント:
コメントを投稿