c語言串列埠收發資料VS2013
阿新 • • 發佈:2019-02-20
最近師兄師姐在做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個位元組來接收就沒有問題了。非常感謝趙老師。
#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檔案裡進行了比對,完全沒有問題。