串口调试+VS2015

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xinyu3307/article/details/58323657

参考

用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。
    • 正两位数到正三位数也不会出现越界现象。

猜你喜欢

转载自blog.csdn.net/xinyu3307/article/details/58323657
今日推荐