プロが教えるわが家の防犯対策術!

int型(2バイト)データの分割

マイコンのフラッシュ領域にint型のデータ(2バイト)を
1バイトづつ書き込むのに以下のコードを考えています。

unsigned int data;
unsigned char dat1,dat2;

data = 555;
dat1 = 0;
dat2 = 0;

dat1 = (char)data;
dat2 = (char)data >> 8;

以下、dat1とdat2をフラッシュに書き込む。

未熟者でプログラムとして合っているのか解りません。
やり方として問題ないでしょうか?
またもっと良い方法があればご教授願います。

このQ&Aに関連する最新のQ&A

A 回答 (7件)

まず考えるべきは、フラッシュメモリの書き込んだデータは誰が使うのか? です。



自分(というか、そのシステム)だけでしか使わないのであれば、余り気にすることはありません。

この場合だと、

data = 555; に対して、

dat1 = data % 0x100;
dat2 = data / 0x100;

が一番安全でしょう。
右辺はいずれも int のサイズで計算されて、代入の際に、(数値として)下の桁から、char 分が代入されます。
※代入の直前までは、int で計算されることに注意。

読み出しの場合は、

data = dat2 * 0x100 + dat1;

で安全に元に戻せます。
(これも、0x100 が int 幅なので、 dat2 * 0x100 は int に拡張され、それに対して、int に拡張された dat1 が加算されます)

すべて符号無しなので、char -> int への拡張も問題なく行われます。

あと、かけ算や割り算は効率が悪いのではないか? という心配も無用です。
0x100 のような、(2進数で)きりの良い数のかけ算や割り算は、普通のコンパイラは、内部でシフトに置き換えますので。
    • good
    • 0
この回答へのお礼

皆様、ご回答どうもありがとうございます。
マイコンはルネサスのR8Cでデータフラッシュに書き込みます。
データは自分でしか使用いたしません。

皆様から教えていただいたコード等を参考にやってみます。
まずはお礼のみで失礼いたします。

お礼日時:2010/10/04 01:14

>マイコンのフラッシュ領域にint型のデータ(2バイト)を1バイトづつ書き込む



8bitのIOポートからFIFOバッファを利用して読み書きするタイプなのかな?
IOのアドレスをFportとすると

unsigned int data;
char *c;

c = (char *)&data;
Fport = c[0];
Fport = c[1];

という方法で書き込めます。書いた通りの順番に読み出せば復元できますから、バイト・オーダーとかは気にする必要はありません。
    • good
    • 0
この回答へのお礼

皆様、ご回答どうもありがとうございます。
マイコンはルネサスのR8Cでデータフラッシュに書き込みます。
データは自分でしか使用いたしません。

皆様から教えていただいたコード等を参考にやってみます。
まずはお礼のみで失礼いたします。

お礼日時:2010/10/04 01:14

処理系依存の問題ですね。


エンディアンも含めた対応をここで回答してみます。
マイコンが何かはわかりませんが、ルネサスの純正コンパイラ(H8でもVer6以降)
であれば、#pragma bit_order でビットの並びが右並びか左並びを指定できます。

仕様として、質問者の例として
555 == 0x22B
dat1に2B
dat2に02
を書くことを目的とすることを考えてみます。

意図した質問かどうかにもよりますが、質問者の例(dat2 = (char)(data >> 8);に訂正済み)では
bigエンディアンの場合にdat2がdat1と連続したアドレスで、dat1のアドレスからintで見たとき
に22Bにならず2B02の動作例になります。
逆にメモリが連続していて、intで見たとき22Bを意図するならmemcpyもありなわけです。

どちらを意図するかによっても回答が異なります。
私の場合は、上記(仕様として)に基づいて回答してみます。


#pragma bit_order right
union {
  unsigned int intdat;
     struct {
        unsigned int chdatLow:8;
        unsigned int chdatHigh:8;
     } chdat;
} data;
#pragma bit_order /* 以降のビット並びはオプションに従う */

data.intdat = 555;

dat1 = data.chdat.chdatLow;
dat2 = data.chdat.chdatHigh;

説明
リトルエンディアンの場合には
0000:indat == 0x22B
0000:chdatLow == 0x2B
0001:chdatHigh == 0x02

dat1 == 0x2B
dat2 == 0x02

ビッグエンディアンの場合は
0000:indat == 0x22B
0000:chdatHigh == 0x02
0001:chdatLow == 0x2B

dat1 == 0x2B
dat2 == 0x02
    • good
    • 0
この回答へのお礼

