打印
[应用相关]

单片机与计算机通信(上位机)——基于VS2017和stm32

[复制链接]
1119|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wakayi|  楼主 | 2019-7-6 16:49 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
**程序说明:**VSwin32命令控制台程序 调用串口,可以根据自己需要配置串口,完成windows与单片机的数据传输。可作为开发参考使用。

直接先贴代码

//32与单片机通信,差不多成功了



#include <iostream>  
#include <cstdlib>  
#include <windows.h>  
#include <stdlib.h>



using namespace std;
HANDLE hComm;
OVERLAPPED OverLapped;
COMSTAT Comstat;
DWORD dwCommEvents;

char g_UartRxBuffer[6] = { 0x0d,1,2,3,4,0x0a };

//int g_UartRxBuffer[0] = 0x0d;//
//int g_UartRxBuffer[1] = 99;
//int g_UartRxBuffer[2] = 0;
//int g_UartRxBuffer[3] = 0;
//int g_UartRxBuffer[4] = 99;
//int g_UartRxBuffer[5] = 0x0a;


bool OpenPort();  //打开串口  
bool SetupDCB(int rate_arg);  //设置DCB  
bool SetupTimeout(DWORD ReadInterval, DWORD ReadTotalMultiplier, DWORD
    ReadTotalConstant, DWORD WriteTotalMultiplier, DWORD WriteTotalConstant);   //设置超时  
void ReciveChar();   //接收字符  
bool WriteChar(char* szWriteBuffer, DWORD dwSend);  //发送字符  


使用特权

评论回复
沙发
wakayi|  楼主 | 2019-7-6 16:49 | 只看该作者
bool OpenPort()
{
    hComm = CreateFile(L"COM6",//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!此处更改com口!!!!!!!!!!!!!!!
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED,
        0);
    if (hComm == INVALID_HANDLE_VALUE)
        return FALSE;
    else
        return true;
}

使用特权

评论回复
板凳
wakayi|  楼主 | 2019-7-6 16:50 | 只看该作者
bool SetupDCB(int rate_arg)
{
    DCB dcb;
    memset(&dcb, 0, sizeof(dcb));
    if (!GetCommState(hComm, &dcb))//获取当前DCB配置  
    {
        return FALSE;
    }
    dcb.DCBlength = sizeof(dcb);
    /* ---------- Serial Port Config ------- */
    dcb.BaudRate = rate_arg;
    dcb.Parity = NOPARITY;
    dcb.fParity = 0;
    dcb.StopBits = ONESTOPBIT;
    dcb.ByteSize = 8;
    dcb.fOutxCtsFlow = 0;
    dcb.fOutxDsrFlow = 0;
    dcb.fDtrControl = DTR_CONTROL_DISABLE;
    dcb.fDsrSensitivity = 0;
    dcb.fRtsControl = RTS_CONTROL_DISABLE;
    dcb.fOutX = 0;
    dcb.fInX = 0;
    dcb.fErrorChar = 0;
    dcb.fBinary = 1;
    dcb.fNull = 0;
    dcb.fAbortOnError = 0;
    dcb.wReserved = 0;
    dcb.XonLim = 2;
    dcb.XoffLim = 4;
    dcb.XonChar = 0x13;
    dcb.XoffChar = 0x19;
    dcb.EvtChar = 0;
    if (!SetCommState(hComm, &dcb))
    {
        return false;
    }
    else
        return true;
}

使用特权

评论回复
地板
wakayi|  楼主 | 2019-7-6 16:50 | 只看该作者
bool SetupTimeout(DWORD ReadInterval, DWORD ReadTotalMultiplier, DWORD
    ReadTotalConstant, DWORD WriteTotalMultiplier, DWORD WriteTotalConstant)
{
    COMMTIMEOUTS timeouts;
    timeouts.ReadIntervalTimeout = ReadInterval;
    timeouts.ReadTotalTimeoutConstant = ReadTotalConstant;
    timeouts.ReadTotalTimeoutMultiplier = ReadTotalMultiplier;
    timeouts.WriteTotalTimeoutConstant = WriteTotalConstant;
    timeouts.WriteTotalTimeoutMultiplier = WriteTotalMultiplier;
    if (!SetCommTimeouts(hComm, &timeouts))
    {
        return false;
    }
    else
        return true;
}

使用特权

