| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 Win95的串行通信机制及串口查询法的原理 常用的DOS系统主要是工作在响应中断方式。PC机串行通信程序大多利用其BIOS块的INT14H中断,以查询串口的方式完成异步串行通信。
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Private Function OpenThePort(cPort as String,cBaud as String,cParity as String,cData as String,tStops asString)As Boolean ’ 打开串口的子过程 Dim lResult as Long Dim lHandle as Long Dim DCB_COMM as DCB Dim cDCBConfig as String lHandle = CreateFile(cPort,GENERIC_READ Or GENERIC_WRITE, 0&,0&,OPEN_EXISTING,0&,0&) If lHandle = -1 Then ’打开串口失败 OpenThePort = False MsgBox “串口可能正被其他应用程序占用!” lResult = CloseHandle(lHandle) ’先关闭串口后再打开 If lResult = 0 Then OpenThePort Exit Function End If End If cDCBConfig.band = 2400 ’设置DCB cDCBConfig.parity = None cDCBConfig.data = 8 cDCBConfig.stop = 1 lResult = BuildCommDCB(cDCBConfig,DCB_COMM) ’按用户设定配置一个DCB结构 If lResult = 0 Then OpenThePort = False MsgBox “无法建立DCB设备控制块” Exit Function End If lResult = SetCommState(lHandle,DCB_Comm) ’实际设置一个串口的DCB If lResult = 0 Then OpenThePort = False MsgBox “无法建立DCB设备控制块” Exit Function End If OpenThePort = True End Function Private Sub SendHand ( ) ’发送握手信号的子过程 Dim Nchars As Long Static Readbuff As String * 1 Static Writebuff As String * 1 Dim lpDCB As DCB Dim lRet As Long Dim lHandle As Long Dim lpOverlapped As OVERLAPPED Dim RNum As Integer MsgBox “请把读卡器插在串口2上!”, 48,“提示窗口” lHandle = OpenThePort(COMM1,2400,None,8,1) lRet = PurgeComm( lHandle,1 ) ’清输出缓冲区 lRet = PurgeComm( lHandle,0 ) ’清输入缓冲区 lRet = GetCommState ( lHandle,lpDCB ) ’获得通讯口的状态 Shand: Writebuff$= Chr$(&H8F) lRet = WriteFile (lHandle,Writebuff$,1,Nchars,lpOverlapped ) ’送握手信号入串口缓冲区 If lRet <= 0 Then MsgBox “发送操作出错,卡握手信号未发送成功”, 16 GoTo Shand ’不成功则重发 Else GoTo Qtest End If GoTo Shand Qtest: Readbuff$ =“ ” ’清除缓冲区为空 Do While lHandle ’循环查询串口 RNum = 0 ’设置读串口次数的指针为0 ReadAgain: lRet = ReadFile( lHandle, Readbuff$,1,Nchars,lpOverlapped ) If lRet < 0 Then MsgBox “读取应答信号时出错”, 16 End If If lRet = 0 Then If RNum > 1000 Then ’只读1000次串口,以免陷入死循环 MsgBox "卡没有插接好或卡没有接在串口上!" GoTo CloseP End If RNum = RNum + 1 GoTo ReadAgain End If If Hex$(Asc(Readbuff)) <> Hex$(&HFF) Then GoTo Shand ’回送码不正确则返回继续发送握手信号 Else Label1.Caption = “握手信号是:” +Hex$(Asc(Readbuff$)) Msgbox “握手信号正确,已正确联机” GoTo CloseP End If Loop CloseP:lRet = CloseHandle( lHandle ) If lRet = 0 Then MsgBox “串行通讯口关闭成功”, 48,“提示窗口” End If End Sub 这里要注意的是:当PC机与单片机系统通信时,单片机数据存储区( RAM )内的数据是十六进制,在信号线上传输的是十六进制数的ASCII码的二进制形式;而Windows系统下使用的是ANSI码,ANSI码仅在前126个与ASCII码相同。即在Win95下接收到的是十六进制数的ASCII码的字符串,可先转换为ANSI码后再在Win95下还原为十六进制数。 6 结束语 以上的软硬件在我们的实践中达到了较为理想的效果。通过软件节省了硬件的开销,并通过在PIC16F84单片机系统和PC机双方的通信软件内增加握手信号,达到了软件数据校验的目的,获得了较高的通信可靠性。 参 考 文 献 1 MICROCHIP CO. PIC16/17 MICROCO-NTROLLER DATA BOOK. 1995/1996 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||