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の割り込みを停止させた方が
良いでしょう。
これですんなり終わるかと思いましたが、なんのなんの…
つづく。