YMF825board with Arduino Uno R3で沼 その2

通信速度でつまずく?

さてさて、ハードウェアの準備は整ったのでいよいよソフトの番です

ArduinoIDEをインストール、実はまともにArduino使うのは今回が初めてです

シーケンサソフトからやって来るデータを受信するのに、まずはArduinoらしく

  Serial.begin(115200);
}
void loop() {
  if (Serial.available() > 0) {
    data = Serial.read();

とやったのですがデータが多いとあっさり破綻しました
115,200bit/sなら3バイトのMIDIコマンドが3、840個/s受信できます

USB-MIDItoシリアルブリッジからの設定は256,000bit/sが最高レートなので

(実際はUBRR0=7で250,000bit/s)これで試しても変わらず。

Arduinoはシリアル115,200が限界って話もちらほら見ますが

クロック16MhzのAVRはアセンブラで割り込み受信書いたら

usartは平気で2Mbit/sぐらいOKなんで、なんかおかしいな~と思いCで書いても駄目??

試しにAtmega16u2をMIDIシリアルブリッジにして最高速度の2Mbit/sで送信するも

データは受信しますが演奏が安定しません?

これはAtmega328Pの方でなんか隠れて処理が行われていると思い調べてみたら

やっぱりありました。

隠れmain()の中のinit()

Aruduinoでは表に出て来ていないmain()関数からsetup()とloop()が

呼ばれているのですが、実はmain()はinit()と言う関数も呼び出しています。

int main(void)
{
  init(); <--こいつ
  initVariant();
#if defined(USBCON)
  USBDevice.attach();
#endif
  setup();
  for (;;) {
      loop();
      if (serialEventRun) serialEventRun();
  }
  return 0;
}

実はこのinit()内でTimer0のoverflow割り込みをセットして頼みもしないのに

時間管理関数の為に割り込みを乱発してます。
この記事が詳しい、おまけに標準のSerial使うと何か呼んでる!

どんどんArduinoのスケッチらしく無くなる

ユーザでもmain()関数を記述できるようなので余計な事はせずに
かつusartのコードも自前でアセンブラで書きます。
int main() {
  int i;
  CLKPR = 0x80;
  CLKPR = 0x00;
  /* usart setup */
  UBRR0 = 0;
  UCSR0A |= (1 << U2X0);
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00) ;
  UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
  UBRR0 = 0x0007;

 

これでタイマ割り込みの問題は解決、Arduinoで処理速度が必要なら

時間関係の処理を自分でしないといけませんがTIMER0の割り込みを停止させた方が

良いでしょう。

これですんなり終わるかと思いましたが、なんのなんの…

 

 

つづく。