用delphi实现串口通信的原理及用例,请多指教!!!!
(1) 打开串口
CreateFile( LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDistribution,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);
lpFileName:将要打开的串口逻辑名,如“COM1”;
dwDesiredAccess:指定串口访问的类型,可以是读取、写入或二者并列;
dwShareMode:指定共享属性,由于串口不能共享,该参数必须置为0;
lpSecurityAttributes:引用安全性属性结构,缺省值为NULL;
dwCreationDistribution:创建标志,对串口操作该参数必须置为OPEN_EXISTING;
dwFlagsAndAttributes:属性描述,用于指定该串口是否进行异步操作,该值为FILE_FLAG_OVERLAPPED,表示使用异步的I/O;该值为0,表示同步I/O操作;
hTemplateFile:对串口而言该参数必须置为NULL;
(2) 配置串口
GetCommState函数可以获得COM口的设备控制块,从而获得相关参数
SetCommState函数设置COM口的设备控制块
例:
procedure TForm1.OpenComm;
var
cc:TCOMMCONFIG;
Temp:string;
begin
Temp:='COM'+inttostr(rg1.ItemIndex+1);
hComm:=CreateFile(PChar(Temp), GENERIC_READ or GENERIC_WRITE,
0, nil, OPEN_EXISTING, 0, 0); // 打开COM
if (hComm = INVALID_HANDLE_VALUE) then begin // 如果COM 未打开
MessageBox (0, '打开通信端口错误!!','',MB_OK);
exit;
end;
GetCommState(hComm,cc.dcb); // 得知目前COM 的状态
cc.dcb.BaudRate:=CBR_1200; // 设置波特率为9600
cc.dcb.ByteSize:=8; // 字节为 8 bit
cc.dcb.Parity:=EVENPARITY; // Parity 为 None
cc.dcb.StopBits:=ONESTOPBIT; // 1 个Stop bit
if not SetCommState(hComm, cc.dcb) then begin// 设置COM 的状态
MessageBox (0, '通信端口设置错误!!!','',MB_OK);
CloseHandle(hComm);
exit;
end;
end;
(3) 读写串口
在读写串口之前,还要用PurgeComm()函数清空缓冲区,
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
BOOL PurgeComm(
HANDLE hFile, //串口句柄
DWORD dwFlags // 需要完成的操作);
参数dwFlags指定要完成的操作,可以是下列值的组合:
PURGE_TXABORT 中断所有写操作并立即返回,即使写操作还没有完成。
PURGE_RXABORT 中断所有读操作并立即返回,即使读操作还没有完成。
PURGE_TXCLEAR 清除输出缓冲区
PURGE_RXCLEAR 清除输入缓冲区
ReadFile(HANDLE hFile, //串口的句柄LPVOID lpBuffer, // 读入的数据存储的地址,// 即读入的数据将存储在以该指针的值为首地址的一片内存区
DWORD nNumberOfBytesToRead, // 要读入的数据的字节数
LPDWORD lpNumberOfBytesRead, // 指向一个DWORD数值,该数值返回读操作实际读入的字节数
LPOVERLAPPED lpOverlapped // 重叠操作时,该参数指向一个OVERLAPPED结构,同步操作时,该参数为NULL。);
例:
procedure TForm1.btn4Click(Sender: TObject);
var
// Temp, Templist: string;
inbuff: array[0..2047] of Char;
nBytesRead, dwError:LongWORD ;
cs:TCOMSTAT;
i: Integer;
pUDPBufferHead : recUDPPG;
NumberBytes : Integer;
Buffer:Array [0..9999] of char;
begin
// Templist := '';
ClearCommError(hComm,dwError,@CS); //取得状态
// 数据是否大于我们所准备的Buffer
if cs.cbInQue > sizeof(inbuff) then begin
PurgeComm(hComm, PURGE_RXCLEAR); // 清除COM 数据
exit;
end;
ReadFile(hComm, pUDPBufferHead,cs.cbInQue,nBytesRead,nil); // 接收COM 的数据
// pUDPBufferHead:=pUDPPG(@Buffer);
if (pUDPBufferHead.wType=1) or (pUDPBufferHead.wType=17) then //模拟量包
begin
for i:=0 to (pUDPBufferHead.wLen div 8)-1 do //把一包发过来的所有测点写入内存
begin
mmo1.Lines.Add(FloatToStr(pANA(Integer(@pUDPBufferHead.bydata)+i*SizeOf(recANA)).GID)+'='+FloatToStr(pANA(Integer(@pUDPBufferHead.bydata)+i*SizeOf(recANA)).Value));
end;
end;
end;
(4) 关闭串口
SetCommMask(hcomm,$0);
CloseHandle(hComm);


档案
日志
相册
视频



评论
想第一时间抢沙发么?