欢迎使用CSDN-markdown编辑器

来源:互联网 发布:澳洲绵羊油 知乎 编辑:程序博客网 时间:2024/06/16 16:07

串口通信1(单向传输)


发送端

代码块

代码块语法遵循标准markdown代码,例如:

#ifndef SERIAL_H_#define SERIAL_H_class CSerial{public:    CSerial(void);    ~CSerial(void);    //打开串口    BOOL OpenSerialPort(TCHAR* port, UINT baud_rate, BYTE date_bits, BYTE stop_bit, BYTE parity = NOPARITY);    //发送数据    BOOL SendData(unsigned char* data);    unsigned char* modbusFormat_pre(SLocaVecTime hitPoint);//击球点,水平角,垂直角度    unsigned char* modbusFormat_realtime(SLocaVecTime hitPoint);public:    HANDLE m_hComm;private:    UINT crc;    unsigned char modbusDataBuf_pre[26];    unsigned char modbusDataBuf_realtime[14];    int m_dataLength;private:    void calccrc(BYTE crcbuf);    unsigned char highByte(int data);    unsigned char lowByte(int data);};#endifCSerial.h
#pragma warning(disable:4996)typedef unsigned(__stdcall *PTHREAD_START) (void *);typedef  int8_t;CSerial::CSerial(void){    m_hComm = INVALID_HANDLE_VALUE;}CSerial::~CSerial(void){    if (m_hComm != INVALID_HANDLE_VALUE){        CloseHandle(m_hComm);    }}/********************************************************************************************** 功能    :    读串口线程回调函数* 描述    : 收到数据后,简单的显示出来********************************************************************************************/DWORD WINAPI CommProc(LPVOID lpParam){    CSerial* pSerial = (CSerial*)lpParam;  //    //清空串口    PurgeComm(pSerial->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);    unsigned char buf[26];    DWORD dwRead;    while (pSerial->m_hComm != INVALID_HANDLE_VALUE){        BOOL bReadOK = ReadFile(pSerial->m_hComm, buf, 26, &dwRead, NULL);        if (bReadOK && (dwRead > 0)){            buf[dwRead] = '\0';            /*MessageBoxA(NULL, buf, "串口收到数据", MB_OK);*/        }    }    return 0;}/******************************************************************************************** 功能     :  打开串口* port     :    串口号, 如_T("COM1:")* baud_rate: 波特率* date_bits: 数据位(有效范围4~8)* stop_bit :    停止位* parity   :  奇偶校验。默认为无校验。NOPARITY 0; ODDPARITY 1;EVENPARITY 2;MARKPARITY 3;SPACEPARITY 4********************************************************************************************/BOOL CSerial::OpenSerialPort(TCHAR* port, UINT baud_rate, BYTE date_bits, BYTE stop_bit, BYTE parity){    //打开串口    m_hComm = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);//独占方式打开串口    TCHAR err[512];    if (m_hComm == INVALID_HANDLE_VALUE){        _stprintf(err, _T("打开串口%s 失败,请查看该串口是否已被占用"), port);        MessageBox(NULL, err, _T("提示"), MB_OK);        return FALSE;    }    //MessageBox(NULL,_T("打开成功"),_T("提示"),MB_OK);    //获取串口默认配置    DCB dcb;    if (!GetCommState(m_hComm, &dcb)){        MessageBox(NULL, _T("获取串口当前属性参数失败"), _T("提示"), MB_OK);    }    //配置串口参数    dcb.BaudRate = baud_rate; //波特率    dcb.fBinary = TRUE;           //二进制模式。必须为TRUE    dcb.ByteSize = date_bits; //数据位。范围4-8    dcb.StopBits = ONESTOPBIT;    //停止位    if (parity == NOPARITY){        dcb.fParity = FALSE;  //奇偶校验。无奇偶校验        dcb.Parity = parity;  //校验模式。无奇偶校验    }    else{        dcb.fParity = TRUE;       //奇偶校验。        dcb.Parity = parity;  //校验模式。无奇偶校验    }    dcb.fOutxCtsFlow = FALSE; //CTS线上的硬件握手    dcb.fOutxDsrFlow = FALSE; //DST线上的硬件握手    dcb.fDtrControl = DTR_CONTROL_ENABLE; //DTR控制    dcb.fDsrSensitivity = FALSE;    dcb.fTXContinueOnXoff = FALSE;//    dcb.fOutX = FALSE;            //是否使用XON/XOFF协议    dcb.fInX = FALSE;         //是否使用XON/XOFF协议    dcb.fErrorChar = FALSE;       //是否使用发送错误协议    dcb.fNull = FALSE;            //停用null stripping    dcb.fRtsControl = RTS_CONTROL_ENABLE;//    dcb.fAbortOnError = FALSE;    //串口发送错误,并不终止串口读写    //设置串口参数    if (!SetCommState(m_hComm, &dcb)){        MessageBox(NULL, _T("设置串口参数失败"), _T("提示"), MB_OK);        return FALSE;    }    //设置串口事件    SetCommMask(m_hComm, EV_RXCHAR); //在缓存中有字符时产生事件    SetupComm(m_hComm, 16384, 16384);    //设置串口读写时间    COMMTIMEOUTS CommTimeOuts;    GetCommTimeouts(m_hComm, &CommTimeOuts);    CommTimeOuts.ReadIntervalTimeout = MAXDWORD;    CommTimeOuts.ReadTotalTimeoutMultiplier = 0;    CommTimeOuts.ReadTotalTimeoutConstant = 0;    CommTimeOuts.WriteTotalTimeoutMultiplier = 10;    CommTimeOuts.WriteTotalTimeoutConstant = 1000;    if (!SetCommTimeouts(m_hComm, &CommTimeOuts)){        MessageBox(NULL, _T("设置串口时间失败"), _T("提示"), MB_OK);        return FALSE;    }    //创建线程,读取数据    HANDLE hReadCommThread = (HANDLE)_beginthreadex(NULL, 0, (PTHREAD_START)CommProc, (LPVOID) this, 0, NULL);    return TRUE;}/********************************************************************************************* 功能    :    通过串口发送一条数据********************************************************************************************/BOOL CSerial::SendData(unsigned char* data){    if (m_hComm == INVALID_HANDLE_VALUE){        MessageBox(NULL, _T("串口未打开"), _T("提示"), MB_OK);        return FALSE;    }    //清空串口    PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);    //写串口    DWORD dwWrite = 0;    DWORD dwRet = WriteFile(m_hComm, data, m_dataLength, &dwWrite, NULL);    //清空串口    PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);    if (!dwRet){        MessageBox(NULL, _T("发送数据失败"), _T("提示"), MB_OK);        return FALSE;    }    //HANDLE hReadCommThread = (HANDLE)_beginthreadex(NULL, 0, (PTHREAD_START)CommProc, (LPVOID) this, 0, NULL);    return TRUE;}/********************************************************************************************* 功能    :    CRC校验码计算********************************************************************************************/void CSerial::calccrc(BYTE crcbuf){    crc = crc^crcbuf;    for (BYTE i = 0; i < 8; i++){        BYTE TT;        TT = crc & 1;        crc = crc & 0x7fff;        if (TT == 1){            crc = crc ^ 0xa001;            crc = crc & 0xffff;        }    }}/********************************************************************************************* 功能    :    数据格式转换********************************************************************************************/unsigned char* CSerial::modbusFormat_pre(SLocaVecTime hitPoint){    unsigned char startCharacter = 0x02;//起始    unsigned char stopCharacter = 0x03;//结束    unsigned char funcCode = 0x06;//命令    unsigned char sizeOfData = 0x14;//数据个数    crc = 0xffff;    int time = int(hitPoint.Time * 1000);//单位:秒*1000    int coordX = int(hitPoint.Location.x * 1000);//单位:毫米    int coordY = int(hitPoint.Location.y * 1000);    int coordZ = int(hitPoint.Location.z * 1000);    int vectorX = int(hitPoint.Vec.x * 1000);//单位:毫米每秒    int vectorY = int(hitPoint.Vec.y * 1000);    int vectorZ = int(hitPoint.Vec.z * 1000);    int angleN = int(hitPoint.Yangle * 10);//水平角,单位:度*10    int angleO = int(hitPoint.Pangle * 10);//垂直角    modbusDataBuf_pre[0] = startCharacter;    modbusDataBuf_pre[1] = funcCode;    modbusDataBuf_pre[2] = sizeOfData;    modbusDataBuf_pre[3] = highByte(time);    modbusDataBuf_pre[4] = lowByte(time);    modbusDataBuf_pre[5] = highByte(coordX);    modbusDataBuf_pre[6] = lowByte(coordX);    modbusDataBuf_pre[7] = highByte(coordY);    modbusDataBuf_pre[8] = lowByte(coordY);    modbusDataBuf_pre[9] = highByte(coordZ);    modbusDataBuf_pre[10] = lowByte(coordZ);    modbusDataBuf_pre[11] = highByte(angleN);    modbusDataBuf_pre[12] = lowByte(angleN);    modbusDataBuf_pre[13] = highByte(angleO);    modbusDataBuf_pre[14] = lowByte(angleO);    modbusDataBuf_pre[15] = highByte(vectorX);    modbusDataBuf_pre[16] = lowByte(vectorX);    modbusDataBuf_pre[17] = highByte(vectorY);    modbusDataBuf_pre[18] = lowByte(vectorY);    modbusDataBuf_pre[19] = highByte(vectorZ);    modbusDataBuf_pre[20] = lowByte(vectorZ);    modbusDataBuf_pre[21] = 0x00;    modbusDataBuf_pre[22] = 0x00;    for (int i = 3; i <= 22; i++){        calccrc(modbusDataBuf_pre[i]);    }    modbusDataBuf_pre[23] = crc & 0xff;    modbusDataBuf_pre[24] = crc / 0x100;    modbusDataBuf_pre[25] = stopCharacter;    m_dataLength = 26;    return modbusDataBuf_pre;}unsigned char* CSerial::modbusFormat_realtime(SLocaVecTime hitPoint){    unsigned char startCharacter = 0x02;//起始    unsigned char stopCharacter = 0x03;//结束    unsigned char funcCode = 0x08;//命令    unsigned char sizeOfData = 0x08;//数据个数    crc = 0xffff;    int time = int(hitPoint.Time * 1000);//单位:秒*1000    int coordX = int(hitPoint.Location.x * 1000);//单位:毫米    int coordY = int(hitPoint.Location.y * 1000);    int coordZ = int(hitPoint.Location.z * 1000);    modbusDataBuf_realtime[0] = startCharacter;    modbusDataBuf_realtime[1] = funcCode;    modbusDataBuf_realtime[2] = sizeOfData;    modbusDataBuf_realtime[3] = highByte(time);    modbusDataBuf_realtime[4] = lowByte(time);    modbusDataBuf_realtime[5] = highByte(coordX);    modbusDataBuf_realtime[6] = lowByte(coordX);    modbusDataBuf_realtime[7] = highByte(coordY);    modbusDataBuf_realtime[8] = lowByte(coordY);    modbusDataBuf_realtime[9] = highByte(coordZ);    modbusDataBuf_realtime[10] = lowByte(coordZ);    for (int i = 3; i <= 10; i++){        calccrc(modbusDataBuf_realtime[i]);    }    modbusDataBuf_realtime[11] = crc & 0xff;    modbusDataBuf_realtime[12] = crc / 0x100;    modbusDataBuf_realtime[13] = stopCharacter;    m_dataLength = 14;    return modbusDataBuf_realtime;}/********************************************************************************************* 功能    :    数据高低位计算********************************************************************************************/unsigned char CSerial::highByte(int data){    unsigned char HighByte;    if (data >= 0){        HighByte = data / 256;    }    else{        data = abs(data);        HighByte = data / 256 + 0x80;    }    return HighByte & 0xFF;}unsigned char CSerial::lowByte(int data){    data = abs(data);    unsigned char LowByte;    LowByte = data % 256;    return LowByte & 0xFF;}... CSerial.cpp'''
#include <fstream>#include <tchar.h>#include "Global.h"#include "CSerial.h"using namespace std;ifstream fin("result.txt");int main(){    CSerial* pSerial = new CSerial();    if(!pSerial->OpenSerialPort(_T("COM7:"), 115200, 8, 1, 1)){        cout << "OpenSerialPort Error" << endl;        return -1;    }    SLocaVecTime data;    float HorAngle = 0.0;    float VerAngle = 0.0;    int line = 0;    while (!fin.eof()){        fin >> data.Location.x;        fin >> data.Location.y;        fin >> data.Location.z;        fin >> data.Vec.x;        fin >> data.Vec.y;        fin >> data.Vec.z;        fin >> data.Yangle;        fin >> data.Pangle;        fin >> data.Time;        pSerial->SendData(pSerial->modbusFormat_pre(data));        line++;        cout << line << endl;        Sleep(10);    }}