« Arduino UNO R4 minima 電源供給方法でクロックが変わる#4 | トップページ | DDS IC「AD9833」をArduino UNO R3で制御 »

2025年5月23日 (金)

DDS IC「AD9833」の周波数レジスタ書き込みで

Arduino UNO R4 minimaの1MHz波ビート音実験で
急ぎでっちあげたアナデバのDDS IC「AD9833」。

Arduino UNOで制御する時にちょいと気になる
ことがありました。
  ・・・たいしたことじゃないけど
AD9833の周波数レジスタは28bitで、LSBとMSBに
分けて2回、14bitで書き込みを行います。

こんな感じ。

AD9833ctrl(0x2000);     // B28 on コントロール
spi16(0x4000 | (d & 0x3FFF));     // ch0 LSB 14bit
spi16(0x4000 | ((d >> 14) & 0x3FFF)); //   MSB 14bit

「d」が32bit(つまり4バイト)の書き込みデータで、
最初に「これから2回のデータを書くで」っという
制御コード(B28 on)を送ってから、LSB、MSBの順に
14bitのデータをSPIで書き込みます。

このタイミングをオシロで見たら、SPIの間隔がずいぶん
空いていたのです。
  16bitのSPI転送は5μsほどなのに、
  LSBとMSBのあいだが9μsほどに
  広がっていました。

32bit値を右に14bitシフトする「(d >> 14)」に、
いがいと時間がかかります。

このようにコードが展開されてました。

bae:  ldi  r17, 0x0E ;14
bb0:  lsr  r7
bb2:  ror  r6
bb4:  ror  r5
bb6:  ror  r4
bb8:  dec  r17
bba:  brne .-12   ;0xbb0
bbc:  ldi  r24, 0x3F ;上位3Fでマスク
bbe:  and  r5, r24
bc0:  movw r24, r4  ;R5,R4をR25,R24に
            ;コピーしてspi16()へ

ここで時間がかかっているのが
32bitデータを保持しているR7,R6,R5,R4レジスタの
14回のシフト。
シフト命令もDEC命令も1クロック。
loop中のBRNEが2クロック。
7クロックが14回で98クロックを要します。

そこで、ちょっとでもスピードアップということで、
14bitのシフト方法を変えてみました。

uint16_t a;          // 2バイトの一時レジスタ
  AD98ctrl(0x2000);       // B28 on コントロール
  spi16(0x4000 | (d & 0x3FFF)); // ch0 LSB 14bit
  d = d << 2;          // d >> 14のかわり
  a = d >> 16;         // シフト2回とレジスタ交換に
  spi16(0x4000 | (a & 0x3FFF)); // MSB 14bit


これだと、このように展開されて、シフト回数が2に
なり、ちょいとだけ高速化できます。

bae:  ldi  r17, 0x02  ; 2
bb0:  add  r4, r4
bb2:  adc  r5, r5
bb4:  adc  r6, r6
bb6:  adc  r7, r7
bb8:  dec  r17
bba:  brne .-12     ; 0xbb0
bbc:  movw r24, r6
bbe:  andi r25, 0x3F

さらに「d = d << 2;」という2bitのシフトを、
「d <<= 1; d <<= 1;」と2つに分割してたら
 ldi r17,1
 dec r17
 brne  .-12 が無くなるかと
期待したのですが、同じコードに展開されました。
  brneを使う方が1命令少なくなります。

オシロで見るとこんな波形。
A01_20250523114301
上段の(d >>14 )のところ、なぜか広いので
「これはなんだろか?」っと思いませんか?

気になってコードを見たら、14回のループに
時間がかかっていたというお話しでした。



※関連
2025年5月21日:Arduino UNO R4 minima 電源供給方法でクロックが変わる#4

|

« Arduino UNO R4 minima 電源供給方法でクロックが変わる#4 | トップページ | DDS IC「AD9833」をArduino UNO R3で制御 »

Arduino」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




« Arduino UNO R4 minima 電源供給方法でクロックが変わる#4 | トップページ | DDS IC「AD9833」をArduino UNO R3で制御 »