皆様、ご回答どうもありがとうございます。
マイコンはルネサスのR8Cでデータフラッシュに書き込みます。
データは自分でしか使用いたしません。

皆様から教えていただいたコード等を参考にやってみます。
まずはお礼のみで失礼いたします。

お礼日時:2010/10/04 01:15

処理系に依存する方法ですが、共用体が使えるなら


それを使った方がシフト演算などを使わずにスマートにできます。
下位バイトが先に来る(リトルエンディアン)の処理系ならchdat[0]とchdat[1]の順番で
上位バイトが先に来る(ビッグエンディアン)の処理系ならchdat[1]とchdat[0]の順番になります。
インテル系のCPUならリトルエンディアンですが、マイコンなら機種により違うので
確認して見て上位と下位が逆だったならchdat[0]とchdat[1]を入れ替えればいいでしょう。
質問者さんの例に合わせて書くなら、こんな感じになります。

union {
  unsigned int intdat;
  unsigned char chdat[2];
} data;

 data.intdat = 555;

 dat1 = data.chdat[0];
 dat2 = data.chdat[1];

参考URL:http://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3% …
    • good
    • 0
この回答へのお礼

皆様、ご回答どうもありがとうございます。
マイコンはルネサスのR8Cでデータフラッシュに書き込みます。
データは自分でしか使用いたしません。

皆様から教えていただいたコード等を参考にやってみます。
まずはお礼のみで失礼いたします。

お礼日時:2010/10/04 01:15

> dat2 = (char)data >> 8;



ここが間違っていることは明らかですが、それ以外は処理系不明なので何ともいえません。
(int型が2バイトであること以外)処理系に依存しないようにするのであれば、

unsigned int data;
unsigned char dat1,dat2;

data = 555;

dat1 = (unsigned char)data;
dat2 = (unsigned char)(data >> CHAR_BIT);

とするのが妥当でしょうね。
    • good
    • 0
この回答へのお礼

皆様、ご回答どうもありがとうございます。
マイコンはルネサスのR8Cでデータフラッシュに書き込みます。
データは自分でしか使用いたしません。

皆様から教えていただいたコード等を参考にやってみます。
まずはお礼のみで失礼いたします。

お礼日時:2010/10/04 01:16

そのコードだと単に変数領域(RAM)にデータを書いてるだけでは?

    • good
    • 0
この回答へのお礼

皆様、ご回答どうもありがとうございます。
マイコンはルネサスのR8Cでデータフラッシュに書き込みます。
データは自分でしか使用いたしません。

皆様から教えていただいたコード等を参考にやってみます。
まずはお礼のみで失礼いたします。

お礼日時:2010/10/04 01:16

dat2 = (char)(data >> 8);

    • good
    • 0
この回答へのお礼

皆様、ご回答どうもありがとうございます。
マイコンはルネサスのR8Cでデータフラッシュに書き込みます。
データは自分でしか使用いたしません。

皆様から教えていただいたコード等を参考にやってみます。
まずはお礼のみで失礼いたします。

お礼日時:2010/10/04 01:16

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aと関連する良く見られている質問

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Q16進数を10進数に簡単に変換する関数は?

16進数を10進数に簡単に変換する関数は何かありますか?
もしご存知でしたら教えていただけないでしょうか?

例えば、3BDF8という16進数を10進数に変換したいと思っています。

Aベストアンサー

C言語のプログラム内では、保持している数値にn進数という概念はなく
文字列化するときに初めて考えるものです。

int n; // <- このnは何進数でもない

ご質問を以下のように解釈してサンプルを書いてみました。

例えば、3BDF8という16進数(の文字列)を10進数(の文字列)に変換したいと思っています。


$ cat test.c
#include <stdio.h>

int main(int argc, char *argv[])
{
int num;
sscanf(argv[1], "%x", &num);
printf("%d\n", num);
}

$ ./a.out 3BDF8
245240

いかがでしょうか。

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Q複数桁10進数の*桁目だけを抽出したい

タイトルがすべてと言えてしまうのですが、
例えば、int宣言された"4287"(この値は変動します)という数値があったとして、1桁目の"7"だけを別の変数へ引き抜きたいのですが、その場合にはANDによるマスク処理による演算で処理可能なのでしょうか?
また、他に良い方法などありましたら教えていただけますでしょうか?

Aベストアンサー

★10進数ですので AND は使えませんね。
・簡単なサンプルを載せますので読み取って下さい。

サンプル1:
int value = 4287;
int a[ 4 ];

a[0] = (value % 10); value /= 10; // 1桁目を取り出す
a[1] = (value % 10); value /= 10; // 2桁目を取り出す
a[2] = (value % 10); value /= 10; // 3桁目を取り出す
a[3] = (value % 10); value /= 10; // 4桁目を取り出す

サンプル2:
int value = 4287;
int a;

a = (value % 10);
value -= a;

value → 4280
a → 7
になります。

Qlong型のデータをバイト型の配列に代入する方法

long型のデータを配列を使って1byte毎に分けたい処理を作りたいのですが、
やりかたとしてはlong型のアドレスをポインタ変数に渡して、
ポインタ変数をバイト配列に代入する方法になりますでしょうか?

具体的なプログラムはこんな感じと考えてますが
unsigned long LONG:
unsigned char AAA[8], *pon, i:

pon = &LONG

for(i=0 i<8 i++)
{
AAA[i] = *pon + i;
}

C言語に詳しい方教えてください、よろしくお願いします。

Aベストアンサー

バイトオーダーを無視してよいのであれば...

memcpy(AAA, &LONG, sizeof(LONG));

とするのが基本です。
以下のように、共用体を使う方法もありますが、任意のバイト配列に格納するにはさらにコピーが必要になります。

union U
{
 unsigned long LONG;
 unsigned char AAA[sizeof(unsigned LONG)];
} u;
u.LONG = 値;

もし、ビッグエンディアンとして扱いたいのであれば次のようにします。

for (std::size_t i = 0; i < sizeof(LONG); i++)
 AAA[i] = LONG >> (CHAR_BIT * (sizeof(LONG) - 1 - i));

リトルエンディアンとして扱うなら次のようにしてください。

for (std::size_t i = 0; i < sizeof(LONG); i++)
 AAA[i] = LONG >> (CHAR_BIT * i);

ちなみに、unsigned char型は必ず1バイトですが、ビット数は8ビットとは限りませんので、必ずCHAR_BITを使う必要があります。
また、unsigned long型が何バイトなのかも処理系定義です。
32ビット以下の多くの処理系や64ビットWindowsではunsigned long型は32ビットですが、多くの64ビットの処理系ではunsigned long型は64ビットです。
また、char型が16ビットや32ビットや64ビットの処理系も実在しますので、その場合はunsigend long型が2バイトや1バイトになることもあります。
一部のDSPではunsigned long型が48ビットで6バイトというものも存在します。

バイトオーダーを無視してよいのであれば...

memcpy(AAA, &LONG, sizeof(LONG));

とするのが基本です。
以下のように、共用体を使う方法もありますが、任意のバイト配列に格納するにはさらにコピーが必要になります。

union U
{
 unsigned long LONG;
 unsigned char AAA[sizeof(unsigned LONG)];
} u;
u.LONG = 値;

もし、ビッグエンディアンとして扱いたいのであれば次のようにします。

for (std::size_t i = 0; i < sizeof(LONG); i++)
 AAA[i] = LONG >> (CHAR_BIT * (sizeof(LONG) - 1 - i));

リト...続きを読む

Q16進数を2文字ずつ配列に格納したい

16進数を配列に格納するのに2文字ずつ格納したいのですがどうしたらいいですか。
例えば
num=ef23157をa[0]=57,a[1]=31,a[2]=f2,a[3]=0e,
のように1バイトずつ格納したいのですが、方法がわかりません。
お願いします。

Aベストアンサー

答えを教えるのは禁止されてるのでヒントだけ

「&」と「>>」

Qビットの取り出し方法

いつもお世話になっております。
今回はビットの取り出しについてお聞きしたいです。

たとえばDWORD型の変数があったとして、この変数の5ビット目は0か1かと
いうことを知る簡潔な方法はありますか?
セットするときはシフト演算を使えばできますが、
あらかじめセットされたものの指定ビット目を得る方法が知りたいです。

bit = dw % 2 という計算でできると思ったのですが、最上位ビットが
何ビット目か判断する方法がよくわからなかったので
ご教授願います。

Aベストアンサー

>>> たとえばDWORD型の変数があったとして、この変数の5ビット目は0か1かと
いうことを知る簡潔な方法はありますか?

5ビット目のみが1、その他のビットはすべて0の定数を準備し、それとのAND演算により得られた結果が
整数として0のときは、0
そうでないときは、1
と判断します。

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

Qprintf で二進表示を行いたい。

すみません。教えていただきたいことがあります。
printf で普通のintの値をフォーマット指定子を使用して二進表示をしたかったのですが見当たりませんでした。
どうにかintの内容を二進で確認したいのですが、どのようにすれば良いですか?
宜しくお願いします。

Aベストアンサー

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if ( value & bit ){
  putchar('1');
 }
 else{
  putchar('0');
 }
}
printf( " です。\n" );

最後に:
・1バイトが 8 ビットの環境が前提です。→まぁ、普通は 8 ビットですが…。
・上記のサンプルを関数などにすれば使いやすくなります。→print_bin()など
・以上。おわり。

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if...続きを読む

QC# シリアル通信でデータ受信時の欠損について

Visualstudio 2013 を使用して C# で開発を行っています。

SerialPort Classを使用してデータの送受信をするプログラムを作成しているのですが、
非同期でデータを受信する際にどうしてもうまくデータを取得出来ません。

5Byteのデータは正常に取得できるのですが、
その直後にくる40Byteのデータは、真ん中あたりの10数Byteや最後の10数Byteしか取れません。


serialPort.DataReceived に登録したイベント関数の中身です。

--------------------------------------------------------------------------------------
private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
bytesRead = 0;
// Initialize a buffer to hold the received data
byte[] buffer = new byte[this.serialPort.ReadBufferSize];

try
{
bytesRead = this.serialPort.Read(buffer, 0, buffer.Length);
if (true == serialPort.IsOpen)
{
serialPort.DiscardInBuffer();//受信バッファをクリアする
}

}
catch (Exception ex)
{
DataLog.Exception(ex);
}

//派生クラス用の処理
DeviceClassEventArgs _DeviceClassEventArgs = new DeviceClassEventArgs(buffer, bytesRead);
DeviceClassEvent(this, _DeviceClassEventArgs);
}
--------------------------------------------------------------------------------------

ネットの情報を参考に、
ReceivedBytesThreshold の値を期待するデータ量に逐一変えることで
とりあえず正常に取ることが出来たのですが、これでいいのでしょうか?
期待するデータ量がわからなかった場合は使えないのかなとも思います。

データが欠損してしまう理由、
上記の対処法以外の一般的な対処法など有りましたら教えて下さい。

その他参考になるページ等ありましたら教えていただけると大変助かります。

Visualstudio 2013 を使用して C# で開発を行っています。

SerialPort Classを使用してデータの送受信をするプログラムを作成しているのですが、
非同期でデータを受信する際にどうしてもうまくデータを取得出来ません。

5Byteのデータは正常に取得できるのですが、
その直後にくる40Byteのデータは、真ん中あたりの10数Byteや最後の10数Byteしか取れません。


serialPort.DataReceived に登録したイベント関数の中身です。

-------------------------------------------------------------------------------...続きを読む

Aベストアンサー

DataReceivedイベントが発生したときでも、
シリアルポートへの受信はまだ継続している可能性があるので
不用意にバッファクリアしてはいけない。
非同期の受信処理は、何かと難しいのです。

private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
  bytesRead = 0;
  // Initialize a buffer to hold the received data
  byte[] buffer = new byte[this.serialPort.ReadBufferSize];

  try
  {
    //bytesRead = this.serialPort.Read(buffer, 0, buffer.Length);
    //if (true == serialPort.IsOpen)
    //{
    // serialPort.DiscardInBuffer();//受信バッファをクリアする
    //}

    // 受信バッファにデータがなくなるまで繰り返し読込む
    while (true)
    {
      if (0 == serialPort.BytesToRead)
      {
        break;
      }
      buffer[bytesRead] = (byte)serialPort.ReadByte();
      bytesRead++;
      System.Threading.Thread.Sleep(0);

      // シリアルポートの受信バッファには、
      // ・必要なブロックの途中から受信している。
      // ・次のブロックの先頭部分も受信されている。
      // 可能性があるので、ここで必要なブロックだけRead()できたことを確認する。
      if (必要なブロックが正常に読めたか確認する関数())
      {
        break;
      }
    }
  }
  catch (Exception ex)
  {
    DataLog.Exception(ex);
  }

  //派生クラス用の処理
  DeviceClassEventArgs _DeviceClassEventArgs = new DeviceClassEventArgs(buffer, bytesRead);
  DeviceClassEvent(this, _DeviceClassEventArgs);
}

DataReceivedイベントが発生したときでも、
シリアルポートへの受信はまだ継続している可能性があるので
不用意にバッファクリアしてはいけない。
非同期の受信処理は、何かと難しいのです。

private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
  bytesRead = 0;
  // Initialize a buffer to hold the received data
  byte[] buffer = new byte[this.serialPort.ReadBufferSize];

  try
  {
    //bytesRead = this.serialPort.Read(buffer, 0, buffer.Le...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング