1. 程式人生 > >c語言串列埠收發資料VS2013

c語言串列埠收發資料VS2013

最近師兄師姐在做GPS定姿的專案,需要把天線解算的結果從電腦串列埠傳送出去,對於VS和C語言小白的我承擔了把資料從串列埠傳送出去的任務。網上串列埠通訊的例子倒是不少,在傳送資料方面,下的功夫倒也不是很多,主要是老師還讓我把資料接收下來校驗傳送的對不對,於是開始了除錯程式碼的不歸路,現在把我的過程記錄下來,程式碼供大家參考。首先是把資料傳送出去,傳送資料協議是自己定義的,一個數據頭2個位元組,20個位元組資料位,2個位元組CRC校驗位,每個資料共24位元組的資料。

void main(){

/*****************************開啟串列埠*************************************/    HANDLE hCom;//全域性變數,串列埠控制代碼
   hCom = CreateFile(_T("COM2"),//COM1口
    GENERIC_READ | GENERIC_WRITE,//允許讀和寫
    0,//獨佔方式
    NULL,
    OPEN_EXISTING,//開啟而不是建立
    0,//同步方式
    //FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERAPPLE,//重疊方式
    NULL);
   if (hCom == (HANDLE)-1)
   {
    printf("開啟COM失敗!");
    return ;
   }    /*********************************配置串列埠*********************************/    SetupComm(hCom, 20480, 20480);//輸入緩衝區和輸出緩衝區的大小都是20480
   COMMTIMEOUTS TimeOuts;
   //設定讀超時
   TimeOuts.ReadIntervalTimeout = 1000;
   TimeOuts.ReadTotalTimeoutMultiplier = 500;
   TimeOuts.ReadTotalTimeoutConstant = 5000;
   //設定寫超時
   TimeOuts.WriteTotalTimeoutMultiplier = 500;
   TimeOuts.WriteTotalTimeoutConstant = 2000;
   SetCommTimeouts(hCom, &TimeOuts);//設定超時
   DCB dcb;
   GetCommState(hCom, &dcb);
   dcb.BaudRate = 115200;//波特率為115200
   dcb.ByteSize = 8;//每個位元組有8位
   dcb.Parity = NOPARITY;//無奇偶校驗位
   dcb.StopBits = TWOSTOPBITS;//兩個停止位
   dcb.fParity = FALSE;
   dcb.fNull = FALSE;    SetCommState(hCom, &dcb);
   PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);//在讀寫串列埠之前清空緩衝區    /******************************同步寫串列埠*************************************/
   unsigned long temp = 0;
   short int crc;
   unsigned char i;
   short int MessageLen = 20;//資料頭:資料長度,不包括資料頭和校驗位
   short int Hour = (Result.ultime / 3600 + 8) % 24;//要傳送的資料,時分秒
   short int Minute = (Result.ultime % 3600) / 60;
   short int Sceond = Result.ultime % 60;
   short int SVNnum = Result.SVN;//衛星個數
   float Len = Result.len;//基線長度
   float Yaw = Result.dYaw;//航向角
   float Pitch = Result.dPitch;//俯仰角
   unsigned char result[100] = { 0 };//寫入串列埠快取區的陣列
   int len = sizeof(short int);
   int len1 = sizeof(float);
   //int len2 = sizeof(int);
   memcpy(result, &MessageLen, len);
   memcpy(result + len, &Hour, len);
   memcpy(result + 2 * len, &Minute, len);
   memcpy(result + 3 * len, &Sceond, len);
   memcpy(result + 4 * len, &SVNnum, len);
   memcpy(result + 5 * len, &Len, len1);
   memcpy(result + 5 * len + len1, &Yaw, len1);
   memcpy(result + 5 * len + 2 * len1, &Pitch, len1);
   //計算出CRC校驗碼
    char result_len = 22;
    unsigned char *ptr = result;
   while (result_len--){
    for (i = 0x80; i != 0; i = i >> 1){
     temp = temp * 2;
     if ((temp & 0x10000) != 0)
      temp = temp ^ 0x11021;
     if ((*ptr & i) != 0)
      temp = temp ^ (0x10000 ^ 0x11021);
    }
    ptr++;
   }
   crc = temp;
   memcpy(result + 5 * len + 3 * len1, &crc, len1);
  
   DWORD dwwrittenLen = 0;
    if (!WriteFile(hCom, result, 24, &dwwrittenLen, NULL))
    {
     printf("傳送資料失敗!\n");
    }
    printf("Main Baseline往串列埠傳送資料成功!");
   
        /***********關閉串列埠***********/
   CloseHandle(hCom);}

資料傳送成功,主要是接收的程式除錯了很久,一開始也是打算一個數據24個位元組24個位元組來迴圈接收,但是每組資料會在固定的第10-13個位元組出錯,一直搞不明白,後來在CSDN發帖,趙老師的幫助下,把接收資料改成8個位元組8個位元組來接收就沒有問題了。非常感謝趙老師。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <conio.h>
#include "tchar.h" int main()
{
 HANDLE hCom1;
 hCom1 = CreateFile(_T("COM1"),//COM1口
  GENERIC_READ | GENERIC_WRITE,//允許讀和寫
  0,//獨佔方式
  NULL,
  OPEN_EXISTING,//開啟而不是建立
  0,//同步方式
  NULL);
 if (hCom1 == (HANDLE)-1)
 {
  printf("開啟COM失敗!\n");
  return FALSE;
 }
 else
 {
  printf("COM開啟成功!\n");
 }
 SetupComm(hCom1, 20480, 20480);//輸入緩衝區和輸出緩衝區的大小都是1024
 COMMTIMEOUTS TimeOuts;
 //設定讀超時
 TimeOuts.ReadIntervalTimeout = 1000;
 TimeOuts.ReadTotalTimeoutMultiplier = 500;
 TimeOuts.ReadTotalTimeoutConstant = 5000;
 //設定寫超時
 TimeOuts.WriteTotalTimeoutMultiplier = 500;
 TimeOuts.WriteTotalTimeoutConstant = 2000;
 SetCommTimeouts(hCom1, &TimeOuts);//設定超時
 DCB dcb1;
 GetCommState(hCom1, &dcb1);
 dcb1.BaudRate = 115200;//波特率為9600
 dcb1.ByteSize = 8;//每個位元組有8位
 dcb1.Parity = NOPARITY;//無奇偶校驗位
 dcb1.StopBits = TWOSTOPBITS;//兩個停止位
 //dcb1.fParity = FALSE;
 //dcb1.fNull = FALSE;
 SetCommState(hCom1, &dcb1);
 DWORD wCount=8;//讀取的位元組數
 PurgeComm(hCom1, PURGE_TXCLEAR | PURGE_RXCLEAR);//清空緩衝區
 while (1)
 {
  
  unsigned char str[8];
  if (!ReadFile(hCom1, str, wCount, &wCount, NULL))
  {
   printf("讀串列埠失敗!");
   return FALSE;
  }
  FILE *fp1;
  fp1 = fopen("串列埠傳送的數.txt", "a+");
  
  int i = 0;
  
  for (i = 0; i < wCount; i++)
  {    printf("讀串列埠成功!讀取資料為: %02X \n", str[i]);
   fprintf(fp1, "%02X ", str[i]);
   
  }
  
  fclose(fp1);
 }
 CloseHandle(hCom1);
} 最後 就是將傳送的資料和接收的資料放到TXT檔案裡進行了比對,完全沒有問題。