串口的操作一般分为打开串口、配置串口、读写串口和关闭串口

一、打开串口 CreateFile

函数原型:

HANDLE CreateFile(LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDistribution,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile);参数说明:
lpFileName:指向一个以NULL结束的字符串,该串指定了要创建、打开或截断的文件。
当用createFile打开串口时,这个参数可用”COM1“指定串口1,用”COM2“指定串口2。
dwDesiredAccess:指定对文件访问的类型,可以是读取、写入或二者并列(GENERIC_READ、GENERIC_WRITE)
dwShareMode:指定此文件可以怎样被共享,由于串口不能共享,因此是独占方式,即该参数必须置为0。
共享属性(FILE_SHARE_READ、FILE_SHARE_WRITE)
lpSecurityAttributes:定义安全性属性,一般不用,可设置为NULL;
dwCreationDistribution:定义文件创建方式,对串口操作必须置为OPEN_EXISTING(打开而不是创建);
dwFlagsAndAttributes:定义文件的属性和标志,用于指定该串口是否进行异步操作,
该值为FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,表示使用异步的I/O;
该值为0(FILE_ATTRIBUTE_NORMAL),表示同步I/O操作;
hTemplateFile:指向一个模板文件的句柄。串口无模板可言,因此对串口而言该参数必须置为NULL;
返回值:串口被成功打开时,返回其句柄,否则返回INVALID_HANDLE_VALUE(0XFFFFFFFF)

二、配置串口函数

1、_DCB说明
在打开通讯设备句柄后,常常需要对串口进行一些初始化配置工作,这需要通过一个DCB结构来进行。
DCB结构包含了诸如波特率、数据位数、奇偶校验和停止位数等信息。在查询或配置串口的属性时,都要用DCB结构来作为缓冲区。
一般用CreateFile打开串口后,可以调用GetCommState函数来获取串口的初始配置。要修改串口的配置,应该先修改DCB结构,然后再调用SetCommState函数设置串口。
DCB结构包含了串口的各项参数设置:

typedef struct _DCB{DWORD DCBlength;          //DCB结构体大小,即sizeof(_DCB),在调用SetCommState来更新DCB前必须作设置DWORD BaudRate;//波特率,指定通信设备的传输速率。这个成员可以是实际波特率值或者下面的常量值之一://CBR_110,CBR_300,CBR_600,CBR_1200,CBR_2400,CBR_4800,CBR_9600,CBR_19200,     //CBR_38400,CBR_56000, CBR_57600, CBR_115200, CBR_128000, CBR_256000DWORD fBinary:1;//指定是否允许二进制模式。Win32 API不支持非二进制模式传输,应设置为trueDWORD fParity:1;//指定是否允许奇偶校验。若此成员为1,允许奇偶校验检查,具体采用何种校验根据Parity成员的设置DWORD fOutxCtsFlow:1; //是否监控CTS(clear-to-send)信号来做输出流控(指定cts是否用于检测发送控制)。//当设置为true时:若CTS为低电平/off,则数据发送将被挂起,直至CTS变为高。 DWORD fOutxDsrFlow:1;//是否监控DSR (data-set-ready) 信号来做输出流控。//当设置为true时:若DSR为低电平,则数据发送将被挂起,直至DSR变为高。DSR的信号一般由DCE来控制DWORD fDtrControl:2;//DTR (data-terminal-ready)流控,可取值如下: //DTR_CONTROL_DISABLE 打开设备时置DTR信号为低电平,应用程序可通过调用EscapeCommFunction函数来改变DTR线电平状态 //DTR_CONTROL_ENABLE 打开设备时置DTR信号为高电平,应用程序可通过调用 EscapeCommFunction     函数来改变DTR线电平状态 //DTR_CONTROL_HANDSHAKE 允许DTR信号握手,此时应用程序不能调用EscapeCommFunction函数 DWORD fDsrSensitivity:1;// 当该值为TRUE时DSR为OFF时接收的字节被忽略DWORD fTXContinueOnXoff:1;//TRUE时,不管接收端是否Xoff, 本方发送端持续发送。//(也就是本方的发送端, 与本方接收端Xon/Xoff是相互独立的)。//若为False 时,则当接收端buffer 达到XoffLim时,发送端发送完Xoff字符后,就停止发送。 DWORD fOutX:1; //Xon和Xoff流量控制在发送时是否可用。//如果为true,当XOFF 值被收到的时候,发送停止;当 XON 值被收到的时候,发送继续。DWORD fInX:1; //Xon和Xoff流量控制在接收时是否可用。//如果为TRUE, 当输入缓冲区已接收满XoffLim 字节时,发送XOFF字符;//当输入缓冲区已经有XonLim 字节的空余容量时,发送XON字符 DWORD fErrorChar:1; //该值为TRUE,则用ErrorChar指定的字符代替奇偶校验错误的接收字符。DWORD fNull:1;//true时,接收时去掉空(0值)字节DWORD fRtsControl:2;//设置RTS (request-to-send)流控,若为0则缺省取 RTS_CONTROL_HANDSHAKE。可取值及其意义: //RTS_CONTROL_DISABLE 打开设备时置RTS信号为低电平,应用程序可通过调用EscapeCommFunction函数来改变RTS线电平状态 //RTS_CONTROL_ENABLE 打开设备时置RTS信号为高电平,应用程序可通过调用EscapeCommFunction函数来改变RTS线电平状态 //RTS_CONTROL_HANDSHAKE 允许RTS信号握手,此时应用程序不能调用EscapeCommFunction函数。 //当输入缓冲区已经有足够空间接收数据时,驱动程序置RTS为高以允许DCE来发送;反之置RTS为低以阻止DCE发送数据。 //RTS_CONTROL_TOGGLE 有字节要发送时RTS变高,当所有缓冲字节已被发送完毕后,RTS变低。DWORD fAbortOnError:1;//true时,当发生错误时停止读写DWORD fDummy2:17;//保留,未启用WORD wReserved;//未启动,必须设置为0WORD XonLim;//在XON字符发送前接收缓冲区内可允许的最小字节数。//当接收Buffer中的字符减少到XonLim规定的字符数, 就发送Xon字符,让对方继续发送。WORD XoffLim;//在XOFF字符发送前接收缓冲区内可允许的最大字节数。//当接收Buffer达到XoffLim规定的字符数, 就发送Xoff字符, 让对方停止发送BYTE ByteSize;//通信数据位数,4-8BYTE Parity;//指定奇偶校验方法。此成员可以有下列值://EVENPARITY 偶校验 //NOPARITY 无校验//MARKPARITY 标记校验 //ODDPARITY 奇校验BYTE StopBits;//指定停止位的位数。此成员可以有下列值://ONESTOPBIT 1位停止位 //TWOSTOPBITS 2位停止位//ONE5STOPBITS 1.5位停止位char XonChar;//指定Xon字符char XoffChar;//指定Xoff字符char ErrorChar;//指定ErrorChar字符,奇偶校验发生错误时使用的字节//(本字符用来代替接收到的奇偶校验发生错误时的值)char EofChar;//EOF替代字符(当没有使用二进制模式时,用来标识数据结束的字符)char EvtChar;//事件触发字符,即接收到此字符时会产生一个事件WORD wReserved1;//保留,未启用
}DCB;

注:
1)流控分为硬件流控和软件流控。其中:硬件流控分为rts/cts和dtr/dsr两种,软件流控分为Xon/Xoff。
2)软件流控Xon/Xoff相关的参数:fOutX、fInX、XonLim、XoffLim、XonChar、XoffChar
fOutX:发送端支持Xon/Xoff。收到Xoff停止发送,收到Xon重新开始
fInX:接收端支持Xon/Xoff。当FIFO中字节超过XoffLim时发送Xoff, 当FIFO中少于XonLim时发送Xon
XonLim:当接收Buffer中的字符减少到XonLim规定的字符数, 就发送Xon字符,让对方继续发送
XoffLim:接收Buffer达到XoffLim规定的字符数, 就发送Xoff字符, 让对方停止发送
XonChar:Xon 字符
charXoffChar:Xoff 字符
fTXContinueOnXoff:;TRUE时,不管接收端是否Xoff, 本方发送端持续发送。 (也就是本方的发送端, 与本方接收端Xon/Xoff是相互独立的)。
若为False 时,则当接收端buffer 达到XoffLim时,发送端发送完Xoff字符后,就停止发送
3)DTR/DSR硬件流控:
3.1)fOutxDsrFlow:true时,支持DSR流控制。当DSR为off时,停止发送
3.2)fDtrControl:DTR设置,有如下值:
fDTRControlDTR_CONTROL_Disable:使DTR为off
DTR_CONTROL_Enable:使DTR为on
DTR_CONTROL_HANDSHAKE:DTR硬件流控
3.3)fDsrSensitivity:true时,当DSR为OFF,则接收端忽略所有字符。
4)RTS/CTS硬件流控:
4.1)fOutxCtsFlow:true时,支持ctsl流控制,当cts为off时,停止发送
4.2)fRtsControl:rts设置,有如下值:
fRTSControlRTS_CONTROL_DISABLE:使RTS保持 off
RTS_CONTROL_ENABLE:使RTS保持on
RTS_CONTROL_HANDSHAKE:RTS硬件流控
RTS_CONTROL_TOGGLE:485通讯RTS自动流控

2、GetCommState 和 SetCommState函数
函数原型:
BOOL GetCommState(HANDLE hFile, LPDCB lpDCB);
BOOL SetCommState(HANDLE hFile, LPDCB lpDCB);
获得/设置COM口的设备控制块,从而获得相关参数。
参数说明:
hFile:标识通讯端口的句柄
lpDCB:指向一个设备控制块(DCB结构)的指针

3、SetupComm函数
函数原型:
BOOL SetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue);
设置串行口的输入和输出缓冲区的大小
hFile:通信设备的句柄
dwInQueue:输入缓冲区的大小(字节数)
dwOutQueue:输出缓冲区的大小(字节数)
注:
除了在BCD中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。Windows用I/O缓冲区来暂存串口输入和输出的数据。
如果通信的速率较高,则应该设置较大的缓冲区。调用SetupComm函数可以设置串行口的输入和输出缓冲区的大小。

4、GetCommTimeouts和SetCommTimeouts函数
函数原型:
BOOL GetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts);
BOOL SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts);
参数说明:
hFile:通信设备的句柄
lpCommTimeouts:设置的超时时间
查询/设置当前的超时设置,该函数会填充一个COMMTIMEOUTS结构。
超时的作用是在指定的时间内没有读入或发送指定数量的字符,ReadFile或WriteFile的操作仍然会结束。
读写串口的超时有两种:间隔超时和总超时。
间隔超时是指在接收时两个字符之间的最大时延。总超时是指读写操作总共花费的最大时间。写操作只支持总超时,而读操作两种超时均支持。用COMMTIMEOUTS结构可以规定读写操作的超时。
COMMTIMEOUTS结构的成员都以毫秒为单位。
COMMTIMEOUTS结构定义为

typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout; //读间隔超时
DWORD ReadTotalTimeoutMultiplier; //读时间系数
DWORD ReadTotalTimeoutConstant; //读时间常量
DWORD WriteTotalTimeoutMultiplier; // 写时间系数
DWORD WriteTotalTimeoutConstant; //写时间常量
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

注:
总超时的计算公式:
总超时=时间系数×要求读/写的字符数+时间常量
例如,要读入10个字符,那么读操作的总超时的计算公式为:
读总超时=ReadTotalTimeoutMultiplier×10+ReadTotalTimeoutConstant
注:
1)间隔超时和总超时的设置是不相关的
2)写操作只支持总超时,而读操作两种超时均支持

5、PurgeComm函数
函数原型:
BOOL PurgeComm(HANDLE hFile, DWORD dwFlags);
清空缓冲区
参数说明:
hFile:通信设备的句柄
dwFlags:需要完成的操作,可以是下列值的组合:
PURGE_TXABORT 中断所有写操作并立即返回,即使写操作还没有完成。
PURGE_RXABORT 中断所有读操作并立即返回,即使读操作还没有完成。
PURGE_TXCLEAR 清除输出缓冲区
PURGE_RXCLEAR 清除输入缓冲区

6、EscapeCommFunction函数
函数原型:
BOOL EscapeCommFunction( HANDLE hFile, DWORD dwFunc);
可将硬件信号置ON或OFF,模拟XON或XOFF
参数说明:
hFile:通信设备的句柄
dwFunc 事件掩码:
CLRDTR DTR置OFF
CLRRTS RTS置OFF
SETDTR STR置ON
SETRTS TRS置ON
SETXOFF 模拟XOFF字符的接收
SETXON 模拟XON字符的接收
SETBREAK 在发送中产生一个中止
CLRBREAK 在发送中清除中止

7、ClearCommError函数
函数原型:
BOOL ClearCommError(HANDLE hFile, LPDWORD lpErrors,LPCOMSTAT lpStat);
清除串行端口错误、读取串行端口现在的状态(清除串口的错误标志以便继续输入、输出操作),Windows系统利用此函数清除硬件的通讯错误以及获取通讯设备的当前状态。
参数说明:
hFile:通信设备的句柄
lpErrors:接收错误代码变量的类型,错误常数如下:
CE_BREAK:检测到中断信号
CE_DNS:Windows95专用,未被选择的并行端口
CE_FRAME:帧错误
CW_IOE:一般I/O错误,常伴有更为详细的错误标志
CE_MODE:不支持请求的模式
CE_OVERRUN:缓冲区超限下一个字符将丢失
CE_RXOVER:接收缓冲区超限
CE_RXPARITY:奇偶校验错误
CE_TXFULL:发送缓冲区满
CE_DNS:没有选择并行设备
CE_PTO:并行设备发生超时
CE_OOP:并行设备缺纸
lpStat:通信状态缓冲区的指针,指向一个COMSTAT结构,该结构返回串口状态信息。
COMSTAT结构包含串口的信息,结构定义如下:

typedef struct _COMSTAT { // cst DWORD fCtsHold : 1; // Tx waiting for CTS signal(为真时,等待cts信号开启传输)DWORD fDsrHold : 1; // Tx waiting for DSR signal (为真时,等待dsr信号时开启传输)DWORD fRlsdHold : 1; // Tx waiting for RLSD signal DWORD fXoffHold : 1; // Tx waiting, XOFF char rec’’d (为真时,等待接收到xoff时开始传输)DWORD fXoffSent : 1; // Tx waiting, XOFF char sent DWORD fEof : 1; // EOF character sent (为真时,eof字符可以被收到)DWORD fTxim : 1; // character waiting for Tx DWORD fReserved : 25; // reserved (保留)DWORD cbInQue; // bytes in input buffer //串口接收缓冲区的字节数,它们还没有来得及被ReadFile操作读走DWORD cbOutQue; // bytes in output buffer  //串口发送缓冲区的字节数
}

8、GetCommMask和SetCommMask函数
函数原型:
BOOL GetCommMask(HANDLE hFile, LPDWORD lpEvtMask);
BOOL SetCommMask(HANDLE hFile, DWORD dwEvtMask);
设置/获取监听事件
参数说明:
hFile:通信设备的句柄
EvtMask:事件掩码,标识将被监视的通信事件。如果该参数设置为0,则表示禁止所有事件。如果不为0,则掩码可为如下:

EV_BREAK 检测到输入为止
EV_CTS CTS(清除发送)信号改变状态
EV_DSR DSR(数据设置就绪)信号改变状态
EV_ERR 发生了线路状态错误.
CE_FRAME(帧错误)
CE_OVERRUN(接收缓冲区超限)
CE_RXPARITY(奇偶校验错误)
EV_RING 检测到振铃
EV_RLSD RLSD(接收线路信号检测)信号改变状态
EV_EXCHAR 接收到一个字符,并放入输入缓冲区
EV_RXFLAG 接收到事件字符(DCB成员的EvtChar成员),度放入输入缓冲区
EV_TXEMPTY 输出缓冲区中最后一个字符发送出去
//在用SetCommMask指定了有用的事件后,应用程序可调用WaitCommEvent()来等待事件发生.

9、WaitCommEvent函数
函数原型:
BOOL WaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped);
等待被监控事件发生
参数说明:
hFile:通信设备的句柄
lpEvtMask:指向一个32位变量,接收事件掩模,标识所发生的通信事件属于何种类型
lpOverlapped:指向一个OVERLAPPED结构,如果打开hFile表示的通信设备时,指定FILE_FLAG_OVERLAPPED标志,则该参数被忽略。如果不需要异步操作,则这个参数不用设置。

三、串口读写函数
1、读函数
函数原型:
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
读串口数据
参数说明:
hFile:串口的句柄
lpBuffer:读入的数据存储的地址,即读入的数据将存储在以该指针的值为首地址的一片内存区
nNumberOfBytesToRead:要读入的数据的字节数
lpNumberOfBytesRead:指向一个DWORD数值,该数值返回读操作实际读入的字节数
lpOverlapped:重叠(异步)操作时,该参数指向一个OVERLAPPED结构;同步操作时,该参数为NULL。

2、写函数
函数原型:
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped);
写串口函数
函数说明:
hFile:串口的句柄
lpBuffer:即以该指针的值为首地址的nNumberOfBytesToWrite个字节的数据将要写入串口的发送数据缓冲区。
nNumberOfBytesToWrite:将要写入的数据的字节数
lpNumberOfBytesWritten:指向一个DWORD数值,该数值返回实际写入的字节数
lpOverlapped:重叠(异步)操作时,该参数指向一个OVERLAPPED结构,同步操作时,该参数为NULL。

OVERLAPPED用于记录了当前正在操作的文件一些相关信息,OVERLAPPED结构说明:
typedef struct _OVERLAPPED {DWORD Internal;//保存已处理的I/O请求的错误码/状态码DWORD InternalHigh;//当异步I/O请求完成的时候,这个成员用来保存已传输的字节数。DWORD Offset;//该文件的位置是从文件起始处的字节偏移量。调用进程设置这个成员之前调用ReadFile或WriteFile函数。当读取或写入命名管道和通信设备时这个成员被忽略设为零。DWORD OffsetHigh;//指定文件传送的 字节 偏移量的高位字。当读取或写入命名管道和通信设备时这个成员被忽略设为零。HANDLE hEvent;//在转移完成时处理一个事件设置为有信号状态。//调用进程集这个成员在调用ReadFile、 WriteFile、TransactNamedPipe、 ConnectNamedPipe函数之前。
} OVERLAPPED;

3、GetOverlappedResult函数
函数原型:
BOOL WINAPI GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait);
根据OVERLAPPED结构来获取重叠操作的状态/结果,用来判断异步操作是否完成,它是通过判断OVERLAPPED结构中的hEvent是否被置位来
参数说明:
hFile:串口的句柄
lpOverlapped:指向重叠操作开始时指定的OVERLAPPED结构
lpNumberOfBytesTransferred:指向一个32位变量,该变量的值返回实际读写操作传输的字节数
bWait:该参数用于指定函数是否一直等到重叠操作结束。如果该参数为TRUE,函数直到操作结束才返回;
如果该参数为FALSE,函数直接返回,这时如果操作没有完成,通过调用GetLastError()函数会返回ERROR_IO_INCOMPLETE。

注:
1)ReadFile函数只要在串口输入缓冲区中读入指定数量的字符,就算完成操作;而WriteFile函数不但要把指定数量的字符拷入到输出缓冲区,而且要等这些字符从串行口送出去后才算完成操作。
2)如果成功,两个函数都返回TRUE。当ReadFile和WriteFile返回FALSE时,不一定就是操作失败,线程应该调用GetLastError函数分析返回的结果。
例如,在重叠操作时如果操作还未完成函数就返回,那么函数就返回FALSE,而且 GetLastError函数返回ERROR_IO_PENDING,这说明重叠操作还未完成。
3)在使用ReadFile和WriteFile重叠操作时,线程需要创建OVERLAPPED结构以供这两个函数使用。线程通过OVERLAPPED结构获得当前的操作状态,该结构最重要的成员是hEvent。
hEvent是读写事件。当串口使用异步通讯时,函数返回时操作可能还没有完成,程序可以通过检查该事件得知是否读写完毕。
当调用ReadFile, WriteFile 函数的时候,该成员会自动被置为无信号状态;当重叠操作完成后,该成员变量会自动被置为有信号状态。

