2026年6月11日木曜日

【STM32】DACのDMAを4MHzよりも速くするとCPUがhangup

メモリ上のリングバッファに置いたsine波tableをDACから出力させます.
TIM2→DMA→DAC3 の流れです.
sine波は10点で1波です.
したがって、400kHzのsine波を出すためには、TIM2→DMA→DAC3が4MHzで動きまくる必要があります.

さてここでトラブルが発生しました.
トラブル: sine波400kHzまではOKなんですが、440kHzよりも周波数を高くするとCPUがhangupします.

検証:
・メモリの問題はなさそう
・DAC3は15MHzまでは対応可
・TIM2の設定は正常

だとすると残りはDMAが速度違反で死んでると想像されるが、たかが4MHzで死ぬDMAなんざDMAじゃねぇ.

というわけでAIに質問したらなかなか的確な回答が返ってきました.

Q: STM32G431において、TIM2からDMAへのトリガ周期を4MHzよりも高速な設定にするとCPUがhangupします.原因はなんでしょうか?

A: 最大の原因はDMA転送要求が多発してバスが飽和し、CPUが命令をフェッチ・実行するためのバス帯域を喪失したことです。DACは15MSPSです。しかしこれは「DACが処理できる限界」であり、手前の「バスが処理できる限界」が4MHz付近で先に限界を迎えます。

A: TIM2はAPB1バスにぶら下がっています。DMAがTIM2にアクセスする際、AHBからAPBへのブリッジを通過する必要があります。

やっぱりそうか...
これについてはAIのおっしゃることを信用してよろしかろう.

AIは対策をいくつか提案してくれたけど、
うまくいかなくて詰みました.

撤退でぇす.

ーーーー
その後も詰んでいるのは相変わらずなんですが、、、
DMA_complete_IRQ()みたいな割込みハンドラがバス帯域を喰ってると思うので、NVICを操作してIRQを片っ端から削除してみたら、DMAがcircular動作しなくなっちゃって、DMAの自動グルグル回しにIRQが関与してるんだなぁ.完全hardじゃないみたいよ.

ーーーー
撤退後・・・

いま作っている装置が0.1Hz~100Hzぐらいの測定帯域なのでsine波発生器を自作したのでした.ところが1MHzまで帯域を伸ばすことになったけど信号発生器を持ってないので改造に着手しました.しかしそもそも1MHzまでsine波で出そうとしてDACを使って死んだというのが事の発端だったので、sine波は諦めて、矩形波でOKにします.矩形波ならばTIMERで簡単に出せます.

Arduino nanoで作るのでAIにcodeを生成させました.しかしArduino nanoを探したら先日の投稿のとおりmini-USBのnanoしか在庫が無くて、嫌になっちゃった.

CPU箱を探したら以前作ったSTM32G030の基板があったので、AIに
 「CPUをSTM32G030F6P6に変えてcode出して」
と頼んだらそれっぽいcodeが出てきたので丸パクリして焼いたら一発で動いた.らっき~
↓かわいいケースに入れました.1kHz~3MHzまでパルスを出せます.

かしこ

0 件のコメント:

コメントを投稿