📄 上海齐济电子-应用技巧-pic16系列单片机与pc机串行通信的软硬件实现.htm
字号:
lang=ZH-CN>;位计数为0则</FONT></SPAN></TD><FONT lang=ZH-CN></FONT></TR>
<TR>
<TD height=18 width="16%"></TD>
<TD height=18 width="15%"></TD>
<TD height=18 width="45%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;发停止位</FONT></SPAN></TD></TR></TBODY></TABLE>
<TABLE border=0 cellPadding=0 cellSpacing=0 width="100%">
<TBODY>
<TR>
<TD height=18 width="16%">
<P align=center><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>goto</FONT></SPAN></P></TD>
<TD height=18 width="15%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>Xnext</FONT></SPAN></TD>
<TD height=18 width="45%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;位计数不为0</FONT></SPAN></TD></TR>
<TR>
<TD height=18 width="16%"></TD>
<TD height=18 width="15%"></TD>
<TD height=18 width="45%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;则发下一位数据位</FONT></SPAN></TD></TR>
<TR>
<TD height=18 width="16%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>Xstop</FONT></SPAN></TD>
<TD height=18 width="15%"></TD>
<TD height=18 width="45%"></TD></TR>
<TR>
<TD height=18 width="16%">
<P align=center><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>call</FONT></SPAN></P></TD>
<TD height=18 width="15%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>Delay</FONT></SPAN></TD>
<TD height=18 width="45%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;延时B/2秒</FONT></SPAN></TD></TR>
<TR>
<TD height=18 width="16%">
<P align=center><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>call</FONT></SPAN></P></TD>
<TD height=18 width="15%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>Delay</FONT></SPAN></TD>
<TD height=18 width="45%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;延时B/2秒</FONT></SPAN></TD></TR>
<TR>
<TD height=18 width="16%">
<P align=center><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>Bsf</FONT></SPAN></P></TD>
<TD height=18 width="15%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>RA,DX</FONT></SPAN></TD>
<TD height=18 width="45%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;发送停止位</FONT></SPAN></TD></TR>
<TR>
<TD height=18 width="16%">
<P align=center><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>Retlw</FONT></SPAN></P></TD>
<TD height=18 width="15%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>0</FONT></SPAN></TD>
<TD height=18 width="45%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;返回</FONT></SPAN></TD></TR>
<TR>
<TD height=18 width="16%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;延时子程序</FONT></SPAN></TD>
<TD height=18 width="15%"></TD>
<TD height=18 width="45%"></TD></TR>
<TR>
<TD height=18 width="16%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>Delay</FONT></SPAN></TD>
<TD height=18 width="15%"></TD>
<TD height=18 width="45%"></TD></TR></TBODY></TABLE>
<TABLE border=0 cellPadding=0 cellSpacing=0 width="100%">
<TBODY>
<TR>
<TD height=18 width="16%">
<P align=center><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>movlw</FONT></SPAN></P></TD>
<TD height=18 width="15%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>12</FONT></SPAN></TD>
<TD height=18 width="45%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;52μS延时</FONT></SPAN></TD></TR>
<TR>
<TD height=18 width="16%">
<P align=center><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>movwf</FONT></SPAN></P></TD>
<TD height=18 width="15%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>DCNT</FONT></SPAN></TD>
<TD height=18 width="45%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;</FONT></SPAN></TD></TR>
<TR>
<TD height=18 width="16%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>Dnext</FONT></SPAN></TD>
<TD height=18 width="15%"></TD>
<TD height=18 width="45%"></TD></TR>
<TR>
<TD height=18 width="16%">
<P align=center><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>decfsz</FONT></SPAN></P></TD>
<TD height=18 width="15%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>DCNT</FONT></SPAN></TD>
<TD height=18 width="45%"></TD></TR></TBODY></TABLE>
<TABLE border=0 cellPadding=0 cellSpacing=0 width="100%"><FONT
lang=ZH-CN>
<TBODY></FONT>
<TR><FONT lang=ZH-CN>
<TD height=18 width="16%">
<P align=center><FONT face=宋体>goto</FONT></P></TD>
<TD height=18 width="15%"><FONT face=宋体>Dnext</FONT></TD></FONT>
<TD height=18 width="45%"><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>;</FONT></SPAN></TD><FONT lang=ZH-CN></FONT></TR>
<TR>
<TD height=18 width="16%">
<P align=center><FONT face=宋体>retlw 0</FONT></P></TD>
<TD height=18 width="15%"></TD>
<TD height=18 width="45%"><FONT face=宋体>;</FONT></TD></TR></TBODY></TABLE>
<P align=justify><SPAN style="FONT-SIZE: 9pt"><FONT color=#800080
lang=ZH-CN><B>4 Win95的串行通信机制及串口查询法的原理</B></FONT></SPAN></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN>
常用的DOS系统主要是工作在响应中断方式。PC机串行通信程序大多利用其BIOS块的INT14H中断,以查询串口的方式完成异步串行通信。<BR>
Windows系统函数即包含了通信支持中断功能。Win95系统为每个通信设备开辟了用户定义的输入输出缓冲区(即读/写缓冲区),数据进出通信口均由系统后台来完成。应用程序只需完成对输入输出缓冲区操作就可以了。实际过程是每接收一个字符就产生一个低级硬件中断,Win95系统中的串行驱动程序就取得了控制权,并将接收到的字符放入输入数据缓冲区。然后将控制权返还正在运行的应用程序。如果输入缓冲区数据已满,串行驱动程序用当前定义的流控制机制通知发送方停止发送数据。队列中的数据按“先进先出”的次序处理。<BR>
(1)
按协议的设置初始化并打开串口,这样做就是通知Windows本应用程序需要这个串口,并封锁其他应用程序使它们不能使用此串口。<BR>
(2) 配置这个串口。<BR> (3) 在串口上往返地传输数据,并在传输过程中进行校验。<BR>
(4)
不需要此串口时,关闭串口。即释放串口以供其它应用程序使用。<BR>在这四个步骤中,主要的程序代码集中在第(3)步。<BR>
串口查询法是一种主要工作在查询方式下的实现方法。当通信程序工作在“查询”方式时,可以不考虑Win95的进程和线程的问题。仅在串口有数据时,去读串口缓冲区就可以了,如图4所示。这种方法下确定串口读取的时机、握手协议及软件纠错的实现是程序员应考虑的主要问题。</FONT></SPAN></P>
<TABLE border=0 cellPadding=0 cellSpacing=0 width="100%">
<TBODY>
<TR>
<TD width="50%">
<BLOCKQUOTE>
<P align=center><FONT face=楷体_GB2312> <IMG
alt="jimages/yyjq8103.GIF (1145 bytes)"
src="上海齐济电子-应用技巧-PIC16系列单片机与PC机串行通信的软硬件实现.files/yyjq8103.gif"></FONT></P></BLOCKQUOTE>
<P align=center><FONT lang=ZH-CN><SPAN
style="FONT-SIZE: 9pt">图</SPAN></FONT><SPAN
style="FONT-SIZE: 9pt"><FONT face=Verdana>4 </FONT><FONT
lang=ZH-CN>读取接收缓冲区数据流程图</FONT></SPAN></P>
<P align=center> </P></TD>
<TD vAlign=top width="50%">
<P align=center><FONT face=楷体_GB2312><IMG alt="jc3.GIF (1515 bytes)"
src="上海齐济电子-应用技巧-PIC16系列单片机与PC机串行通信的软硬件实现.files/yyjq8104.gif"></FONT></P>
<P align=center><SPAN style="FONT-SIZE: 9pt">图<FONT face=Verdana>5
</FONT><FONT
lang=ZH-CN>串口初始化流程</FONT></SPAN></P></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD vAlign=top width="80%">
<TABLE border=0 cellPadding=0 cellSpacing=0 width="100%">
<TBODY>
<TR>
<TD colSpan=2 vAlign=top width="100%"><SPAN
style="FONT-SIZE: 9pt"><FONT lang=ZH-CN>
由于这种方法主要工作在查询方式。程序员必须完成相当一部分通信状态的检测工作,许多细节(甚至包括通信过程中的字符属性的转换)也必须通过程序代码完成。这种查询方法对通信双方协议的依赖性尤其大。双方通信协议的约定对程序实现的难易程度影响很大。<BR>
串口查询法中,一般串口初始化的流程如图</FONT>5<FONT lang=ZH-CN>。<BR>
值得注意的一点是,此方法下协议的约定必须满足以下条件:即甲方发送时,乙方必须在甲方发送动作之前进入循环接收状态,直到接收到字符后通过对串口读取函数</FONT>ReadFile<FONT
lang=ZH-CN>返回值的判断跳出循环状态。</FONT></SPAN></TD></TR>
<TR>
<TD vAlign=top width="50%">
<P align=justify><FONT lang=ZH-CN><B></B><SPAN
style="FONT-SIZE: 9pt">
同时,一般为了不使系统因循环等待接收而进入“死循环”状态,可以人为设置读取串口的循环次数,一般</SPAN></FONT><SPAN
style="FONT-SIZE: 9pt">1000<FONT lang=ZH-CN>~</FONT>10000<FONT
lang=ZH-CN>次即可。<BR>
本程序的实现平台是VB4,这是一种极为灵活的高级语言,它可以方便地引入汇编语言的思维,利用其GoTo转向语句方便地控制程序的流程,灵活方便。</FONT></SPAN></P>
<P align=justify><FONT color=#800080 lang=ZH-CN><B><SPAN
style="FONT-SIZE: 9pt">5 PC机内通信程序的实例</SPAN></B></FONT></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt"><FONT
lang=ZH-CN> 现约定甲方是</FONT>PC<FONT
lang=ZH-CN>机,乙方是单片机系统(如读卡器)。通信格式设置为</FONT>2400<FONT
lang=ZH-CN>波特率,</FONT>8<FONT lang=ZH-CN>位数据位,</FONT>1<FONT
lang=ZH-CN>位停止位,无奇偶校验。<BR>
下面是一个约定好通讯协议的程序实例,协议流程如图</FONT>6<FONT lang=ZH-CN>所示。<BR>
以下是甲方(</FONT>PC<FONT lang=ZH-CN>机)的几个子函数的程序实例。</FONT></SPAN></P></TD>
<TD vAlign=top width="50%">
<P align=center><SPAN style="FONT-SIZE: 9pt"><IMG
alt="jc4.GIF (2223 bytes)"
src="上海齐济电子-应用技巧-PIC16系列单片机与PC机串行通信的软硬件实现.files/yyjq8105.gif"></SPAN></P>
<P align=center><SPAN style="FONT-SIZE: 9pt">图6 <FONT
lang=ZH-CN>通信协议流程</FONT></SPAN></P></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD vAlign=top width="80%">
<P align=justify><SPAN style="FONT-SIZE: 9pt">Private Function
OpenThePort(cPort as String,cBaud as String,cParity </SPAN></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt">as String,cData as
String,tStops asString)As Boolean ’ 打开串口的子过程</SPAN></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt"> Dim lResult as
Long</SPAN></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt"> Dim lHandle as
Long</SPAN></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt"> Dim DCB_COMM as
DCB</SPAN></P>
<P><SPAN style="FONT-SIZE: 9pt"> Dim cDCBConfig as
String</SPAN></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt"> lHandle =
CreateFile(cPort,GENERIC_READ Or GENERIC_WRITE,</SPAN></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt">
0&,0&,OPEN_EXISTING,0&,0&)</SPAN></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt"> If lHandle = -1
Then ’打开串口失败</SPAN></P>
<P align=justify><SPAN
style="FONT-SIZE: 9pt"> OpenThePort =
False</SPAN></P>
<P align=justify><SPAN
style="FONT-SIZE: 9pt"> MsgBox
“串口可能正被其他应用程序占用!”</SPAN></P>
<P align=justify><SPAN
style="FONT-SIZE: 9pt"> lResult =
CloseHandle(lHandle) ’先关闭串口后再打开</SPAN></P>
<P align=justify><SPAN
style="FONT-SIZE: 9pt"> If lResult = 0
Then</SPAN></P>
<P align=justify><SPAN
style="FONT-SIZE: 9pt">
OpenThePort</SPAN></P>
<P align=justify><SPAN
style="FONT-SIZE: 9pt">
Exit Function</SPAN></P>
<P align=justify><SPAN
style="FONT-SIZE: 9pt"> End
If</SPAN></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt"> End
If</SPAN></P>
<P align=justify><SPAN style="FONT-SIZE: 9pt"> cDCBConfig.band
= 2400 ’设置DCB</SPAN></P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -