历史上的今天
返回首页

历史上的今天

今天是:2025年02月26日(星期三)

正在发生

2020年02月26日 | 单片机与计算机通信(上位机)——基于VS2017和stm32

2020-02-26 来源:eefocus

**程序说明:**VSwin32命令控制台程序 调用串口,可以根据自己需要配置串口,完成windows与单片机的数据传输。可作为开发参考使用。


直接先贴代码


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


#include   

#include   

#include   

#include


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);  //发送字符  


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;

}


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;

}


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;

}


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);

    }

}


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;

}

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;

    }


分析

主要就是下面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); //发送字符


一、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

);


参数列表 

这里写图片描述

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

推荐阅读

史海拾趣

光大芯业公司的发展小趣事

在公司的成长过程中,光大芯业始终坚持以技术为核心,不断寻求技术上的突破。他们积极与国内外知名科研院所开展技术合作,引进先进的技术和设备,提升自身的研发能力。其中,与浙江大学微电子研究所的合作,成功开发出了开关电源管理芯片SDC7500,这一成果不仅填补了国内市场的空白,也展示了光大芯业在技术创新方面的实力。

AUSTIN公司的发展小趣事

在合并与合作的背景下,奥斯汀汽车开始注重产品创新和多样化。公司不断推出新的车型,以满足不同消费者的需求。例如,奥斯汀A40和A50等车型在市场上取得了不错的销量。同时,奥斯汀汽车还注重技术研发和创新,不断提升产品的性能和品质。

CUI公司的发展小趣事

在电子行业的初期,CUI技术的应用受限于其导电性能和稳定性。然而,随着科研人员的不断努力,新型的CUI材料逐渐问世,它们不仅导电性能优良,而且能够抵御各种环境因素的影响。与此同时,市场对于小型化、高集成度的电子产品需求日益增长,CUI技术因其能够在狭小空间内实现高效电路连接而备受青睐。

Harbour Industries公司的发展小趣事

背景:随着信息技术的快速发展和工业互联网的兴起,电子行业正经历着深刻的数字化转型和智能化升级。Handok紧跟时代步伐,积极推动公司的数字化转型和智能化升级。

发展:Handok引入了先进的信息化管理系统和智能制造技术,实现了生产过程的自动化、智能化和可视化。同时,公司还加强了与上下游企业的协同合作,构建了更加紧密、高效的产业链生态系统。

影响:数字化转型和智能化升级不仅提高了Handok的生产效率和产品质量,还降低了运营成本和市场风险。此外,这一战略还有助于公司在未来的市场竞争中保持灵活性和创新性。

请注意,以上故事是基于一般性的商业逻辑和行业趋势构建的,并非Handok公司的实际发展历程。由于直接关于Handok在电子行业发展的详细故事资料有限,这些故事仅供参考和启发。

E-San Electronic Co Ltd公司的发展小趣事

E-San Electronic Co Ltd非常重视人才培养和团队建设。公司建立了完善的培训机制,为员工提供了各种专业技能和综合素质的培训机会。同时,公司还注重员工的职业规划和晋升通道建设,为员工提供了广阔的发展空间和良好的职业前景。这些措施不仅提升了员工的综合素质和业务能力,也为企业的发展注入了源源不断的活力。

Analytic Instruments Corp公司的发展小趣事

随着电子行业的快速发展和技术的不断进步,Analytic Instruments Corp面临着日益激烈的市场竞争。为了保持领先地位,公司不断调整产品结构和市场策略,积极应对行业变革。公司加大了研发投入,推出了一系列具有创新性和竞争力的新产品。同时,公司还加强了与客户的沟通和合作,深入了解客户需求,为客户提供更加个性化的解决方案。

问答坊 | AI 解惑

关于运放的虚短

请各位电子高手从内部结构上解释一下运放的“虚短”,谢谢!…

查看全部问答>

发布一块Renesas开发板的全部资料

Renesas单片机前身是三菱和日立单片机的联盟。因此每年出货量全球第一位。 设计了一块对此单片机的评估板,也可以说是一块开发板。(板子已经在制版,焊接好发图片,下周五之前) 因为不涉及公司机密,将在这个帖子里面发布我的所有资料。只是可惜 ...…

查看全部问答>

CE6.0 R3里的QQ和MSN支持语音聊天吗?

在有网络供使用的情况下,CE6.0 R3里的QQ和MSN支持语音聊天吗? 谢谢各位!…

查看全部问答>

DeviceIoControl与u盘硬件通信

利用DeviceIoControl()与u盘进行通信, 通信方式为IOCTL_SCSI_PASS_THROUGH_DIRECT, 这里需要一个CDB命令块,这个CDB命令是如何得到的。 我看到别人的程序中有BYTE Cdb[6] = {0x12,        0x01,      &n ...…

查看全部问答>

进制转化问题

数值的补码表示分两种情况: (1)正数的补码:与原码相同。 (2)负数的补码:符号位为1,其余位为该数绝对值的原码按位取反;然后整个数加1。 每当有人问我怎么把原码转化成补码时我就这样告诉他,自己也是这么求的。可是我不知道为什么要 ...…

查看全部问答>

请教TCPMP视频问题

请教各位DX:    我现在通过修改interface来实现自己设计的界面,由于修改了视频显示区域,所以原有视频显示不正常,有拉伸,如何修改原有视频数据,达到正常的缩放显示效果。…

查看全部问答>

为什么我不可以在MiniIDE里的output里做rd,t f之类debug?

我在miniIDE 里不能输入rd来注册输出,按不了回车。…

查看全部问答>

我的TIzigbee开发板不知为什么烧录不了呢?

我两块板上电了,设备管理器上也有显示,说明驱动也安装了。但是在debug时,弹出的选择目标(target selection)中是空白的。!!!! 那个对话框下面就写着 a target connot be selected wh ...…

查看全部问答>

2012电子大赛控制题讨论

本帖最后由 paulhyde 于 2014-9-15 04:05 编辑 现在清单都出来了,想必大家都研究了好几天了,大家过来讨论下,到底会出什么题呢?肯定不会太难,可是根据清单不得不往难处想,各种纠结啊,可以参考一下黑龙江激光打靶题,这题我也想了半天,除了 ...…

查看全部问答>