最近师兄师姐在做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
#include
#include
#include
#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文件里进行了比对,完全没有问题。