• 射频识别技术课程实验--模拟串口间的通信--基础实验


    射频识别技术课程实验–模拟串口间的通信

    前期准备

    串口调试小助手:

    模拟串口工具:

    Visual Studio 2022:

    测试代码(c++):

    #include
    #include
    
    using namespace std;
    
    int main() 
    {
    	system("color 3F");
    	HANDLE hCom = CreateFile("\\\\.\\COM2", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,// 指定串口编号
    		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
    	if (INVALID_HANDLE_VALUE == hCom)
    	{
    		cout << "serial open failed" << endl;
    		system("pause");
    		return -1;
    	};
    
    	//设置串口
    	//1、设置输入输出缓冲区大小
    	SetupComm(hCom, 1024, 1024);
    	//2、设置时延
    	COMMTIMEOUTS TimeOuts;
    	TimeOuts.ReadIntervalTimeout = 1000;
    	TimeOuts.ReadTotalTimeoutMultiplier = 500;
    	TimeOuts.ReadTotalTimeoutConstant = 5000;//设定写超时
    	TimeOuts.WriteTotalTimeoutMultiplier = 500;
    	TimeOuts.WriteTotalTimeoutConstant = 2000;
    	SetCommTimeouts(hCom, &TimeOuts);
    	//3、DCB结构体
    	DCB dcb;
    	GetCommState(hCom, &dcb);
    	dcb.BaudRate = 9600;
    	dcb.ByteSize = 32;
    	dcb.StopBits = 1;
    	SetCommState(hCom, &dcb);
    	//4、清空硬件的通信错误,清空输入输出缓冲,为W/R做准备
    	PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    
    
    
    	//5、发送串口信息
    	char buffer[] = { 0XFE, 0X03, 0X04, 0X00, 0X03, 0X00, 0X00, 0X00, 0X00, 0X00, 0XFA };
    	DWORD dwBytesToWrite = sizeof(buffer);
    	DWORD dwBytesRealWrite;
    	DWORD dwErrorFlags;
    	COMSTAT comStat;
    	OVERLAPPED osWrite;
    	//memset(&osWrite,0,sizeof(OVERLAPPED));
    	osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    	osWrite.Offset = 0;
    	osWrite.OffsetHigh = 0;
    	//清除硬件通信错误;
    	ClearCommError(hCom, &dwErrorFlags, &comStat);
    	BOOL bWriteStatus;
    	bWriteStatus = WriteFile(hCom, buffer, dwBytesToWrite, &dwBytesRealWrite, &osWrite);
    	int m = GetLastError();
    	if (!bWriteStatus)
    	{
    		if (GetLastError() == ERROR_IO_PENDING)
    		{
    			WaitForSingleObject(osWrite.hEvent, 2000);
    
    			//清理IO缓冲区;
    			PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    		}
    		else
    		{
    			cout << "failed to send" << endl;
    			system("pause");
    			return -1;
    		}
    		PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    	}
    	PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    
    	//6、接收串口信息
    	unsigned char lpInBuffer[1024];
    	DWORD dwBytesRead;
    	OVERLAPPED osRead;
    	memset(&osRead, 0, sizeof(OVERLAPPED));
    	
    
    	BOOL bReadStatus;
    	DWORD dwRealRead;
    	while (1)
    	{
    		dwBytesRead = 1024;
    		osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    		ClearCommError(hCom, &dwErrorFlags, &comStat);
    		dwBytesRead = min(dwBytesRead, (DWORD)comStat.cbInQue);
    		if (!dwBytesRead)
    		{
    			//cout << "no data to be read" << endl;
    			Sleep(1000);
    			continue;
    		}
    
    		bReadStatus = ReadFile(hCom, lpInBuffer, dwBytesRead, &dwRealRead, &osRead);
    
    		if (!bReadStatus)
    			//如果ReadFile函数返回FALSE
    		{
    			if (GetLastError() == ERROR_IO_PENDING)
    				//GetLastError()函数返回ERROR_IO_PENDING,表明串口正在进行读操作
    			{
    				WaitForSingleObject(osRead.hEvent, 2000);
    				//使用WaitForSingleObject函数等待,直到读操作完成或延时已达到2秒钟
    				//当串口读操作进行完毕后,osRead的hEvent事件会变为有信号
    				PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
    
    				short *temp = new  short[dwRealRead + 1];
    				for (int i = 0; i < dwBytesRead; ++i)
    				{
    					temp[i] = lpInBuffer[i];
    					printf("%02X", temp[i]);
    				}
    				cout << endl;
    				/*delete[] temp;*/
    			}
    			else
    				cout << "failed to read" << endl;
    		}
    		else
    		{
    			short *temp = new  short[dwRealRead + 1];
    			for (int i = 0; i < dwBytesRead; ++i)
    			{
    				temp[i] = lpInBuffer[i];
    				printf("%02X", temp[i]);
    			}
    			cout << endl;
    			delete[] temp;
    		}
    		Sleep(1000);
    		PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    	}
    	PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    	system("pause");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139

    实验过程

    基础实验

    1. 模拟两个串口

    2. 打开两个串口调试小助手,分别打开上一步模拟的两个串口,这里我创建的串口名字为“COM1”和“COM2”。

    3. 测试串口连通性:

      可以看到串口连通性正常,两端都可以互相发送数据

    4. 打开Visual Studio 2022,新建空项目

    5. 将准备好的代码放在源文件中,运行调试:

      发现提示serial open failed,这是因为我们一开始打开了两个串口,并且代码中指定串口编号为COM2,但是COM2已经打开了,所以报错串口开启失败。

      HANDLE hCom = CreateFile("\\\\.\\COM2", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,// 指定串口编号
      
      • 1
    6. 于是我们关闭COM2,保留COM1

      这时再次运行C++程序,使用串口COM1发送数据:

      此时我们的C++程序扮演的角色其实就是串口COM2,接收到串口COM1发送的数据,至此,基础实验部分就完成了。

  • 相关阅读:
    使用vue-cli搭建SPA项目
    软件测试-朋友圈的点赞功能怎么测?
    js将带标签的内容转为纯文本
    【STM32CubeMX】NRF24L01模块实现“1对1“及“1对多“无线通信
    CVPR 2022 Oral | MAXIM: Multi-Axis MLP for Image Processing
    Spring的SmartLifecycle可以没用过,但没听过就不好了! - 第517篇
    利用宏定义在编译阶段检查结构体大小的方法
    机械专业学子的芯片封装仿真“逆袭之路”
    最短路问题之Dijkstra算法 洛谷 单源最短路径
    开发一个自己的前端脚手架
  • 原文地址:https://blog.csdn.net/liujaiqi111/article/details/133713335