您的位置:首页 > 编程语言 > C语言/C++

c语言串口收发数据VS2013

2017-11-27 10:48 267 查看
最近师兄师姐在做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文件里进行了比对,完全没有问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息