mbedのSerial通信要項
必要なこと
- インクルード
#include "Serial.h"
- インスタンス生成
Serial pc(USBTX, USBRX); // USBシリアルポートのインスタンス
Serial Cc(p28,p27); // RX,TXでのシリアルポート生成
- ボーレート調整
pc.baud(115200);
Cc.baud(115200);
#include "Serial.h"
Serial pc(USBTX, USBRX); // USBシリアルポートのインスタンス
Serial Cc(p28,p27); // RX,TXでのシリアルポート生成
pc.baud(115200);
Cc.baud(115200);
int data = 1;
pc.printf("hello %5d \r\n",data);
概要
mbedでの一番の利点は、受信割り込みがある事でしょう。Arduinoには有りません。さらにUSBも入れると4つもポートがあるので、センサー系統は全てSerialでまとめておくと通信失敗やよくわからないデーターの送信受信不一致を避けることができてとても楽です。mbedはSPI割り込みを持たないので、やはりSerialでしょう。
通信速度については、115200bpsも有れば、1秒に14400byte もデータが送れるので速度で困ることはほぼないでしょう。
ただし、送信処理printfに食われるmbedの処理時間はとてもながいです。これは、printfでは1byteで10進数の1桁のみを送ることになるためとても効率が悪いことも原因です。よって、送信する場合はprintfでなくputc(char)によってASCIIコードに変換せず送るのが良いと思われます。
受信
Serial pc(USBTX, USBRX); // USBシリアルポートのインスタンス生成
Serial Cc(p28,p27);
void getC(){
//受信割り込み処理
}
int main() {
pc.baud(115200);
Cc.baud(115200);
Cc.attach(getC,Serial::RxIrq); //受信割り込み関数getC(名前は何でも良い)を設定
while (1) {
}
}
Serial pc(USBTX, USBRX); // USBシリアルポートのインスタンス生成
Serial Cc(p28,p27);
void getC(){
//受信割り込み処理
}
int main() {
pc.baud(115200);
Cc.baud(115200);
Cc.attach(getC,Serial::RxIrq); //受信割り込み関数getC(名前は何でも良い)を設定
while (1) {
}
}
このようにattach(関数名,Serial::RxIrq);で割り込み関数を設定して、処理します。
void getC(){
char receive = Cc.getc();
int data = (int)receive;
pc.printf("%5d \r\n",data);
}
getc()で1byte受け取り、int型に変換しPC側に表示させるプログラムです。
mbedに接続している、送信側は1byteデータを送信させます。
これだと、上位byte、下位byteの区別が付かないので1byteしか受け取れません。
void getR()
{
//pc.printf("%c ",Ro.getc());
char Rse = Ro.getc();
if((Rse&0b10000000)==0b10000000) { //highByte
high = Rse ;
if((high&0b01000000)==0b01000000) { //値は負なのでそのまま
Polarity = true;
} else { //値は正なので最上位を0にする
high= high & 0b01111111;
Polarity = false;
}
//pc.printf("%3x high",Rse);
} else { //lowByte
low = Rse;
//pc.printf("%3x low",Rse);
Rotate = (high <<7) | low ;
if(Polarity ==true ) { //負の時 int 2byte でないので
Rotate = Rotate|0x8000;
}
//pc.printf("%6d \r\n",Rotate);
}
}
14bit(+-8000程度)データの送受信、8bit目の数値を0,1で上位か下位かを区別してデータを変換し受け取っています。
送信
int data = -3;
char send = (char)data;
Cc.putc(send);
int data = -3;
char send = (char)data;
Cc.putc(send);
これで、1byteまでなら送信できます。2byte以上のデータの場合、先頭を示すか、外部割り込みで指示するか一部bitを順番を指示するのに使用するか等の工夫が必要になります。
dataは-127 から+127までです。
int char
-256 -> 0
-255 -> 1
-127 -> 129
-126 -> 130
-125 -> 131
-1 -> 255
0 -> 0
1 -> 1
125 -> 125
126 -> 126
127 -> 127
128 -> 128
255 -> 255
256 -> 0
扱いとなります。
よって、データを128 ~ -127 にしておいて、char型に変換し、送信すれば
受信側は
0~128まではそのまま
-1~-127までは 256 + int
をすれば変換できます。
Serial受信割り込みとputcの併用の注意
2019/12/11:追記
受信割り込みを入れた場合、Cc.putc(5);の送信は割り込み関数内に入れないと、送信中に受信割り込みが入った場合エラーになります。USART,UARTの違いが影響しているかも知れません。CPUの説明ではUART4,5と有るのでUARTはSerial4,5のみです。
エラーはコンパイラではなく、mbedが動作を停止しているように見えます。
サンプルプログラム
#include "mbed.h"
Serial pc(USBTX, USBRX); // USBシリアルポートのインスタンス
Serial moterDriver(PC_10,PC_11); //モータードライバ
void geCC(){
int k2=moterDriver.getc();
}
int main() {
pc.baud(115200);
moterDriver.baud(115200);
moterDriver.attach(geCC,Serial::RxIrq);
while(1) {
moterDriver.putc(3);
pc.printf("moving\r\n");
}
}
このプログラムを動かしている時に、PC_10,PC_11にSerialデータを送信すると、movingが停止します。 tx,rx,電圧レベルの問題ではない事は、私の確認ですがいろいろ試して確認しました。Nucleo F446REで確認しました。 LPC1768でも、似たプログラムを使っている際に頻繁に落ちて困ってしまったので仕様だと思われます。
putcをする際は安全のため、そのSerial受信割り込みにputcを置いた方が良いかもしれません。
Author And Source
この問題について(mbedのSerial通信要項), 我々は、より多くの情報をここで見つけました https://qiita.com/hiRina/items/c642908a7cc0de95658d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .