【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.22795

スレッドを用いたシリアル通信
投稿者---oumi(2005/08/24 16:44:31)


タイトル通り、スレッドを使ったシリアル通信プログラムを作っているのですが、行き詰っています。
Visual Studio.netで開発していて、Win32 コンソールプロジェクトで作っています。Windows上に、新しくウインドウを作ったりするのではありません。

以下が、途中まで作っているプログラムです。
スレッドでは、常に読み込みをしてリングバッファに書き込みをしていくプログラムにしようと思っています。

わからない点は、
スレッド(ReadThread)の中でReadFileでシリアルポートからデータを読み込んだときに、リングバッファへの書き込みをするためのプログラムの書き方がわかりません。

○ポートからデータを読む
○リングバッファ更新するため排他をかける
○リングバッファにデータを書き込む
○排他を解除に、またポートからデータを読む

というスレッドにしたいのです。

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>

#define BUFFSIZE 256  //バッファサイズ
#define TRUE 1
#define FALSE 0


HANDLE  hCom;  //シリアルポートのハンドラ
HANDLE  hthread;  //スレッドのハンドル

int run;   //スレッドの実行フラグ(実行中か否か)
int stopped;  //スレッド停止フラグ(停止したかどうか)


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void init()
{
    hCom = INVALID_HANDLE_VALUE;
    hthread = NULL;
    run = FALSE;
    stopped = TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//受信スレッド
static void ReadThread(void* lpvoid)
{
    static unsigned long        Readsize;            //読み取ったバイト数
    static struct _OVERLAPPED   Overlapped;                //オーバーラップ構造体のバッファ
    static unsigned char        ReadBuf[BUFFSIZE];    // 受信データ
    long                        dataBuf[BUFFSIZE];    //リングバッファ
    
    if(!ReadFile(hCom, ReadBuf, 8, &Readsize, &Overlapped) || Readsize == 0)
    {
    }

    Sleep(10);

}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ポートオープン
//    CString PortName[] = {"COM1","COM2","COM3","COM4"}
int Com_Open(void)
{
    hCom = CreateFile("COM1", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    if(hCom  == INVALID_HANDLE_VALUE){
        printf("★ポートをオープンできませんでした。\n");
        return FALSE;
    }else printf("☆ポートをオープンしました。\n");
    
    //通信設定 19200, 8BIT, 偶数パリティ, STOP1に固定

    DCB  dcb; // DCB構造体

    if(!GetCommState(hCom, &dcb)){
        printf("★通信設定失敗しました。\n");
        return(FALSE);
    }else printf("☆通信デバイスの設定を制御ブロックに格納しました。\n");
    
    dcb.BaudRate = 19200;
    dcb.ByteSize = 8;
    dcb.Parity = EVENPARITY;
    dcb.StopBits = ONESTOPBIT;
    if(!SetCommState(hCom, &dcb)){//通信デバイス構成の初期化
        printf("★通信デバイス構成の初期化に失敗しました。\n");
        return(FALSE);
    }else printf("☆伝送方法を設定しました。\n");
    
    // タイマー設定 : 受信待ち無制限、送信待ち100ms + 1文字10ms

    COMMTIMEOUTS  Timeout;  // タイムアウト構造体

    Timeout.ReadIntervalTimeout = 0;
    Timeout.ReadTotalTimeoutMultiplier = 0;
    Timeout.ReadTotalTimeoutConstant = 0;//タイムアウト時間
    Timeout.WriteTotalTimeoutMultiplier = 10;
    Timeout.WriteTotalTimeoutConstant = 100;
    
    if(!GetCommTimeouts(hCom, &Timeout)){
        printf("★タイムアウト失敗\n");
        return(FALSE);
    }else printf("☆タイムアウト成功 \n");
    
    return(TRUE);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int open()
{
    //すでにコネクションが張られているなら何もしない
    if(hCom != INVALID_HANDLE_VALUE)
        return(FALSE);

    //シリアルポートのオープン
    if(Com_Open() == FALSE)
        return(FALSE);

    //スレッドを走らせる
    run = TRUE;
    stopped = FALSE;
    
    if((unsigned long)(hthread = (HANDLE)_beginthread(ReadThread, 0, hCom)) == -1){
        CloseHandle(hCom);
        hCom = INVALID_HANDLE_VALUE;
        run = FALSE;
        stopped = TRUE;
        
        return(FALSE);
    }

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int serial_close(void)
{
    if(run == TRUE){
        run = FALSE;
        while(stopped == FALSE)
            Sleep(10);
        
        CloseHandle(hCom);
        
        hCom = INVALID_HANDLE_VALUE;
        hthread = NULL;
    }
    
    return (TRUE);
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    init();
    open();
    serial_close();

}




この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