はじめに
本記事はMATLAB Expo2021 LTでの発表「MATLAB Homeでのモータ制御MBD開発に向けた“脱獄指南書”」の解説をシリーズ化したものの最初の記事となります。
シリーズ構成案は下記。(完了時期:未定)
①Arduino Dueに3相同期・三角波・相補PWMを打たせる
②Arduino DueでPWM山同期AD変換を行う
番外編 実質無料! Tiの3相GaNインバータの使い方
③Arduino Dueの2ch DACを利用する
④MATLAB/SimulinkでArduinoのレジスタを叩く
⑤MATLAB/SimulinkとArduino DueでPWM同期の制御を実現する
色々と試してみて分かった事ですが、MATLAB Homeでコード生成を行った場合はJ-ScopeのようなRAMスコープが使えません。このためDACの利用はかなり重要なポイントとなるため、本記事にて解説を行うものとします。(といってもADCと比べると滅茶苦茶簡単ですが。)
MATLAB Homeのコード生成(Embedded Coder未使用)を突き詰めた結果、限界が見えてしまいました。
— モータ制御マン (@motorcontrolman) September 19, 2021
この子、J-Scopeに接続できない=デバッガが使えません。通常の方法で生成されたelfと明らかに挙動が違います、無念。
これはちょっと致命的だなぁ…。 pic.twitter.com/3bhPSBbWWj
1. DACを有効化する
下記のソースコードをardinoの初期化関数に記述することでDACが有効化されます。
関数dacInit
は著者が便宜上定義した関数であって、別に関数化する必要はありません。
ADCの設定と比べ、特に説明するところがないです。寂しいですね
void dacInit(){
PMC->PMC_PCER1 = PMC_PCER1_PID38; // DACC power ON
DACC->DACC_CR = DACC_CR_SWRST ; // Reset DACC
DACC->DACC_MR =
DACC_MR_TRGEN_DIS | // DACC in free running mode
DACC_MR_WORD_HALF | // Half-Word transfer
DACC_MR_TAG_EN;
DACC->DACC_CHER = DACC_CHER_CH1 | DACC_CHER_CH0;
}
2. 信号をDACに出力する
下記となります。
関数dacWrite
は著者が便宜上定義した関数であって、別に関数化する必要はありません。
void dacWrite(uint16_t DAC0, uint16_t DAC1){
DACC->DACC_CDR = (0 << 12) | DAC0;
DACC->DACC_CDR = (1 << 12) | DAC1;
}
いちいち言う事でもないですが、Arduino DueのDACは12bitとなります。
このため上記関数の入力はuint16ですが、上位4bitは無視されますので注意下さい。
3. モータ制御における実際の使用方法
ここまでで終わってしまうと余りにも面白くないので実際の使用方法を記載します。
関数dacWrite
を、AD変換の割り込み関数内でコールして使います。
モータ制御ではAD変換をPWM山(谷)同期に設定していると思いますので、DACも同様の周期で更新されることなります。
要するに、こうじゃ!
void ADC_Handler() {
Iu_ad = ADC->ADC_CDR[7]; // Read and clear status register
//こいつを消すと動かなくなる。CH7の完了と同期しているから?
Iv_ad = ADC->ADC_CDR[6];
Iw_ad = ADC->ADC_CDR[5];
dacWrite(Iv_ad, Iw_ad)
PIOB->PIO_ODSR ^= PIO_ODSR_P27; //Lチカ用
}
参考
上記コードについて、gitの下記にも置いています。
DAC.cpp と DAC.hを参照下さい。
おわりに
書くことがなさすぎて逆に困惑している。