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
#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文件里进行了比对,完全没有问题。

你可能感兴趣的:(串口通讯,收发数据,C语言,VS2013)