エキスパートには当たり前だったかもしれないのだが、私は知らなかった。
mbed-os5のAPIにあるUSBSerialでは、printfの送信で1バイトごとパケットに乗せられる。1ms間隔でデータを送信したかったが、間隔が1msではなかったという結果があり、気づいた。下記コードで確認してみた。
#include "mbed.h"
#include "USBSerial.h"
USBSerial usbserial;
Ticker tbase;
SPI spi(D11,D12,D13);
volatile int tb_reach=0;
void tbase_t(void){
tb_reach=0;
}
int main(){
spi.format(8,3);
spi.frequency(2000000);
tbase.attach( &tbase_t , 0.001 );
int nn=0;
while (true) {
spi.write(0x55);
usbserial.printf("%020d\r\n",nn++);
while( tb_reach );
tb_reach=1;
}
}
SPI送信しているのは、オシロで確認するのに端子動作は遅いかもという理由で利用したかったからで、意味はないです。1msインターバルにすると、だいたい20文字分ぐらいで1msより長くかかってSPIのクロック送信間隔になった。USBDeviceのUSBSerialはbaud設定もないし、ずっとわからなかった。以前教えてもらったmbed_lib.json
https://github.com/ARMmbed/mbed-os/blob/master/platform/mbed_lib.json
の中に、デフォルトbaud設定があるような感じだったので、見よう見まねで設定してみたけど、何も変わらない。しようがないので、会社のオシロを使ってUSBのパケットを覗いてみたら1byte=1パケットの送信の仕方になっていて1ms以内に終わらなかったということがわかった。最初に思ったように、USBDeviceのUSBSerialはボーレート設定はなくUSBで送信される。(パソコン側のボーレート設定を何に設定しても通信できる)
mbed-osのAPIを見ていると、USBSerialの下位層にあるUSBCDCクラスのexampleに、sendがあった。絵からすると(streamのprintfが使えるように)関数が継承されているようにも思える。
https://os.mbed.com/docs/mbed-os/v5.15/apis/usbserial.html
そこで、送信部分を下記のように書き換えたら、データが1パケットで送信できるようになった。
int tmp;
char buff[32];
tmp = sprintf(buff , "%020d\r\n",nn++ );
usbserial.send((uint8_t *)buff,strlen(buff));
また、数日かかった。いろいろ勉強になってよろしいのですが、頭がついていかないですね。
それにしても、USBのパケット見えるオシロ欲しいですね。それか、定年になっても、会社にしがみついているか(それはやだなー)?
コメントを追加