历史上的今天
今天是: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 ); 参数列表 该函数第一个参数那里可以更改串口号 
上一篇:stm32实时时钟——RTC
下一篇:stm32的堆和栈
史海拾趣
|
Renesas单片机前身是三菱和日立单片机的联盟。因此每年出货量全球第一位。 设计了一块对此单片机的评估板,也可以说是一块开发板。(板子已经在制版,焊接好发图片,下周五之前) 因为不涉及公司机密,将在这个帖子里面发布我的所有资料。只是可惜 ...… 查看全部问答> |
|
利用DeviceIoControl()与u盘进行通信, 通信方式为IOCTL_SCSI_PASS_THROUGH_DIRECT, 这里需要一个CDB命令块,这个CDB命令是如何得到的。 我看到别人的程序中有BYTE Cdb[6] = {0x12, 0x01, &n ...… 查看全部问答> |
|
请教各位DX: 我现在通过修改interface来实现自己设计的界面,由于修改了视频显示区域,所以原有视频显示不正常,有拉伸,如何修改原有视频数据,达到正常的缩放显示效果。… 查看全部问答> |
|
我两块板上电了,设备管理器上也有显示,说明驱动也安装了。但是在debug时,弹出的选择目标(target selection)中是空白的。!!!! 那个对话框下面就写着 a target connot be selected wh ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 04:05 编辑 现在清单都出来了,想必大家都研究了好几天了,大家过来讨论下,到底会出什么题呢?肯定不会太难,可是根据清单不得不往难处想,各种纠结啊,可以参考一下黑龙江激光打靶题,这题我也想了半天,除了 ...… 查看全部问答> |




