串口调试+VS2015

来源:互联网 发布:拳皇2002键盘优化 编辑:程序博客网 时间:2024/06/06 05:05

参考

用VS2010写了一个串口示例程序(使用API写的)—-lindabell@欧海

/*"Serial_Vs.h"*/#include<iostream>  #include<TCHAR.H>   #include<windows.h>  #include<string.h>/*#include "opencv2/objdetect.hpp"#include "opencv2/videoio.hpp"#include "opencv2/highgui.hpp"#include "opencv2/imgproc.hpp"#include "opencv2/video/tracking.hpp"  #include "opencv2/imgproc/imgproc.hpp"  #include "opencv2/highgui/highgui.hpp"  #include <stdio.h>*/using namespace std;using namespace cv;HANDLE Serial_open(LPCWSTR, int); //串口开启函数int Serial_read(HANDLE, void*, int); //串口读int Serial_write(HANDLE, const void*, int); //串口写void Serial_close(HANDLE);//串口关void clear_buf(unsigned char*, int); //清空字符串数组/**open serial@param COMx: eg:_T("COM1")@param BaudRate:return 0 success ,return Negative is haed err*/HANDLE Serial_open(LPCWSTR COMx, int BaudRate){    HANDLE hCom;//串口设备句柄    DCB dcb = { 0 };    hCom = CreateFile(COMx,        GENERIC_READ | GENERIC_WRITE,        0,        0,        OPEN_EXISTING,        0,//FILE_FLAG_OVERLAPPED,   //同步方式 或 重叠方式           0    );    if (hCom == INVALID_HANDLE_VALUE)    {        DWORD dwError = GetLastError();        printf("Sorry, failed to open the serial\n");        //return -1;          printf("The program will terminate in 3 seconds\n");        Sleep(3000);        exit(0);    }    else        printf("The serial is successfully opened in a Baudrate %d!\n", BaudRate);    dcb.DCBlength = sizeof(DCB);    if (!GetCommState(hCom, &dcb))    {        DWORD dwError = GetLastError();        return(HANDLE)(-1);    }    dcb.BaudRate = BaudRate;   //波特率       dcb.ByteSize = 8;          //位数       dcb.Parity = NOPARITY;     //奇偶检验       dcb.StopBits = ONESTOPBIT;  //停止位数       if (!SetCommState(hCom, &dcb))    {        DWORD dwError = GetLastError();        return(HANDLE)(-1);    }    if (!PurgeComm(hCom, PURGE_RXCLEAR))   return(HANDLE)(-1);    SetupComm(hCom, 1024, 1024);    return hCom;}/**serial read@param Buf:data buf@param size:@return The len of read*/int Serial_read(HANDLE hCom, void* OutBuf, int size){    DWORD cnt = 0;    ReadFile(hCom, OutBuf, size, &cnt, 0);    return cnt;}/**serial write@param Buf:data buf@param size:bytes of Buf@return The len of writen*/int Serial_write(HANDLE hCom, const void*Buf, int size){    DWORD dw;    WriteFile(hCom, Buf, size, &dw, NULL);    return dw;}/**serial close*/void Serial_close(HANDLE hCom){    CloseHandle(hCom);}/**clear buf*/void clear_buf(unsigned char*buf, int N){    int i;    for (i = 0; i <N; i++)buf[i] = 0;    buf[i] = '\0';}/*main.cpp*/HANDLE hCom;int main(){    //--open serial port as a default baudrate 9600      hCom = Serial_open(_T("COM4"), 9600); //修改串口号"COMx"    int len=0;    int i = 0;    while (1)    {        //len = Serial_read(hCom,&data, 1);        char data = '0';        //char datastrX[4] = "";        //char datastrY[4] = "";        char bufferX[4] = "";        char bufferY[4] = "";        int x, y;        Serial_read(hCom, &data, 1);        switch (data) {        case 'X':            for (int i = 0; i <5; i++)            {                Serial_read(hCom, &data, 1); //读取串口设备数据1个字节,放到data中                if (data == 'R') break;                bufferX[i] = data;                data = '0';            }            //write(hCom,&bufferX,4); //写入串口设备            char * sx;            //strncpy_s(datastrX, bufferX, 4);            x = strtol(bufferX, &sx, 10);//X轴坐标的int形式            memset(bufferX, 0, sizeof(bufferX) / sizeof(char));//清空字符串数组            break;        case 'Y':            for (int i = 0; i <5; i++)            {                Serial_read(hCom, &data, 1); //读取串口设备数据1个字节,放到data中                if (data == 'R') break;                bufferY[i] = data;                data = '0';            }            char * sy;            //strncpy_s(datastrY, bufferY, 4);            y = strtol(bufferY, &sy, 10);//Y轴坐标的int形式            memset(bufferY, 0, sizeof(bufferY) / sizeof(char));            break;        default:  break;        }        PurgeComm(hCom, PURGE_RXABORT);//清空缓存        printf("标识中心坐标为  \t%d , \t%d\n", x, y);        int c = waitKey(10);        if ((char)c == 27) { break; } // escape    }    PurgeComm(hCom, PURGE_RXCLEAR);    //--Close and reopen the port      Serial_close(hCom);    return 0;}

问题

程序运行接收串口数据后一段时间,出现 buffer is too small

原因

strncpy_s() 字符串拷贝函数,出现字符串数组长度不匹配问题,但是修改长度后还是存在问题。
可能的方案:
参数直接给字符串数组时,有几率发生这种运行时错误,现先用CString赋值,再作参数。

  • 2017.2.28
    • 右击工程 - 属性 - 配置属性 - C/C++ - 命令行
    • 命令行增加/D _CRT_SECURE_NO_WARNINGS
    • 使用strncpy()而不是添加了安全性能防止数组越界的strncpy_s()。不再报buffer is too small,但是数据从负的两位数到负的三位数时,strncpy()中的bufferXdatastrX同时产生乱码:

    • bufferX is :-102烫烫烫烫烫烫烫烫烫烫烫烫烫烫 datastrX is :-102烫烫烫烫烫烫烫烫烫烫烫烫烫烫
    • strtol()转换的整型不受影响,还是输出-102。
    • 正两位数到正三位数也不会出现越界现象。
0 0