#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)