#Requires AutoHotkey v2.0
ComHandle := ComOpen("COM3", 115200, "N", 8, 1) ; 1 stop bit
;ComHandle := ComClose(ComHandle)
ComWriteHex(ComHandle, "01 05 00 00 ff 00 8C 3A") ;16进制发送
;ComWriteString(ComHandle, "hello") ;字符串发送
Sleep(200) ;延迟200毫秒
MsgBox(ComReadByte(ComHandle)) ;接收
return
; NOTE: See the Changelog at the end of this file.
;###############################################################################
;###############################################################################
; COM Library Subroutines. This uses the Win32 API even with 64-bit Win & AHK.
; (other DLL calls that could be useful: EscapeCommFunction, GetCommModemStatus)
;###############################################################################
;###############################################################################
;###############################################################################
; COM Open Subroutine
; This opens a COM Port returns a COM Port File Handle. If unsuccessful,
; this returns a null (""). Port is COM1, COM2, ..., COM10, COM11, etc.
; Baud is 9600 for example. What bauds work depends on the COM hardware.
; Parity is N, E, O, M, S. Stop is 1, 2, maybe others.
; Settings for handshake lines and flow control could also be added.
;###############################################################################
ComOpen(Port, Baud, Parity, Data, Stop)
{
;MsgBox("Port=" Port " Baud=" Baud " Parity=" Parity " Data=" Data " Stop=" Stop)
COM_Settings := Port " baud=" Baud " parity=" Parity " data=" Data " stop=" Stop
;###### Build COM DCB ######
DCB := Buffer(90) ;Create the DCB structure (actually 40 words, 80 bytes long)
BCD_Result := DllCall("BuildCommDCB"
, "str", COM_Settings
, "ptr", DCB)
If (BCD_Result != 1)
Return (MsgBox("Error opening port '" Port "' using BuildCommDCB"), "")
;###### Extract/Format the COM Port Number ######
;7/23/08 Thanks krisky68 for finding/solving the bug in which COM Ports
; greater than 9 didn't work.
;For COM Ports > 9 \\.\ needs to prepended to the COMn name.
;So the valid names are ... COM8 COM9 \\.\COM10 \\.\COM11 ...
If (StrLen(Port) > 4)
Port := "\\.\" . Port
;###### Create COM File Handle ######
ComFileHandle := DllCall("CreateFile"
, "Str", Port
, "UInt", 0xC0000000
, "UInt", 3
, "UInt", 0
, "UInt", 3
, "UInt", 0
, "UInt", 0
, "Int")
If (ComFileHandle < 1)
Return (MsgBox("Error opening port '" Port "' using CreateFile"), "")
;###### Set COM State (Port number, baud rate, etc.) ######
SCS_Result := DllCall("SetCommState", "UInt", ComFileHandle, "ptr", DCB)
If (SCS_Result != 1)
Return (MsgBox("Error opening port '" Port "' using SetCommState"),
ComClose(ComFileHandle))
;###### Set the COM Timeouts ######
Data := Buffer(20, 0) ; 5 * sizeof(DWORD)
NumPut("UInt", 0xffffffff, Data, 0) ; ReadIntervalTimeout
NumPut("UInt", 0x00000000, Data, 4) ; ReadTotalTimeoutMultiplier
NumPut("UInt", 0x00000000, Data, 8) ; ReadTotalTimeoutConstant
NumPut("UInt", 0x00000000, Data, 12) ; WriteTotalTimeoutMultiplier
NumPut("UInt", 0x00000000, Data, 16) ; WriteTotalTimeoutConstant
SCT_result := DllCall("SetCommTimeouts", "UInt", ComFileHandle, "ptr", Data)
If (SCT_result != 1)
Return (MsgBox("Error opening port '" Port "' using SetCommTimeouts"),
ComClose(ComFileHandle))
Return ComFileHandle
}
;###############################################################################
; COM Close Subroutine
; This closes the COM port. It returns a null-string.
;###############################################################################
ComClose(ComFileHandle)
{
If (!ComFileHandle)
{
;MsgBox("Error: Cannot close COM port because it is already closed!")
Return ""
}
If (DllCall("CloseHandle", "UInt", ComFileHandle) != 1)
Return (MsgBox("Error closing COM port using CloseHandle"), "")
Return ""
}
;###############################################################################
; COM Write Byte Subroutine
; This writes a byte to ComFileHandle. This returns 1 for error and 0 for OK.
; If this is passed a string to write, the string cotents will be interpreted
; as a number (as opposed to using the first character's ordinal value/code).
;###############################################################################
ComWriteHex(ComFileHandle, Message)
{
If (!Message || !ComFileHandle)
Return 0
Message := StrReplace(RegExReplace(Message, "(\w+)", "0x$1"), A_Space, ",") ;将报文变为"0x24,0x01,0x04,0x01"这种格式
;MsgBox Message
Byte:=StrSplit(Message, ",",".") ; 忽略句点.
Data := Buffer(600, 0) ; 5 * sizeof(DWORD)
loop(Byte.Length)
{
NumPut("UChar", Byte[A_Index], Data, A_Index -1) ; ReadIntervalTimeout
}
Size:=Byte.Length
Bytes_Sent := 0 ; this prevents unset variable error
Null_Var := 0 ; not used by the Win32 API
WF_Result := DllCall("WriteFile" ; send message to COM port
, "UInt", ComFileHandle
, "ptr", Data
, "UInt", Size
, "UInt*", &Bytes_Sent
, "Int", Null_Var)
If (WF_Result != 1 || Bytes_Sent != Size)
Return (MsgBox("Error writing COM port using WriteFile, "
Bytes_Sent " of 1 bytes sent"), 1)
Return 0
}
;###############################################################################
; COM Write String Subroutine
; This writes string "Message" to COM port "ComFileHandle".
; This returns 1 for error and 0 for OK.
; NOTE: At this time, AutoHotkey v2 strings are always UTF-16.
; This handles character codes 1-127 for sure. Not so sure about 0 & 128+.
;###############################################################################
ComWriteString(ComFileHandle, Message)
{
If (!Message || !ComFileHandle)
Return 0
Size := StrPut(Message, "") ; convert Messge from UTF-16 to bytes
Buff := Buffer(Size)
StrPut(Message, Buff, "")
Size := Size - 1 ; don't treat the null terminator as data to output
;msgbox("Byte_Size=" Size " String=" Message)
Bytes_Sent := 0 ; this prevents unset variable error
Null_Var := 0 ; not used by the Win32 API
WF_Result := DllCall("WriteFile" ; send message to COM port
, "UInt", ComFileHandle
, "ptr", Buff
, "UInt", Size
, "UInt*", &Bytes_Sent
, "Int", Null_Var)
If (WF_Result != 1 || Bytes_Sent != Size)
Return (MsgBox("Error writing COM port using WriteFile, "
Bytes_Sent " of 1 bytes sent"), 1)
Return 0
}
;###############################################################################
; COM Read Byte Subroutine
; This reads/returns a byte from COM port "ComFileHandle" or -1 if no data is
; available or there's an error. The return value ranges from 0 to 255
; (0x00 to 0xff), or -1 if there's no data available or there's an error.
; NOTE: At this time, AutoHotkey v2 strings are always UTF-16, so this doesn't
; use strings at all.
;###############################################################################
ComReadByte(ComFileHandle)
{
If (!ComFileHandle)
Return -1
Buff := Buffer(4000) ; bigger than needed
Bytes_Received := 0 ; this prevents unset variable error
RF_Result := DllCall("ReadFile"
, "UInt", ComFileHandle
, "ptr", Buff
, "Int", 0XFF
, "UInt*", &Bytes_Received
, "Int", 0)
;MsgBox("Bytes_Received=" Bytes_Received) ;返回的字节数
If (RF_Result != 1)
Return (MsgBox("Error reading COM port using ReadFile, "
Bytes_Received " bytes received"), -1)
If (0 == Bytes_Received)
Return -1
RR:=""
loop(Bytes_Received)
{
RR .= Format("{:02}",Format("{1:X}", NumGet(Buff, A_Index -1, "uchar")))
}
Return RR
}
/*
CHANGELOG FOR AUTOHOTKEY v2 COM LIBRARY
2023-08-28 v1.0 initial release (used AHK v2.0.5)
*/
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。

评论(0)