wince 串口 编程相关推荐

  1. Wince C++串口编程

    C# 串口操作系列:http://blog.csdn.net/wuyazhe/article/category/695097 在windows程序设计与开发过程中,特别是涉及到开发嵌入式软硬件系统时, ...

  2. 【linux】串口编程(三)——错误处理

    一个程序的优劣,可以从多个角度来判断,错误处理就是其中之一.从代码中的错误处理部分,可以体现出一个程序员的水平和修养. 下面还是以libmodbus为例,总结下串口编程中的错误处理. [1]基础 [1 ...

  3. 【linux】串口编程(一)——配置串口

    目前遇到的串口编程都是用于通信,很少作为终端显示.以前没有对串口编程做深入研究,本次以libmodbus源码中对串口的设置为例,详解总结串口编程时配置的属性(struct termios) 以libm ...

  4. QT开发(五十)——QT串口编程基础

    QT开发(五十)--QT串口编程基础 一.QtSerialPort简介 1.串口通信基础 目前使用最广泛的串口为DB9接口,适用于较近距离的通信.一般小于10米.DB9接口有9个针脚. 串口通信的主要 ...

  5. 【C#串口编程计划】C#通讯类库构建

    这篇图文是关于[串口编程计划]的最后一篇"C#通讯类库的构建",也就是把这次所做的关于串口系统的代码集成到团队的类库中,做到代码的可复用(以后写串口的系统,只需要写数据的定义,协议 ...

  6. 【C#串口编程计划】通信协议解析 -- byte[]与常用类型的转换

    刚刚完成一个串口通讯的系统.目前在把串口通信的代码整合到团队的类库中(把串口通信与网口Soket通讯整合起来,后面只需要配置参数,就可实现网络与串口通讯的转换),故C#串口编程计划的最后一篇图文&qu ...

  7. 【C#串口编程计划】串口编程简介

    介绍C#串口编程的基本知识.

  8. VirtualBox Ubuntu虚拟机串口编程

    VirtualBox Ubuntu虚拟机串口编程 此文适用于Ubuntu虚拟机实现串口通信,可以在虚拟机上运行程序,直接将windows下的串口映射到虚拟机上即可.在网上找了半天,没有找到合适的教程, ...

  9. UART0串口编程(五):串口编程(UART0)之UC/OS(一)UC/OS下的串口发送任务编程

    UART0串口编程(五) 串口编程(UART0)之UC/OS(一) 一.在UC/OS中设计串口程序所要考虑的问题 1.     串口通信数据以帧为单位进行处理,如果需要接收大量数据,则帧缓冲区规模必然 ...

最新文章

  1. git:Git fetch和git pull的区别, 解决Git报错:error: You have not concluded your merge (MERGE_HEAD exists)....
  2. 用dw中html设置背景,Dreamweaver 教程-CSS背景属性(background)
  3. CuteBot智能小车
  4. vb字符串在内存中的分布?
  5. Java虚拟机——Java内存区域与内存溢出
  6. datagrid wpf 刷新数据_c# – WPF Datagrid-自动刷新
  7. 02-24 面向对象--方法重载、隐藏
  8. 2021牛客第一场 K.Knowledge Test about Match
  9. Android 为应用添加默认加载页
  10. Struts2之Crud综合实例
  11. 关于多线程的几个问题
  12. c语言case后接printf,C编程中switch。case 问题
  13. BIOS中未启用虚拟化支持系列~~例如:因此无法安装Hyper-V
  14. 简单的扫雷游戏代码(c++)
  15. 基于Springboot+Vue+ElementUI物流配送管理系统
  16. 【薪酬调研报告】2019TMT标杆企业高管薪酬与激励调研报告—德勤管理咨询
  17. iTunes12.9以上 自定义铃声 无法拖入 无法添加
  18. SOAR:软件定义安全之编排篇
  19. 阿里云企业版云服务器如何选择及部署策略
  20. 西方世界的劫难Ⅳ:真神的国度--十大支线攻略

热门文章

  1. java绘制五子棋棋盘
  2. Flink的流处理与批处理
  3. 十大经典排序算法动图图解
  4. 手机上有哪些可以记录生日倒计时天数的软件?
  5. 台式电脑共享笔记本电脑的无线网络
  6. Datawhale组队学习NLP之transformer Task03 BERT
  7. 我为何在 CSDN 乐在其中
  8. 3d建模师就业前景?
  9. 韩松手机摄影笔记第八课--手机人物摄影
  10. 像素(px)与厘米的关系