该程序实现了串口的读写功能
适用于windows平台
开发环境为:VS2019
运行效果 目前很简陋,以后有时间再做细化:
该次运行是通过虚拟串口软件虚拟出com3,com4端口
com3连接程序,com4连接的是一款串口软件AccessPort 配置与图片在本文后面
com4端的配置
代码如下
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 #include <Windows.h> 4 #include <atlstr.h> 5 #include <strsafe.h> 6 #include <crtdbg.h> 7 8 int FILESIZE = 16; 9 char szStr[5] = "com3"; 10 11 12 13 DWORD WriteFileContent(LPCWSTR szFilePath,DCB dcb) 14 { 15 HANDLE hFile; 16 17 BYTE lpFileDataBuffer[1024]; 18 //lpFileDataBuffer[0] = 0xff; 19 //lpFileDataBuffer[1] = 0xff; 20 DWORD dwWritedSize = 0; 21 DWORD dwWritedSizes; 22 int i = 0; 23 int ByteSize = 0; 24 25 hFile = CreateFile(szFilePath, 26 GENERIC_WRITE, 27 FILE_SHARE_READ, 28 NULL, 29 OPEN_ALWAYS, 30 FILE_ATTRIBUTE_NORMAL, 31 NULL 32 ); 33 if (hFile == INVALID_HANDLE_VALUE) 34 { 35 printf("打开文件失败!\n"); 36 exit(-1); 37 } 38 39 /* 40 DCB配置 41 */ 42 if (!SetCommState(hFile, &dcb)) 43 { 44 printf("BCD配置设置失败!"); 45 CloseHandle(hFile); 46 exit(-1); 47 } 48 49 while (1) 50 { 51 printf("请输入数据字节数,0则退出写入:\n>> "); 52 scanf("%d", &ByteSize); 53 54 if (ByteSize == 0) 55 { 56 //CloseHandle(hFile); 57 //return 0; 58 break; 59 } 60 61 printf("请输入数据,其间空格隔开:\n>> "); 62 for (i = 0; i < ByteSize; i++) 63 { 64 scanf("%x", &lpFileDataBuffer[dwWritedSize++]); 65 } 66 67 dwWritedSize = ByteSize; 68 69 if (!WriteFile(hFile, 70 lpFileDataBuffer, 71 dwWritedSize, 72 &dwWritedSizes, 73 NULL)) 74 { 75 printf("写入文件错误: %d\n", GetLastError()); 76 break; 77 } 78 printf("写入%d字节\n>> ", dwWritedSize); 79 80 81 for (i = 0; i < dwWritedSize; i++) 82 { 83 printf("%x ", lpFileDataBuffer[i]); 84 } 85 printf("\n"); 86 dwWritedSize = 0; 87 88 Sleep(1000); 89 } 90 CloseHandle(hFile); 91 return dwWritedSize; 92 } 93 94 DWORD ReadFileContent(LPCWSTR szFilePath, DCB dcb) 95 { 96 HANDLE hFile; 97 98 BYTE lpFileDataBuffer[1024]; 99 DWORD dwReadedSize; 100 DWORD i; 101 DWORD Time = 0; 102 103 104 105 hFile = CreateFile(szFilePath, 106 GENERIC_READ, 107 FILE_SHARE_WRITE, 108 NULL, 109 OPEN_EXISTING, 110 FILE_ATTRIBUTE_NORMAL, 111 NULL); 112 113 if (hFile == INVALID_HANDLE_VALUE) 114 { 115 printf("打开文件失败!\n"); 116 exit(-1); 117 } 118 119 /* 120 DCB配置 121 */ 122 if (!SetCommState(hFile, &dcb)) 123 { 124 printf("BCD配置设置失败!"); 125 CloseHandle(hFile); 126 exit(-1); 127 } 128 129 /* 130 设置超时 131 */ 132 COMMTIMEOUTS timeOver; 133 memset(&timeOver, 0, sizeof(timeOver)); 134 DWORD timeMultiplier = 100, timeConstant = 5000; 135 timeOver.ReadTotalTimeoutMultiplier = timeMultiplier; 136 timeOver.ReadTotalTimeoutConstant = timeConstant; 137 SetCommTimeouts(hFile, &timeOver); 138 139 140 while (1) 141 { 142 if (!ReadFile(hFile, 143 lpFileDataBuffer, 144 FILESIZE, 145 & dwReadedSize, 146 NULL)) 147 { 148 printf("读取文件错误: %d\n", GetLastError()); 149 break; 150 } 151 printf("读取%d字节\n>> ",dwReadedSize); 152 if (dwReadedSize == 0) 153 { 154 ++Time; 155 if (Time == 1) 156 { 157 printf("读取数据停止!\n"); 158 break; 159 } 160 } 161 else 162 { 163 printf("读取%d字节\n>> ", dwReadedSize); 164 } 165 166 for (i = 0; i < dwReadedSize; i++) 167 { 168 printf(" %x ", lpFileDataBuffer[i]); 169 } 170 printf("\n"); 171 172 Sleep(1000); 173 } 174 CloseHandle(hFile); 175 return 0; 176 } 177 178 void SetDcb(DCB* dcb) 179 { 180 /* 181 DCB结构配置 182 BauRate (波特率) 183 fParity (指定奇偶校验位) 184 Parity (校验方式) 185 ByteSize (数据位个数) 186 StopBits (停止位个数) 187 */ 188 int No = 0; 189 190 dcb->DCBlength = sizeof(DCB); 191 192 while (1) 193 { 194 printf(" DCB结构配置\n"); 195 printf("0.设置:串口编号\n"); 196 printf("1.设置:波特率\n"); 197 printf("2.设置:检验方式\n"); 198 printf("3.设置:停止位数\n"); 199 printf("4.设置:数据位个数\n"); 200 printf("5.设置:读取时一组的字节数\n"); 201 printf("6.查看:当前结构\n"); 202 printf("7.退出\n"); 203 printf(">> "); 204 205 scanf("%d",& No); 206 switch (No) 207 { 208 case 0: 209 { 210 printf("请输入串口编号 例如1:\n>> "); 211 getchar(); 212 scanf("%c", &szStr[3]); 213 printf("串口编号成功改为:%s\n", szStr); 214 break; 215 } 216 case 1: 217 { 218 printf("波特率:\n>> "); 219 scanf("%d", &dcb->BaudRate); 220 printf("波特率成功改为:%d\n", dcb->BaudRate); 221 break; 222 } 223 case 2: 224 { 225 printf("2 :偶校验 EVENPARITY\n"); // EVENPARITY 226 printf("3 :标志校验 MARKPARITY\n"); // MARKPARITY 227 printf("0 :无校验 NOPARITY\n"); // NOPARITY 228 printf("1 :奇校验 ODDPARITY\n"); // ODDPARITY 229 printf(">> "); 230 scanf("%d", &dcb->Parity); 231 printf("校验法成功更改为:%d\n", dcb->Parity); 232 break; 233 } 234 case 3: 235 { 236 printf("0 :1停止位 ONESTOPBIT\n"); // ONESTOPBIT 237 printf("1 :1.5停止位 ONE5STOPBITS\n"); // ONE5STOPBITS 238 printf("2 :2停止位 TWOSTOPBITS\n"); // TWOSTOPBITS 239 printf(">> "); 240 scanf("%d", &dcb->StopBits); 241 printf("停止位成功更改为:%d\n", dcb->StopBits); 242 break; 243 } 244 case 4: 245 { 246 printf("数据位个数:\n>> "); 247 scanf("%d", &dcb->ByteSize); 248 printf("数据位个数成功更改为:%d\n", dcb->ByteSize); 249 break; 250 } 251 case 5: 252 { 253 printf("接收时每组字节数设置:\n>> "); 254 scanf("%d", &FILESIZE); 255 printf("接收时每组字节数成功更改为:%d", FILESIZE); 256 break; 257 } 258 case 6: 259 { 260 printf(" DCB结构配置\n"); 261 printf("0.串口编号 %s\n",szStr); 262 printf("1.波特率 %d\n", dcb->BaudRate); 263 printf("2.检验方式 ");//%d\n", dcb->Parity); 264 switch (dcb->Parity) 265 { 266 case 0: 267 { 268 printf("NOPARITY 无校验\n"); 269 break; 270 } 271 case 1: 272 { 273 printf("ODDPARITY 奇校验\n"); 274 break; 275 } 276 case 2: 277 { 278 printf("EVENPARITY 偶校验\n"); 279 break; 280 } 281 case 3: 282 { 283 printf("MARKPARITY 标志校验\n"); 284 break; 285 } 286 } 287 288 printf("3.停止位数 ");// % d\n", dcb->StopBits); 289 if (dcb->StopBits == 0) 290 printf("ONESTOPBIT 1停止位\n"); 291 else if (dcb->StopBits == 1) 292 printf("ONE5STOPBITS 1.5停止位\n"); 293 else if (dcb->StopBits == 2) 294 printf("TWOSTOPBITS 2停止位\n"); 295 else 296 printf("dcb->ByteSize = %d\n", dcb->StopBits); 297 298 printf("4.数据位个数 %d 位\n", dcb->ByteSize); 299 printf("5.字节数 %d 字节\n", FILESIZE); 300 break; 301 } 302 case 7: 303 { 304 printf("退出配置\n"); 305 return; 306 } 307 default: 308 { 309 printf("输入有误\n"); 310 break; 311 } 312 } 313 printf("完毕\n"); 314 } 315 316 } 317 318 int main() 319 { 320 321 int Change = 0; 322 323 DCB dcb; 324 memset(&dcb, 0, sizeof(dcb)); 325 326 /* 327 将char[]类型转化成LPCWSTR类型 328 */ 329 330 WCHAR wszClassName[8]; 331 memset(wszClassName, 0, sizeof(wszClassName)); 332 MultiByteToWideChar(CP_ACP, 0, szStr, strlen(szStr) + 1, wszClassName, 333 sizeof(wszClassName) / sizeof(wszClassName[0])); 334 335 LPCWSTR lpFileName = _T("com3"); //= wszClassName; 336 337 /* 338 DCB结构配置 339 BauRate (波特率) 340 fParity (指定奇偶校验位) 341 Parity (校验方式) 342 ByteSize (数据位个数) 343 StopBits (停止位个数) 344 */ 345 printf("DCB结构正在默认配置..."); 346 dcb.DCBlength = sizeof(DCB); 347 dcb.BaudRate = 9600; 348 dcb.Parity = 2; 349 dcb.ByteSize = 8; 350 dcb.StopBits = ONESTOPBIT; 351 printf("完成\n"); 352 353 354 355 while (1) 356 { 357 printf("\n <Win串口读写程序>\n"); 358 printf("1.读取数据\n"); 359 printf("2.写入数据\n"); 360 printf("3.配置DCB结构体\n"); 361 printf("4.结束程序\n"); 362 printf(">> "); 363 scanf_s("%d", &Change); 364 if (Change == 1) 365 { 366 ReadFileContent(lpFileName,dcb); 367 } 368 else if (Change == 2) 369 { 370 WriteFileContent(lpFileName,dcb); 371 } 372 else if (Change == 3) 373 { 374 SetDcb(&dcb); 375 } 376 else if (Change == 4) 377 { 378 printf("程序结束\n"); 379 break; 380 } 381 else 382 printf("输入错误,请重新输入!\n"); 383 } 384 385 return 0; 386 }
目前时间紧迫,以后在做注释
参考文献
串口DCB结构体详解 :
https://blog.csdn.net/wangshubo1989/article/details/47746401
使用win32API实现windows下的一步串口通讯
https://www.cnblogs.com/icemencc/p/6098606.html
使用windowsAPI进行串口编程
https://www.cnblogs.com/milanleon/p/4244267.html
c语言中的串口读写功能实现
https://blog.csdn.net/mrsama/article/details/77140443