您当前的位置:五五电子网电子知识单片机-工控设备综合-其它PIC16系列单片机与PC机串行通信的软硬件实现 正文
PIC16系列单片机与PC机串行通信的软硬件实现

PIC16系列单片机与PC机串行通信的软硬件实现

点击数:7479 次   录入时间:03-04 11:47:46   整理:http://www.55dianzi.com   综合-其它

由于这种方法主要工作在查询方式。程序员必须完成相当一部分通信状态的检测工作,许多细节(甚至包括通信过程中的字符属性的转换)也必须通过程序代码完成。这种查询方法对通信双方协议的依赖性尤其大。双方通信协议的约定对程序实现的难易程度影响很大。
串口查询法中,一般串口初始化的流程如图5。
值得注意的一点是,此方法下协议的约定必须满足以下条件:即甲方发送时,乙方必须在甲方发送动作之前进入循环接收状态,直到接收到字符后通过对串口读取函数ReadFile返回值的判断跳出循环状态。
同时,一般为了不使系统因循环等待接收而进入“死循环”状态,可以人为设置读取串口的循环次数,一般1000~10000次即可。
本程序的实现平台是VB4,这是一种极为灵活的高级语言,它可以方便地引入汇编语言的思维,利用其GoTo转向语句方便地控制程序的流程,灵活方便。

5 PC机内通信程序的实例

现约定甲方是PC机,乙方是单片机系统(如读卡器)。通信格式设置为2400波特率,8位数据位,1位停止位,无奇偶校验。
下面是一个约定好通讯协议的程序实例,协议流程如图6所示。
以下是甲方(PC机)的几个子函数的程序实例。



图6 通信协议流程


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下还原为十六进制数。
具体为:Code$=Hex$(Asc ( Readbuff$ ) )
另外,由于32位API函数参数的数据类型的变化,所有整形参数都被换为长整型(Long)以支持32位的处理,这一点在设置返回值时尤其如此。

6 结束语

以上的软硬件在我们的实践中达到了较为理想的效果。通过软件节省了硬件的开销,并通过在PIC16F84单片机系统和PC机双方的通信软件内增加握手信号,达到了软件数据校验的目的,获得了较高的通信可靠性。

上一页  [1] [2] 


本文关键字:单片机  通信  综合-其它单片机-工控设备 - 综合-其它