评论回复
5
wakayi|  楼主 | 2019-7-6 16:50 | 只看该作者
void ReciveChar()
{
    bool bRead = TRUE;
    bool bResult = TRUE;
    DWORD dwError = 0;
    DWORD BytesRead = 0;
    char RXBuff;
    for (;;)
    {
        bResult = ClearCommError(hComm, &dwError, &Comstat);
        if (Comstat.cbInQue == 0)
            continue;
        if (bRead)
        {
            bResult = ReadFile(hComm,  //通信设备(此处为串口)句柄,由CreateFile()返回值得到  
                &RXBuff,  //指向接收缓冲区  
                1,  //指明要从串口中读取的字节数  
                &BytesRead,   //  
                &OverLapped);  //OVERLAPPED结构  
            std::cout << RXBuff << std::endl;
            if (!bResult)
            {
                switch (dwError == GetLastError())
                {
                case ERROR_IO_PENDING:
                    bRead = FALSE;
                    break;
                default:
                    break;
                }
            }
        }
        else
        {
            bRead = TRUE;
        }
    }
    if (!bRead)
    {
        bRead = TRUE;
        bResult = GetOverlappedResult(hComm,
            &OverLapped,
            &BytesRead,
            TRUE);
    }
}

使用特权

评论回复
6
wakayi|  楼主 | 2019-7-6 16:51 | 只看该作者
bool WriteChar(char* szWriteBuffer, DWORD dwSend)
{
    bool bWrite = TRUE;
    bool bResult = TRUE;
    DWORD BytesSent = 0;
    HANDLE hWriteEvent = NULL;
    ResetEvent(hWriteEvent);
    if (bWrite)
    {
        OverLapped.Offset = 0;
        OverLapped.OffsetHigh = 0;
        bResult = WriteFile(hComm,  //通信设备句柄,CreateFile()返回值得到  
            szWriteBuffer,  //指向写入数据缓冲区  
            dwSend,  //设置要写的字节数  
            &BytesSent,  //  
            &OverLapped);  //指向异步I/O数据  
        if (!bResult)
        {
            DWORD dwError = GetLastError();
            switch (dwError)
            {
            case ERROR_IO_PENDING:
                BytesSent = 0;
                bWrite = FALSE;
                break;
            default:
                break;
            }
        }
    }
    if (!bWrite)
    {
        bWrite = TRUE;
        bResult = GetOverlappedResult(hComm,
            &OverLapped,
            &BytesSent,
            TRUE);
        if (!bResult)
        {
            std::cout << "GetOverlappedResults() in WriteFile()" << std::endl;
        }
    }
    if (BytesSent != dwSend)
    {
        std::cout << "WARNING: WriteFile() error.. Bytes Sent:" << BytesSent << "; Message Length: " << strlen((char*)szWriteBuffer) << std::endl;
    }
    return TRUE;
}

使用特权

评论回复
7
wakayi|  楼主 | 2019-7-6 16:51 | 只看该作者
int main(int argc, char** argv)
{
    if (OpenPort())
        std::cout << "Open port success" << std::endl;
    if (SetupDCB(9600))//!!!!!!!!!!!!!!!!!!!此处更改波特率!!!!!!!!!!!!!!!!!!!!!!
        std::cout << "Set DCB success" << std::endl;
    if (SetupTimeout(0, 0, 0, 0, 0))
        std::cout << "Set timeout success" << std::endl;
    PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

    while (1)
    {
        WriteChar(g_UartRxBuffer, 6);//可以自行设置分部发送



    //  ReciveChar();

        cout <<"正在发送"<< endl;
    }

使用特权

评论回复
8
wakayi|  楼主 | 2019-7-6 16:51 | 只看该作者
分析
主要就是下面5个函数构成
bool OpenPort(); //打开串口

bool SetupDCB(int rate_arg); //设置DCB

bool SetupTimeout(DWORD ReadInterval, DWORD ReadTotalMultiplier, DWORD
ReadTotalConstant, DWORD WriteTotalMultiplier, DWORD WriteTotalConstant); //设置超时

void ReciveChar(); //接收字符

bool WriteChar(char* szWriteBuffer, DWORD dwSend); //发送字符

使用特权

评论回复
9
wakayi|  楼主 | 2019-7-6 16:51 | 只看该作者
一、bool OpenPort(); //打开串口
里面主要调用了一个CreateFile()函数
这个函数的功能是创建或者打开一个文件或者I/O设备,通常使用的I/O形式有文件、文件流、目录、物理磁盘、卷、终端流等。如执行成功,则返回文件句柄。 INVALID_HANDLE_VALUE 表示出错,会设置 GetLastError 。
函数的声明定义:

  HANDLE WINAPI CreateFile(
  _In_      LPCTSTR lpFileName,              
  _In_      DWORD dwDesiredAccess,
  _In_      DWORD dwShareMode,
  _In_opt_  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  _In_      DWORD dwCreationDisposition,
  _In_      DWORD dwFlagsAndAttributes,
  _In_opt_  HANDLE hTemplateFile
);

使用特权

评论回复
10
wakayi|  楼主 | 2019-7-6 16:52 | 只看该作者

参数列表

该函数第一个参数那里可以更改串口号


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

3853

帖子

1

粉丝