STM32G4のDACをTIMで駆動してDMAで転送して2chの波形を出す
NUCLEO-G474REボードを使っています。
CubeMXの設定
DAC4の設定
今回はDAC4を使うことにしました(ピンアサインの競合の関係で)。
今回はテストデータとして正弦波を使うので、Signed FormatをEnableに設定しています。またTriggerにTimer 7 Trigger Out eventを設定しています。
DAC4のDMAの設定
Data WidthのPeripheral側は必ずWordに設定してください。Memory側はフォーマットに応じて設定することになりますが、今回は8bitデータが2ch分でHal Wordを設定しました。12bit幅をフルに使う場合はMemory側もWordになります。
あとはModeをCircularに設定し、必要に応じてPriorityも設定しておきます。
OPAMP4/5の設定
OPAMP4のModeをFollower-DAC4_OUT1-INPに設定します。それ以外はデフォルトです。
OPAMP5も同様に、Follower-DAC4_OUT2-INPに設定します。
TIM7の設定
TIM7を適当に設定しておきます。
今回はコアクロックが170MHzなので、周期を170-1として、1MHzのトリガを発生させます。
Trigger Event SelectionにUpdate Eventを設定しておきます。
DACの起動
適当な正弦波を作成し、DACを開始します。OPAMPも有効にして、最後にタイマをスタートします。
今回は1MHzトリガなのでポイント数を1000とし、1kHzの正弦波が出るようにしました。また、デュアルチャンネルなので、cosとsinで90度位相をずらした信号を設定しました。
sin/cosは-1から+1の範囲ですが、DACには8bitのデータを渡すので、127倍しています。DACは符号有りモードに設定しているので、オフセットは不要です。
constexpr uint16_t N = 1000;
static struct
{
int8_t ch1;
int8_t ch2;
} data[N] = {};
for (uint32_t i = 0; i < N; i++)
{
constexpr float pi = 3.1415926535897932384626433832795f;
data[i].ch1 = static_cast<int8_t>(cosf(i * pi * 2 / N) * 127);
data[i].ch2 = static_cast<int8_t>(sinf(i * pi * 2 / N) * 127);
}
HAL_DACEx_DualStart_DMA(&hdac4, DAC_CHANNEL_1, reinterpret_cast<uint32_t *>(data), N, DAC_ALIGN_8B_R);
HAL_OPAMP_Start(&hopamp4);
HAL_OPAMP_Start(&hopamp5);
HAL_TIM_Base_Start(&htim7);
綺麗な波形が出ていますね。
雑記
今回、なぜかDMAが動かなくて、数時間溶かしました。結局、DMAのPeripheral側の幅をWordにしないとダメだった、という。リファレンスマニュアルを読めば「32bitでアクセスしろ」と書いてあるので、ちゃんと仕様書を読め、という話なんですが。。。
以前はDMAの幅は気にせずに動いていたような気がします。前にQiitaに投稿したF3でDACをDMAで転送するサンプルもHalfWordで転送しているようですし。もしかしたらG4はそのあたりが厳しくなったのかもしれません。F3でもF4でも同様に「32bitでアクセスしろ」と書いてあるので、仕様外なのにたまたま動いていただけかもしれませんが。
今回の教訓
「公式のドキュメントは隅から隅まで読み尽くせ」
Author And Source
この問題について(STM32G4のDACをTIMで駆動してDMAで転送して2chの波形を出す), 我々は、より多くの情報をここで見つけました https://qiita.com/amutou/items/d0c6ee8e0d6195df4332著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .