gombeのブログ

マイコンの電子工作系PIC32/KiCad/C/C++/3D/

マイコンのDMAでの断続的な転送


DMA 単一のアドレス空間上にはFlashペリフェラル(周辺機器)のレジスタ、RAMメモリがある。この空間の間は通常CPUなどがアクセスしてメモリ間転送している。

img_2582

これはCPUにやらせてもいいのだがCPUはリソースを取られるし一定時間内で転送しなければならない項目が重なるとデータをこぼしかねない。なのでその代わりにDMAを使ってCPUを返さず直接的にメモリとペリフェラル(周辺機器)間をアクセスするのがDMAである。

img_2583

これは非常に便利なものである。使い方を説明する。転送時にはやみくもにあるまとまった量を転送するバーストモードとトリガーがかかったら(引き金、転送要因という)転送するモードがある。今回はPWMのdutyを一周期ごとにセットしたいのでトリガーの方を用いる。

今回はメモリからペリフェラルへ転送する方について触れるが逆も同様である。 各ペリフェラルの転送先には必ずアドレスがあるのでそれをセットする。手元にあるバッファのアドレスもセットする。手元にあるアドレスはポインタインクリメントする。転送先のアドレスはインクリメントしない。また送信先のアドレスのデータ長も定義する。送信先と手元のバッファはデータ長が一致する必要がある。そうしたら送信要因を設定する。これは今回はPWM1周期分出し終えたタイミングにセットする。データが枯渇するとまずいので半分転送が完了した段階でに割り込みをかける。転送許可を与えて転送準備が完了する。あとは必要に応じて転送が開始される。半分以上転送が完了すると割り込みがかかるので、以後に最初の半分のデータをセットする。最終転送が完了したらまた割り込みがかかるのでそしたら再度転送を開始する。そしたらまた半分から最後までデータをセットする。

CPUからデータセット

img_2584

転送開始で一番目のデータを転送。図中☆は転送元ポインタの参照先である。

img_2585

二番目を転送すると半分転送完了割り込みがかかる

img_2586

CPUは割り込み処理で最初の半分にデータを入れる。図ではその最中にも三つ目のデータを送信している。

img_2592

最終転送が完了すると割り込み処理にはいる。ここで再度DMAを有効にすることで再度転送を開始することができる。

img_2593

この際に後半にもデータを入れておくようにする。これを繰り返して実行し、データを断続的に送信する。

img_2594