串口设计

2024-10-23

串口设计(精选12篇)

串口设计 篇1

串口驱动程序编写应该是所有外围器件驱动中较为容易的一类, 因为一般串行设备控制寄存器较少, 所以思路较易理清, 代码编写上较为容易。设备驱动程序编程都遵循一种约定, 即系统提供中间层 (对底层驱动而言, 即系

统提供回调函数) , 从而将底层驱动与上层 (一般为用户接口层) 隔离开来。这种隔离使得底层驱动程序员可以编写针对具体硬件的驱动程序并加入到内核中去, 这样的中间层一般被称为虚拟驱动层或者接口层。硬件驱动程序员需要清楚了解驱动程序与系统的接口所在。对系统接口层了解的越清楚, 编写出的驱动程序将更具健壮性和稳定性。

串口驱动既然作为底层驱动程序的一个方面, 系统不例外的也提供了其与上层的接口层。对于vxWorks操作系统而言, 这个接口层由ttyDrv, tyLib所代表。接口层本质上就是系统内核自定义的一套操作函数和数据结构, 底层设备驱动程序将使用其中某些函数和结构与接口层进行交互, 接口层经过进一步的处理后, 继续与上层进行交互。如上文所述, 所谓的上层一般即指用户接口层, 如I/O层。之间关系如图1所示。

ttyDrv和tyLib被称为虚拟驱动层, 二者协同工作共同管理设备驱动层。虚拟驱动层提供的功能主要有:

(1) 以字符设备的形式向上层 (I/O系统层) 注册其读写和控制函数。注册是在ttyDrv () 函数中完成的。而ttyDrv则调用iosDrvInstall完成其注册功能。其对上层注册的读写和控制函数如下: (以下所谓“对应上层XXX函数”是指上层XXX函数将针对tty设备进一步调用此处提供的函数, 如上层read函数针对tty设备将调用ttyRead函数进行进一步的处理)

ttyOpen:tty设备打开函数, 对应上层open函数。

ttyClose:tty设备关闭函数, 对应上层close函数。

tyRead, :tty设备字符读取函数, 对应上层read函数。

tyWrite:tty设备字符发送函数, 对应上层write函数。

ttyIoctl:tty设备控制函数, 对应上层ioctl函数。

(2) 向下层 (设备驱动层) 注册回调函数。作为对下层的接口, 针对是读还是写稍有不同。对于写而言, 在上层I/O层调用write函数写设备时, ttyWrite函数需要主动调用底层驱动程序相关函数发送字符。而对于读而言, ttyRead函数则直接从该层 (虚拟层) 读缓冲区中读取字符, 当缓冲区为空时, 等待 (阻塞方式) 或者立刻返回错误 (非阻塞方式) 。而此时读缓冲区的填充是由底层驱动主动进行的, 当底层驱动接受到一个字符时, 其调用虚拟层提供的机构函数将字符写入缓冲区中以供上层读取。

换句话说, 从虚拟层的角度:当写字符时, 在将字符填入写缓冲区后, 其需要直接调用底层驱动函数发送写缓冲区中的字符。

而当读字符时, 则不会直接调用底层驱动函数, 而只是检查读缓冲区是否有可读字符。读缓冲区中字符的填入是由底层驱动异步进行的。

从底层驱动的角度:对于写字符时, 如果发送完一个字符后, 其需要从写缓冲区中 (如果非空) 取下一个字符继续发送, 由于底层驱动不被允许操作虚拟层中的写缓冲区, 所以虚拟层即以回调函数形式提供一个函数 (tyITx) 供底层驱动从写缓冲区中取字符进行发送。当写缓冲区为空时 (即目前所有字符已被发送完) , 底层驱动将停止发送, 处于空闲状态。此时如果I/O层调用write函数, 继而到达虚拟层的ttyWrite函数, ttyWrite函数在将字符填入写缓冲区后, 其就需要启动底层驱动从空闲状态转入发送状态。这种启动即通过调用底层驱动的某个函数完成。而这个函数的地址在底层驱动程序初始化时将被提供给虚拟层。

对于读字符, 由于字符到达的随机性, 其不能等待上层调用write函数, 才进行接收, 而是只要有字符, 就进行接收, 并将接收到的字符上传给虚拟层, 至于如何对这些字符进行处理将由应用程序决定。此处底层驱动将接收到的字符上传给虚拟层即是通过虚拟层提供的回调函数 (tyIRd) 完成的。

综上, 虚拟层提供给底层驱动的回调函数有两个:①发送:底层驱动从写缓冲区中取字符函数:tyITx;②接收:底层驱动向读缓冲区中写字符函数:tyIRd。

(3) 完成其内部初始化 (如读写缓冲区分配) 和其他各种与硬件无关的辅助功能。

内部初始化主要有:①读写缓冲区分配;②互斥信号量分配;③重要变量和函数指针初始化。

作为底层驱动程序, 向上其与虚拟层交互, 向下其与具体硬件交互。所以其主要完成的功能也可以分为三个方面:

(1) 向上层提供回调函数。底层驱动需要提供一些函数供上层 (虚拟驱动层) 调用, 如启动发送函数, 硬件配置函数等等。一般虚拟层为了完成其功能, 对于其需要调用的底层功能实现函数会专门以一个数据结构的形式进行封装, 底层驱动程序需要对这个数据结构进行初始化后调用虚拟层提供的函数将信息通报给虚拟层。针对串口而言, 这个数据结构即为SIO_DRV_FUNCS结构, 该结构中所有成员均为函数指针, 底层驱动必须编写对应的完成相应功能的函数, 用这些函数地址对SIO_DRV_FUNCS结构进行初始化并通知给虚拟驱动层。

/*sioLib.h文件*/

typedef struct sio_drv_funcs SIO_DRV_FUNCS;

typedef struct sio_chan /*内核使用 SIO_CHAN结构表示一个串口设备*/

{

SIO_DRV_FUNCS * pDrvFuncs;

} SIO_CHAN;

struct sio_drv_funcs /*驱动函数指针定义 */

{

int (*ioctl) (SIO_CHAN *pSioChan, int cmd, void *arg) ;

int (*txStartup) (SIO_CHAN *pSioChan) ;

int (*callbackInstall) (SIO_CHAN *pSioChan, int callbackType,

STATUS (*callback) (void *, ...) , void *callbackArg) ;

int (*pollInput) (SIO_CHAN *pSioChan, char *inChar) ;

int (*pollOutput) (SIO_CHAN *pSioChan, char outChar) ;

};

vxWorks操作系统对每个串口用一个SIO_CHAN结构表示, SIO_DRV_FUNCS结构作为SIO_CHAN结构中一个字段而存在。串口驱动程序必须定义一个SIO_CHAN结构并对其进行初始化, 实际上即对SIO_DRV_FUNCS结构字段进行初始化。在实现上, 为了同时保存其它信息, 驱动程序定义一个自定制数据结构。如下所示。

/*底层设备驱动程序文件:arm926_uart.c*/

typedef struct _ARM926_CHAN{

/* SIO_CHAN类型字段必须是自定制结构的第一个成员 */

SIO_CHAN sio; /*内核定义的SIO_CHAN结构类型 */

…… /*其他信息定义*/

} ARM926_CHAN;

/*定义一个自定义ARM926_CHAN结构类型变量*/

ARM926_CHAN pChan;

/*初始化一个SIO_DRV_FUNCS结构*/

LOCAL SIO_DRV_FUNCS arm926UartDrvFuncs =

{

arm926UartIoctl,

arm926UartTxStartup

arm926UartCallbackInstall,

arm926UartPollInput,

arm926UartPollOutput,

};

/*在初始化函数中对SIO_CHAN结构字段进行初始化*/

void arm926UartDevInit (ARM926_CHAN * pChan)

{

……

pChan->sio.pDrvFuncs = &arm926UartDrvFuncs;

……

}

arm926UartTxStartup函数即是底层驱动提供的供虚拟层调用的发送启动函数。

arm926UartCallbackInstall函数也是由底层驱动程序提供, 虚拟层调用该函数向底层驱动注册tyITx, tyIRd函数地址, 即虚拟层提供给底层驱动的其 (虚拟层) 内部读写缓冲区操作函数, 也即前文中所述的虚拟层向下层提供的两个回调函数。之所以提供arm926UartCallbackInstall函数, 原因在于:①底层驱动并不知道虚拟层提供的回调函数究竟为何?②虚拟层并不清楚底层驱动将自己提供的回调函数安放在何处?

所以虚拟层提供另外一个函数指针callbackInstall, 由底层驱动实现, 虚拟层提供回调函数地址作为参数传入, 至于这些回调函数地址被保存在何处由底层驱动决定。

此处底层对callbackInstall 的具体实现为arm926UartCallbackInstall。对于串口, 网口, 一般存在两种工作模式:中断和查询。中断模式为硬件正常工作模式, 查询模式一般使用在系统调试时。由于查询模式需要明确的由上层进行控制何时进行接收和发送, 所以底层驱动程序必须提供对应的函数供上层调用, 而上层提供函数指针以获取函数地址, 这就是SIO_DRV_FUNCS结构中pollInput, pollOutput函数指针的目的所在。

(2) 控制下层硬件进行字符接收和发送及其他硬件配置工作。底层驱动程序完成的主要功能即控制具体硬件进行字符的接收和发送。在软件实现上, 也即读写相关硬件寄存器内容。正常方式下, 对于串口, 网口这样与外界进行数据交换的设备, 一般通过中断方式进行数据的接收和发送, 中断方式特别对于数据接收具有重要的意义, 因为数据接收时刻对于本设备而言完全不可知, 或者说具有相当的随机性, 内核或者应用程序无法预知何时有数据到达, 从而正好对其进行读取, 所以需要底层驱动程序的异步接收功能:即无论数据何时到达, 底层驱动都进行接收, 并上传给虚拟驱动层进行缓冲, 当应用程序需要读取数据时, 直接从缓冲区中读取即可。

而对于数据发送而言, 中断同样起着至关重要的作用, 通过中断, 底层驱动才可获知此次数据是否发送出去, 从而继续发送下一波数据。

总而言之, 无论是串口驱动还是网口驱动, 中断起着枢纽作用, 是中断将具体硬件与驱动软件联系起来。所以在软件架构上, 无论是串口还是网口, 其都是围绕一个中断处理程序而进行, 由中断处理程序再调用其他相关处理函数进行进一步的处理。

(3) 内部控制结构初始化和其他硬件相关辅助功能。对于驱动程序而言, 其必须维护一个自定义数据结构, 这个结构中将既包括上层需要的结构信息, 也包括对应硬件的具体信息, 如硬件控制寄存器基地址, 中断号等等。

至于其他辅助功能, 包括硬件的统计信息收集和其他一些辅助配置功能。

以上从层次上介绍了虚拟驱动层和设备驱动层的基本功能。了解层次关系对于下文中各层次之间的交互至关重要。下文即从串口初始化开始介绍串口驱动所关联的内核部分。

对于vxWorks而言, 串口初始化是在usrInit函数中 (定义在usrConfig.c文件中) 进行的, 调用路径如下: (以下采取“文件名:函数名”形式说明, 底层驱动程序文件名为arm926_uart.c, 该文件中定义的函数名均以arm926打头, 以与内核函数区分)

usrConfig.c:usrInitundefined:sysHwInitundefined: sysSerialHwInitundefined

arm926_uart.c: arm926UartDevInit ()

sysHwInit是对所有外围硬件进行初始化的函数, 对于串口而言, 具体的初始化函数在sysSerial.c文件sysSerialHwInit函数中进行。而sysSerialHwInit函数实现即与具体硬件平台相关, 对于某个具体的平台而言, 需要对sysSerialHwInit函数进行自实现, 该实现继续调用具体硬件驱动程序初始化函数, 如前文中对于ARM926EJS开发环境, 其对应初始化函数即为arm926UartDevInit。

此时进行的初始化只是底层驱动程序的初始化:

(1) 完成相关数据结构初始化, 包括虚拟层提供的相关结构的初始化从而提供给虚拟层相关回调函数地址。

(2) 完成相关硬件寄存器的配置。配置后硬件处于非工作状态, 但所有的硬件准备工作已经完成, 只是相关工作使能位尚未开启。

此时除了开启硬件正常进行工作, 已完成前文所述底层驱动程序所需完成的三个任务中所有方面。

内核相关初始化在usrRoot函数中完成。从代码实现看, 如果需要在内核中包括串口组件, 必须在config.h文件中定义如下常量:

#define INCLUDE_SERIAL

#define NUM_TTY N_SIO_CHANNELS /*串口通道数*/

#define CONSOLE_TTY 0

#define CONSOLE_BAUD_RATE 115200

INCLUDE_SERIAL变量作为控制是否包含串口设备的总开关。对于需要使用串口的平台, 必须定义该变量。

NUM_TTY为串口通道数, 这也是平台相关的。

CONSOLE_TTY表示控制终端使用的通道号, 一般定义为0。

CONSOLE_BAUD_RATE即控制终端所使用通道的波特率。

usrRoot函数种对串口组件初始化涉及到的关键函数有三:

(1) ttyDrv () 内核实现。该函数实现在前文中已给出。该函数主要完成的功能是虚拟驱动层向上层 (I/O层) 注册读写和控制函数:诸如ttyWrite, ttyRead, ttyIoctl等等, 以供上层调用。

(2) ttyDevCreate () 内核实现。该函数完成对下层相关函数的注册以及内核相关缓冲区和信号量等其它辅助功能初始化工作。

经过以上调用, 此时虚拟驱动层已完成前文中所述该层所需完成的三个主要任务, 内核串口组件已处于正常工作状态。

(3) sysSerialChanGet () 内核提供函数原型, 平台相关实现, 由底层设备驱动程序员完成编写, 与底层串口驱动数据结构相关。该函数的实现读者可参考templateARM目录下 (或者其它体系结构下对应的目录) sysSerial.c文件。

到此, 只剩下向内核注册中断程序 (调用intConnect函数完成) 和开启硬件使能位。这是在sysClkConnect函数中完成的。函数调用路径如下: (采用“文件名:函数名”方式说明, 底层串口驱动程序名为arm926_uart.c) 。

usrRoot:sysClkConnectundefined:sysHwInitundefined:sysSerialHwInitundefined

arm926_uart.c: arm926UartDevInit2 ()

arm926UartDevInit2函数的实现较为简单:①调用intConnect完成中断处理程序的注册。②调用intEnable使能该中断。③写具体硬件相关寄存器使能位开启硬件工作。

所有串口相关准备工作完成, 串口进行正常的数据接收和发送。

底层驱动程序框架总结如下:

(1) 自定义描述设备的数据结构, 形式如前文所述。

(2) 初始化一个虚拟驱动层定义的SIO_DRV_FUNCS结构, 如前文所述。

(3) 编写中断处理核心函数。具体函数架构可参考Wind River提供的串口驱动模版文件。

(4) 提供底层驱动初始化函数, 修改sysSerial.c中相关函数实现, 调用这些初始化函数。注意由sysSerial.c中相关初始化函数对底层驱动程序中初始化函数的调用通过修改sysSerial.c中相关函数实现完成的, 而对于sysSerial.c文件中初始化函数的调用是由内核自动完成, 这从前文的分析中也可看出。所以底层驱动程序员可以而且应该改变sysSerial.c文件中相关函数实现, 但一定不可修改该文件中函数定义的原型:函数名称和参数类型与个数均不可进行改变。

(5) 编写其他具体处理数据接收和发送函数以及其它硬件配置和控制函数, 这些函数由中断处理核心函数调用。

结束语

为使内核上层结构独立于具体底层驱动程序实现, 几乎所有的操作系统都会在设备驱动层之上提供接口层, 一般我们将该层称为虚拟驱动层。作为驱动程序编写者, 除了要了解具体硬件功能外, 还需要清楚了解底层驱动程序与虚拟驱动层之间的联系。本文以vxWorks下串口驱动程序为例, 详细阐述了串口驱动程序底层模块和虚拟驱动层模块的功能以及基本实现, 并从内核初始化代码进行分析, 了解内核模块和底层驱动模块的初始化过程。文章最后附以具体代码给出了一个串口驱动程序的架构。串口驱动程序虽然是所有外围器件驱动程序中较为容易的一类, 但要编写出一个稳定健壮的串口驱动程序还是需要清楚地了解其涉及的各个方面, 希望本文可以在此方面助你一臂之力。

摘要:串口驱动程序由于涉及硬件寄存器较少, 所以是外围器件驱动程序编写中相对较为容易的一类, 但其与内核操作系统的联系上和其它驱动程序都具有相同的层次结构。论文着重阐述了vxWorks操作系统下串口驱动程序与其上层虚拟驱动层的交互, 并详细解释了虚拟驱动层和串口驱动程序的功能以及初始化过程。论文最后结合代码示例给出了串口驱动程序的架构。

关键词:vxWorks,虚拟驱动层,串口驱动

参考文献

[1]Wind River Systems Inc.vxworks kernel programmers guide.2006.09

[2]Wind River Systems Inc.vxworks device driver developers guide.2006.09

[3]Wind River Systems Inc.内核示例源代码

[4]陈智育等.VxWorks程序开发实践.北京:人民邮电出版社, 2004.

[5]http://www.gd-emb.org/detail/id-31347.html, 2008.08

串口设计 篇2

本文重在利用OK6410开发板串口通信模块和Qtcreator环境下使用的第三方串行通信控件qextserialport,自定义通信协议,研究与实现ARM型基因扩增仪与PC机的串行通信,以完成相应的功能要求,满足社会需求。

1相关技术研究

1.1串口通信

串口通信是指外设和计算机间,通过数据信号线、地线、控制线等,按位进行传输数据的一种通讯方式。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低[2]。

本文用的是RS-232串行通信,其接口标准:EIA公布的RS-232C是用得最多的一种串行口通讯标准。事实上的RS-232C串口标准配置为”D”型9针插头,其引脚定义如图1。

1.2QT图形界面系统

Qt是一个跨平台的C++图形用户界面应用程序框架。它提供给应用程序开发者建立艺术级的图形用户界面所需的所用功能。Qt是完全面向对象的,非常容易扩展,并允许真正地组件编程。本设计中上位机和下位机程序均利用QT开发,通过选择不同的编译器,即可生成X86版本和ARM版本的应用程序[3]。通过上位机的界面上的按钮可以实现对基因扩增仪各种参数的设置,也可读取PCR状态信息。使用QT开发程序具有以下优点:

1)优良的跨平台特性;2)面向对象;3)丰富的API及类库;4)运行速度快;5)大量的开发文档及实用的开发工具。

2基因扩增仪与PC机的通信硬件连接

本设计中基因扩增仪采用飞凌公司出品的开发板OK6410来实现。该开发板搭载了三星公司ARM11的处理器S3C6410。底板上提供了1个五线RS232电平串口(UART0)和3个三线TTL电平串口(UART1~UART3)。在开发阶段,需要两根串口线与PC机连接,其中UART0默认为调试串口,它的作用是可以与电脑直接相连,进而监控系统调试信息,另外一个串口需要使用MAX232将TTL电平转化为RS-232电平才可以和电脑相连,该串口线用于数据和指令的发送[4]。

串口设计 篇3

关键词:LabWindows/CVI;TMS320F2808;串口通讯

中图分类号:TP393.09

LabWindows/CVI是一个完全的ANSI C开发环境,用于仪器控制、自动检测、数据处理的应用软件。使用灵活的C语言开发平台与数据采集、分析和显示有机的结合起来,为熟悉C语言的开发人员建立自动化检测系统、数据采集系统和过程化控制等提供了一个理想的软件开发环境。采用TI公司生产的TMS320F2808作为处理芯片,它是一款专为控制应用系统而设计的32位定点运算DSP。它具有强大的外设功能,无需额外增加其它芯片便可轻松实现AD采集、多功能GPIO口、SCI、SPI、CAN、IIC以及其它通信接口。利用LabWindows/CVI灵活的C语言以及DSP强大的处理能力,可以灵活的实现PC机与DSP之间串行数据的交互功能。

1 PC机与DSP间的串口通讯设计

1.1 DSP串口设计

DSP与PC机进行数据交换,两者之间必须采用一个电平转换芯片,本文选用MAX公司生产的MAX3232进行电平转换。PC机与DSP串口通讯框图如图1所示,电平转换电路如图2所示。

TMS320F2808的内部具有两个相同的SCI模块,SCIA和SCIB。每个SCI模块都有独立的接收器和发送器,他们有各自独立的使能位和中断位,可以进行半双工和全双工的工作模式。每个SCI模块同时拥有独立的两个收发引脚SCIRXD和SCITXD,在不使用SCI模式时,这两个引脚可以作为通用I/O口使用。TMS320F2808可编程实现64000种不同的波特率,还可通过硬件逻辑来实现自动波特率的功能。

1.2 通讯协议设计

DSP与PC机之间采用固定的9.6K波特率,无奇偶校验,8位数据位,1位停止位。传输的数据格式为:帧头(0CH),数据长度帧,数据长度帧,命令帧(F0H,F1H……),数据帧,校验帧,帧尾(C0H)。PC机接收数据正确并执行完毕后回传AAH+55H;当接收数据错误回传55H+错误码。错误码为01H,03H,……09H,不同的错误码对应不同的含义。

2 PC机通讯程序设计

LabWindows/CVI编程的核心概念是对象编程,而虚拟仪器中的控件就是对象,对象是数据和代码的组合,LabWindows/CVI中程序的运行便是对一系列控件的响应和函数的调用。如响应面板关闭控件库函数,QuitUserInterface (0);

PC机程序设计采用LabWindows/CVI的软件设计,利用LabWindows/CVI提供强大的函数库,可轻松的实现PC机串口的收发功能。利用C语言,可灵活的实现复杂的数据处理。

OpenComConfig(1,"",9600,0,8,1,512,512); //打开串口并设置波特率

Fmt(str,"%s[a]<%x[w3]",data[i]); //数据字符串转换

MessagePopup ("信息","请打开串口"); //提醒用户打开串口

*length=GetInQLen(1); //读取串口接收数据的长度

3 DSP软件设计

DSP软件设计采用TI公司提供的CCS3.3集成开发环境进行设计,利用灵活的C语言进行开发,可通过JTAG口进行在线调试,提高了程序设计的效率。

DSP串口采用中断模式进行数据的接收,数据接收完毕后通过协议进行数据的有效性判断。若接收数据无效,则放弃本次接收的数据,并等待下次接收。若接收数据有效,则保存数据,并执行相应的程序。程序流程图如图3所示。

DSP 通过中断函数进行数据接收和协议判断,具体实现如下:

interrupt void rxaint_isr(void) // SCI-A

{

PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;//打开相应的中断级门禁

ReceivedAChar = SciaRegs.SCIRXBUF.all; //读取缓冲区数据

Receive_data[ReceivedCount] = ReceivedAChar; //暂存数据

SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; //清中断标志,等待下次中断

}

4 结束语

LabWindows/CVI提供的交互式平台、丰富的功能面板和强大的函数库,为虚拟仪器的程序设计提供了强有力的支持。灵活的C语言设计,代码易于实现,且硬件简单,不需要专用的通讯接口,性价比较高。

参考文献:

[1]王建新,杨世凤,隋美丽.LabWindows/CVI测试技术及工程应用[M].北京:化学工业出版社,2006.

[2]任润柏,周荔丹,姚钢.TMS320F28X源码解读[M].北京:电子工业出版社,2010.

[3]顾卫钢.手把手教你学DSP—基于TMS320X281X[M].北京:北京航空航天大学出版社,2011.

作者简介:肖勇(1987-),男,四川宜宾人,助理工程师,初级,工学学士学位,研究方向:自动测试。

CPLD的串口电路设计 篇4

本文选用CPLD是ALTERA公司的EPM240T100, 结合MAX232接口芯片进行串口通信设计, 框图如下图1所示。

二、VHDL程序模块设计及描述

使用VHDL对CPLD进行编程, 设计3个模块, 波特率发生模块, 接收器, 发送器。

1. 波特率发生模块

波特率发生器实际是一个分频器, 如前所述, 本文设计的波特率为19.2kb/秒, 设计使用的时钟频率为10MHz, 所以计数器进行计数时计数到260进行翻转。

程序如下 (关键部分保留, 非必要部分用……代替) :

2. 发送模块

发送部分采用状态机t_state进行编程, 共设两个值:t-start和t_shift, 分别表示发送开始以及发送保持状态。复位键按下时设置到t-start状态, 并将发送数据位设为“1”, 发送的数据位数计数为0, 在t-start状态, 状态机将处于这一个状态并等待波特率计数信号的电平上升沿到来。上升沿到来时, 依据t_state状态的不同值做不同处理, 如果是t-start开始状态则先读待发送的数据, 并发送开始位“0”, 然后将状态转到发送保持t_shift状态, 在发送保持t_shift状态, 不断判断发送的数据位数是否满8位, 如果满了则回归t-start状态, 否则继续发送, 保持在t_shift状态, 为避免干扰将其余情况下的状态自动跳转到t-start状态。程序如下:

3. 数据接收模块

接收部分采用状态机进行编程, 共设两个状态:r-start和r_shift分别表示接收开始以及接收保持状态;复位键按下时设置到r-start状态, 并将待接收存放数据的data赋值为“00000000”, 在r-start状态, 接收状态机将处于这一个状态并等待波特率计数信号的电平上升沿到来。波特率发生模块的计数上升沿到来, 依据状态的不同值做不同处理, 如果是r-start接收开始状态则等待开始位信号, 检测到rxds=‘0’的开始位信号好转到r_shift接收保持状态, r_shift接收保持状态会不断判断接收的数据位数是否满8位, 如果满了则回归r-start状态, 否则继续接收, 保持在r_shift接收保持状态, 为避免干扰将其余情况下的状态自动跳转到r-start接收开始状态, 程序与发送部分类似, 此处省略。

三、串口通信的VHDL程序仿真结果

串行口通信的仿真结果如图2所示。从图中可以看出, 每发送完一个字节, 即8位数据后, 线路上将输出一个高电平, 之后又开始传送下一个字节。同样, 仿真波形显示, 有效数据到达接收管脚rxd之前, 线路上保持为高电平, 直到收到一个低电平起始位, 将该起始位后的8位数据串行接收后依次送到保存接收结果的信号data的各位。

串口通信的硬件验证

将程序通过在系统编程下载入配套的CPLD电路板进行硬件验证, 按照以下步骤进行。

(1) 确定管脚对应关系:

串行接收管脚rxd与max232的12脚R1OUT对应;串行发送管脚txd与max232的11脚T1IN对应;复位信号reset与按键S1对应。

(2) 由QUARTUS II进行管脚分配:

f10MHz在MAXII芯片上对应的管脚号为12;S1在MAXII芯片上对应的管脚号为21;rxd在MAXII芯片上对应的管脚号为89;txd在MAXII芯片上对应的管脚号为90。

(3) 电平定义:

按键S1按下时表示输入信号为低电平。

单片机串口总结 篇5

有句话说“尽信书不如无书”,要学好单片机就要不断的、大胆的实验,要多怀疑,即使我们的怀疑最终被证明是错误的那么这也是进步(人们认识事物很多情况下来源于怀疑),当怀疑出现时就要去实践。有很多东西如果不通过实践是不可能掌握其中隐藏的奥秘,就拿51单片机串口通讯这一块,我认为掌握很好了,可以很轻松的实现数据的接收、发送,但这段时间当我重新学习串口时,我才发现里面还有很多小细节从没注意,更别说研究了。对于接收发送程序永远是按照别人的模式来编写程序,并没有真真正正的挖掘深层次的内容。我身边太多的人在临摹别人的程序,当然我不反对,但是希望自己多问几个问什么,单纯的会编程是学不好单片机的,毕竟单片机有自己独特的硬件结构。

开讲之前先简要说一下同步、异步通信:

同步通信:发送方时钟对接收方时钟控制,使双方达到完全同步。

异步通信:发送与接受设备使用各自的时钟控制数据的发送和接受过程(虽然时钟不同,但一般相差不大)。

51单片机串行口结构

从上图中我们看到,51单片机有两个物理上独立的接收、发送缓冲器SBUF,它们共用同一个地址99H,但是请注意:接收缓冲器只能读而不能写,发送缓冲器只写不读。单片机可以同时实现数据的发送与接收功能。

特别注意:接收器是双缓冲结构:当前一个字节从接收缓冲区取走之前,就已经开始接收第

二个字节(串行输入至移位寄存器),此时如果在第二个字节接收完毕而前一个字节还未被读走,那么就会丢失前一个字节。

51单片机串口控制寄存器

关于51单片机的控制寄存器各个位表示的含义在这里我只谈SM2。

SM2为多机控制位,主要用于工作方式2和3,当接收机的SM2=1时,可以利用接收到的RB8来控制是否激活RI(RB8=0不激活RI,收到的数据丢失;RB8=1时收到的数据进入SBUF,并激活RI ,进而在中断服务程序中将数据从SBUF中读走)。当SM2=0时,不论收到的RB8为何值都将使接收到的数据进入SBUF,并激活RI,通过控制SM2实现多机通信。

51单片机串口通讯方式

51串口通讯方式有3种,方式0、方式

1、方式2与方式3,他们的工作模式不尽相同。首先他们的波特率很容易忽视。方式0与方式2的波特率固定,而方式1和3的波特率由T1的溢出率决定。

方式0的波特率=f/12

系统晶振的12分频,换句话说12M晶振的情况下,其波特率可达1M,速度是很高的(当我们在选用串行器件并采用方式0时需要特别注意器件所能允许的最大时钟频率)。

方式2 =f/64或f/32(当SMOD=1时为f/32,SMOD=0时为f/64)。

曾经我用方式2进行MODBUS通信时,总是通讯失败,我仔细检查程序,没有发现逻辑错误,特别是当我参考别人的程序时,发现很少有人用方式2进行MODBUS通讯,所以当时自己妄下结论51单片机的串行方式2不可用,直到有一天夜里我突然想起方式2的波特率是固定的,试想晶振11.0592M/32或11.0592M/64怎么也不可能是9600啊,怎么可能通信成功。这才恍然大悟,看来还是自己太武断了,没有认真看书啊。有时我们认为我们犯这样的错误很低级,其实我们很多次都是因为这样的小细节导致我们整个系统不正常,正所谓“千里之堤毁于蚁穴”,这些细节真的伤不起啊。

方式1、3波特率=(2smod/32)*T1的溢出率,其中TI的溢出率=f/{12*[256-(TH1)]}.关于3种通讯方式其中有几点特别容易出错:

1、无论采用哪种通讯方式,数据发送和接受都是低位在先,高位在后。、3种方式作为输出,由于输出是CPU主动发送,不会产生重叠错误,当数据写入SBUF后,发送便启动(通过单片机内部逻辑控制,与程序无关),当该字节发送结束(SBUF空),置TI。不要理解为当数据一写入SBUF就置位TI,如果中断允许则在中断中发送数据,这就大错特错了。同样作为输入,可能会产生重叠错误(主要依赖于特定的环境),当一个字节的数据接收完毕(SBUF满)置位RI,表示缓冲区有数据提示CPU读取。

接下来通过一些实验具体说明串口通信中需要注意的地方 方式0输出

方式0主要功能是作为移位寄存器,将数据从SBUF中逐位移出,最常见的用法就是外接串入并出的移位寄存器,如74LS164。之前在做这一部分实验时总是利用单片机I/O端口模拟实现,现在想想在串口未被占用的情况下,方式0是最好的实现方式。

利用串口方式0,向74LS164输出字符“0”的编码,程序如下:

该程序采用了中断方式实现,结果是通过74LS164使数码管显示“0”。实验结果如下:

这里我说明几点: 如果采用查询方式,并且只发送一遍,那么程序最后的while(1);不可以省略,否则会出现数码管闪烁的现象(在KEIL环境下,main()函数也是作为一个调用函数,最后也有返回RET,它不像C中的main()函数,当执行完毕后就停止,而是重新复位执行,如此反复,这一点要特别注意)

这是查询方式下不加while(1);的现实效果 如果采用中断方式发送,请记得中断中清除TI,仅仅是为了解除中断标志,而不是等待发送结束,因为此时数据早已离开了SBUF跑到外边去了。3 74LS164最高25MHZ,采用方式0,没有问题。

方式0作为输入模式

以74ls165(最高时钟25MHZ)为例,可以满足要求。

对应结果如下:

(注意:74ls165线传送高位,而串口通信低位在先,所以显示的数据和实际数据高低位正好相反

P1.7---P1.0对应D0---D7)。

本程序只接收一次,也许有人会问,中断程序中REN=0,表示什么意思?可不可以改成ES=0?

这个问题很好,首先REN=0表示接收禁止,即不允许串口接收数据;ES=0是禁止中断和单片机是否接收数据没有关系,不接收数据自然中断允许也是徒劳,这两者有很大的区别。我们在很多接收程序中经常可以看到在判断RI标志后紧跟着清除标志位,我想问一下,为什么?)

如果我们也按照这种模式改写会怎样呢?

实验结果如下

两次结果差异怎么这么大?为什么会这样子?

为了便于理解,也为了说明问题方便,对中断程序做了如下处理:

结果又变了

是不是感觉很奇怪,究竟咋回事呢?

首先中断程序中当判断RI置位标志后紧跟着清零是为了接收下一个字节的数据,也为了避免单片机重复中断。

当51单片机串口方式0作输入时,在REN=1且RI=0的条件下就启动了单片机串口接收过程。如果有一个条件不满足就不能启动接收过程,以上出现的错误正式由于忽略了这个重要的因素造成的。在RI清零后由于REN仍然为1,单片机已经开始接收第二字节的数据,由于串口速度很快,RI仍会置位,而紧接着将REN清零只能阻止单片机接收数据,但是却

不能阻挡第二次中断。由于只接收了部分外部引脚数据(此时外部引脚为高电平,即逻辑1,其实单片机只接收了一位,对于12M晶振而言,方式0大约8us接收一个字节数据)。相反在RI=0与REN=0之间加上适当的延迟,就可以保证一个字节的数据全部接收完毕,故此时我们读上来的一个字节为0xff。

我在中断程序中添加了一个中断计数器(不加延迟),发现中断服务程序的确执行了两次

结果如下

加上延迟结果

这就验证了刚才的结论。

至于说可不可以换做ES=0,回答是可以的,尽管同样可以实现数据的读取,但是实质不同,当禁止中断后,单片机仍在接收外部数据,只是不再请求中断,自然的不再读取第2、3。。。字节的数据,那么P1将保留第一次中断时从SBUF中读出的数据。如果某一时刻打开中断发现结果不正常,如果理解了上面的机制就不会觉得惊讶了。建议:单次接收时,中断服务程序中REN清零放在RI之前。

还有一个问题非常重要:

如果我在中断服务程序中不清除RI,会怎样?

很少有人会这样用,但是经常有人忘记了(包括我)。课本上写得很清楚,务必在中断中用软件清除RI,为什么要这样呢?难道仅仅是为了接收下一次数据并且避免单片机不断的响应中断?的确如此,如果对于一个小系统而言,不清除中断标志,那么单片机将不停的中断,影响接下来任务的执行,系统必然瘫痪,而且不能正常的接收数据。总结:方式0作为发送方,只要向SBUF中写入数据就启动了发送过程;

方式0在座位接收模式时,REN=

1、RI=0的情况下就已经启动了接收过程。在中断程序中要注意两者清零的顺序。

还有一种情况要特别注意:单片机复位时SCON自动清零,如果单片机不工作在方式0,那么如果采用位操作SCON时也要注意REN=1与SM0、SM1的书写顺序,总之切记方式0启动发送、接收数据的条件。

方式1 方式1为10位异步通信模式。作为输出和方式0没有本质的区别,不同的是数据帧的形式,但是对于接受模式则有点不同,当REN=1且RI=0时,单片机并不启动接收过程。而是以已选择波特率的16倍速率采样RXD引脚的电平,当检测到输入引脚发生1---0负跳变时,则说明起始位有效,才开始接受本帧数据。方式1模式下 单片机可以工作在全双工以及半双工方式。下面举两个例子

半双工

主机发送某一字符,从机接收到数据后返回数据加1的值 比如 主机发送“1“,从机收到后回复主机”2“。实验结果如下:

方式1工作方式主要注意: 1 波特率可变。数据接收以起始位为标志,停止位结束。当RI=0且SM2=0或接收到有效停止位时,单片机将接收到的数据移入SBUF中,两个条件缺一不可。

方式2和方式3 方式2和3不同的只是波特率,这里以方式3为例

作为输出模式同方式1没有区别,只是增加了第八位数据位,第八位数据可以用作校验位或在多机通信中用作数据/地址帧的判别位。

首先我们来做模拟主从奇偶校验模式

主机发送一帧数据,并发送奇偶校验位,从机接收数据后,判断数据是否正确,如果正

确,接收指示灯亮,并且回送主机数据加1,反之回送0;主机接收从机信息,如果校验正确点亮LED指示灯.(从机、主机接收数据无论校验正确与否,均显示接收到的字节数据)。奇校验模式 演示结果如下:

(注:从接接收不正确,返回0)

主从机接收正确效果

之前我们已经介绍了SM2的具体用法,主要用于多机通信,将SM2作为数据/地址帧 的判别位,在接收地址时令SM2=1,当接收到的第八位数据为1时激活RI产生中断,然后比较地址,如果地址符合则清除SM2准备接受数据信息,反之不理睬。

特别注意 当RI=0且SM2=0(或SM2=1时接收到第9位数据为1)时,单片机将接收到的数据移入SBUF中,两个条件缺一不可。

在这里我只举一个简单的例子 一个主机,两个从机 起始时,主机从机的SM2均置位,所有的从机等待主机发送地址帧,主机令TB8=1,发送地址帧。所用的从机将接受到的地址和自己的地址比较,如果符合,点亮LED指示灯,清除SM2(准备接受主机发送的数据帧),并将自己的地址发送到主机。主机接收从机发送的地址信息,如果地址符合则数码管显示从机地址并开始准备发送数据,反之发复位信号,TB8=1。从机接收数据先判断RB8,如果RB8=1,则复位,重新开始接收主机发送的地址帧,反之通过P1口外接数码管显示接收到的数据。实验结果如下:

注意:如果主机没有得到正确的地址,则将按照一定的速率发送地址帧,直到接收正确的地址为止,该试验主机向从机2发送信息。

另外在这里我补充两点: 我们可以很方便的利用串口通信的工作方式2或3实现奇偶校验,注意技巧,当为偶校验时TB8=P,奇校验时TB8=~P;

串口设计 篇6

关键词:OLE控件;char(0)字符;位操作

中图分类号:TP311.56文献标识码:A 文章编号:1000-8136(2009)17-0022-03

PowerBuilder(以下简称PB),作为一种编程工具,以其简洁易操作的界面,类似VB的编程语言,丰富的数据库接口以及其独特的数据窗口技术,使其在数据库编程中具有相当的优势,因而受到很多编程人员的亲睐。在当今微软Delphi停止开发的情况下,PB为广大数据库编程人员提供了另外一种很好的选择,而且PB从10.0开始,也开始全面支持.NET,可以说对.NET的支持也比较全面。

但是PB中没有直接操作串并口的函数,也没有直接对二进制数据的位操作函数,这导致在工业控制中PB的应用一直偏少。最近笔者在实际工作中就遇到了这个问题,通过一段时间的研究,圆满解决了该问题,下面提出了一种解决思路,与大家一起探讨。

1 用PB完成数据库编程应解决的问题

委托编程的矿井从井下传回8路状态电平,需要把这些电平读入电脑,并转化为相应的数据,并把这些数据以曲线图的形式显示在大屏幕上,还要同时存储数据以便今后用户自定义条件查询。因为数据处理的信息量较大,用户要求的数据操作如查询、排序等又特别繁琐,笔者第一时间就定下了采用数据库编程有优势的PB完成该工作,但有4个问题需要解决。

1.1信号电平如何转化为标准串口数据格式

井下各种设备传回的状态电平不是串口可接受的CMOS 12 V格式,而是以-48 V或-24 V的电平表示正常工作,以0 V表示停止工作;而串口是以+12 V表示1,-12 V表示0,并且还必须有开始位、停止位等固定格式,二者完全不匹配。

解决该问题分3步:

(1)采用三端稳压使正常工作时输出+5V,停止工作时输出0V。本例采用固定三端稳压器w7805来实现。

(2)将该开关信号加入开始位、停止位使其成为标准串口数据。这一步用AT89C52单片机来实现,具体程序如下:

描述:单片机从P1口接收外部的状态数据,然后将数据传送到P0口, 并传回给主机。

; 变量定义

ORG0000H

LJMPMAIN

MAIN:

MOVTMOD,#20H; 使定时器1工作于8位自动重载模式,用于产生波特率

MOVTH1,#0FDH

MOVTL1,#0FDH; 波特率9600

MOVSCON,#50H; 设定串行口工作方式为1方式

ANLPCON,#0EFH; 波特率不倍增

SETBTR1; 启动定时器1

MOVIE,#0; 禁止任何中断

MAIN_RX:

MOVA,P1; 数据传送到P1口

LCALLSEND_CHAR; 回传接收到的数据

MOVR7,#0FFH;

LCALLDELAYMS

LJMP MAIN_RX

SEND_CHAR:

; 传送一个字符

; 传入参数: ACC(要发送的数据)

; 返回值: 无

MOVSBUF,A

JNBTI,$; 等待数据传送

CLRTI; 清除数据传送标志

RET

DELAYMS:

; 延时子程序

; 传入参数:R7 --- 延时值(MS)

; 返回值:无

MOVA,R7

JZEND_DLYMS

DLY_LP1:

MOVR6,#185

DLY_LP2:

NOP

NOP

NOP

DJNZR6,DLY_LP2

DJNZR7,DLY_LP1

END_DLYMS:

RET

END

(3)5 V的TTL电平转化为±12 V的RS-232电平

单片机的串口一般不符合RS-232标准,它是一种RS-232标准的变种,只是码制、波特率等等和RS-232定义都是一样的,只有一点不一样,就是高低电平的定义。AT89C52单片机高电平一般是+5 V,而低电平一般是GND。而RS-232标准的高电平定义为+12 V,低电平定义为-12 V。

电脑的COM口就是标准RS-232接口,所以单片机的串口必须经过电平转换才可以和标准RS-232通信,一般选用MAX232或SP232, HIN232。

它与单片机和电脑串口的接法见图1。

1.2 解决串口通信问题

PB中没有直接操作串口的控件,但提供了创建OLE控件的方法,通过它可以调用其他语言编写的ocx或dll控件,这次我们要调用微软的MsComm控件。设置其OLE属性如下:

Comport=“1” //对应com1,其余类推;

//波特率为9600,无校验,8位数据位,1位停止位,此处和单片机的设置对应

Settings=“ 9600,n,8,1”

Handshaking=“0” //无握手信号

InBufferSize=“1024” //1KB的输入缓存

OutBufferSize=“512” //512B的输出缓存,因为本程序不涉及输出,所以此处设置可为0

Rthreshold=“4” //输入阀值为4,该值决定串口每接收几个字节触发一次OnComm事件,在该//事件中用户可以处理接收的数据。本例中串口每接收4个字节触发一次OnComm事件,而//单片机每255ms发1B的数据,即每1 s触发一次OnComm事件

Sthreshold=“0”

//输出阀值为0,设置缓存到一定字节数后统一输出到串口,设为0则直接输出不缓存

其他属性可以为默认。

在窗口的Open事件中插入语句MSComm1.object.PortOpen=True打开该控件对应的串口。

在窗口的Close事件中插入语句MSComm1.object.PortOpen=False关闭该控件对应的串口。

在MSComm1控件的OnComm事件中插入语句string s=mscomm1.object.Input 用s接收串口数据并做进一步处理。

1.3 解决char(0)字符问题

至此,微机应该已能正常接收井下机器的状态数据,但实际工作中,当所有机器状态都为0时,微机没有正确地显示这一状态,这是为什么呢?

经反复调试并查阅资料发现,此时串口已收到了这一全零字节,但因为PB无法接收处理这类ASCII码为0的字符即char(0),导致这类故障。解决方法用到了一类特殊数据类型——大二进制数据类型Blob,它可以用来处理图片和大文本等各种“大”数据,因为在这些文件中不可避免的会有char(0)字符,所以PB是直接把它们整体当成一块二进制数据而不是一串字符串来处理,Comm1控件的OnComm事件如下:

Blob s

String s1

Long i

s = mscomm1.object.Input

if len(s)=4 then

//正常处理程序

Else

for i=1 to 4

s1=string(blobmid(s,i,1))

if len(s1)=0 then

//此时第i位为char(0)字符,转入相应处理程序

else

//正常处理程序

end if

next

end if

再次测试,微机能够读取全部状态数据。

1.4 自定义PB中的位操作函数

到目前为止,我们获取的每一字节数据都包含了8台机器某一时间的状态,但是当我想查询某一台机器的状态时,就很不方便了,因为PB没有专门的位操作函数。只好自己编写了,基本思路如下:

A.先将字符转化位十进制数;

function long f_bin2dec (string as_binary);

integer li_cnt

long ll_len

char lch_char[]

long ll_decimal=0

If IsNull(as_binary) or Len(as_binary)<=0 then

long ll_null

SetNull(ll_null)

Return ll_null

End If

ll_len = Len(as_binary)

lch_char = as_binary

For li_cnt = 1 to ll_len

If (Not lch_char[li_cnt]='1') AND (Not lch_char[li_cnt]='0') Then

Return -1

End If

ll_decimal = ll_decimal + (long(lch_char[li_cnt]) * (2 ^ (ll_len - li_cnt)))

Next

Return ll_decimal

end function

B.再用"除二取余法"取出十进制数指定位的0、1状态

function integer f_getbit (long as_decimal, unsignedinteger ai_bit);

// ai_bit取值为1-8

int lb_null

IfIsNull(as_decimal) or IsNull(ai_bit) then

SetNull(lb_null)

Return lb_null

End If

If Int(Mod(as_decimal / (2 ^(ai_bit - 1)), 2)) > 0 Then

Return 1

End If

Return 0

end function

2 结束语

至此,本程序已完结,但通过这次调试程序, 笔者发现PB的功能应该还不止于此,例如:

(1)加入按位输出的函数,PB即可给下位机发送控制信号。

(2)加入将读取的数据转化为ASCII码,BCD码等的功能,PB即可处理下位机发送的大量数据并将其转化为正确的格式。

(3)PB还支持将串口当作一个文件一样的打开、写入,这对于要往串口输出大量有格式文本时特别方便,比如超市收银台的票据打印机就有许多是串口打印机。

综上所述,PB提供的插入OLE Control功能完全可以弥补它本身的一些不足之处,只要我们多思考,多测试,PB是可以在工业控制领域获得更多的应用。

Application of PowerBuilder Serial Port Communication Technology

Sun Xiang

Abstract:PowerBuilder does not have a direct parallel string operation functions, but also not directly on the binary data bit manipulation functions, then in the industrial control arena PowerBuilder does not it? These papers present a program, and in practice the success of the application.

VxWorks下多串口通信设计 篇7

本嵌入式系统在传输距离远电缆较长时使用的是RS485广播方式,在近距离传输时使用的是RS422方式,实现数据容量较大的通信,用RS232实现VxWorks编译环境Tornado下的宿主机-目标机的连接、下载和调试.该多串口通信系统使用的主要硬件是盛博公司的基于PC104总线的SEM/MSP-8多串口卡.

1 硬件设置

SEM/MSP-8采用2片TG16C554芯片,共有8个串口,Port1~4 RS232/RS422/RS485/TTL可选 ;Port5~8 RS-232/RS-485/TTL可选,根据需要可以扩展到12个串口.带有16 B的 FIFO,标准配置下可以达到115 200bps,+5 V电压,8个串口的基地址和中断选择上电时从EEPROM中读取数据配置,上电后可通过软件配置.首先进行多串口板上的跳线设置,JP1,JP1a,JP2,JP2a,分别为设置Port1~Port8工作在RS232/RS422/RS485方式.D、C、B、A为基址地址设置,根据实际,这里基址设为0x100, D、C、B、A对应值为1 011,其中1表示短接,0表示断开.2,3,4,5,…,15为中断号,要使用哪个中断就将其跳为1,最好加上中断匹配电阻(通过J8设置).在此用到5,6,11三级中断.JCK为频段范围跳线,跳上时串口的工作频率是原来不跳上时的1/4[2].

跳线设置见图1.

Port1~Port4,为RS422工作方式 ,中断级别为5;Port5、Port6为RS485,中断号为6;Port7设置为RS232,中断号为11;Port8备用.其中Port1~Port4与通信的另一端为一一对应的关系,RS485因为可以广播,一个串口上对应的通信另一端又带了几个RS485端.如图2所示.

2 软件设计

软件设计包括初始化设计,接收方软件设计和发送方软件设计,其中发送方软件设计分为RS232/RS422发送方设计和RS485发送方设计.使用模块化的设计方法,在开发期间应用了数据流程图[3].

2.1 初始化软件设计

EMM8在系统启动时会从板上的EEPROM中读取各个端口的基本配置信息,主要是端口映射地址及分配的中断号,这些信息可以在启动后编程修改,在此设置串口的基地址为0x300,还可以通过对EEPROM的读写,用来对串口板进行上电自检.ACE串行通信口有一个可编程波特率发生器,以1到(216-1)为除数因子将时钟(1.843 2 MHz)分频,分频输出值(即串口通信的波特率)=时钟频率/(除数因子×16).2个8位除数因子锁存寄存器以16位二进制格式存储除数因子.(DLM高8位,DLL锁存除数因子的低8位).

软件流程如图3所示.

具体对各个寄存器的操作见源代码注释:

sysOutByte(BASEADDRESS+0,0x80+i);/*BASEADDRESS为板上硬件跳线确定的地址,在此为0x100,0x80使能最高位,i为串口号 */

sysOutByte(BASEADDRESS+1,COMBASE[i]>>3);/*设置的串口地址 */

sysOutByte(BASEADDRESS+0,0x88+i); /*0x8+i*//*写入存放串口i-1的中断选择的内部寄存器*/

sysOutByte(BASEADDRESS+1,LOADINT);/*设置中断号*/

sysOutByte(COM7BASE+3,0x9b); /*设置

通信格式,8-E-1*/

sysOutByte(COM7BASE+0,0x02);/*高位为0,低位为2*/

sysOutByte(COM7BASE+1,0x0);/*设置波特率9 600*/

sysOutByte(COM7BASE+4,0x09); /*使能外部中断和/DTR*/

sysOutByte(COM7BASE+1,0x05); /*外部数据接收中断置有效*/

intConnect(INUMTOIVEC(INTVECGET(LANUCHINT)),(VOIDFUNCPTR)BombINT,0); /*挂接中断服务程序, */

sysIntEnablePIC(LANUCHINT); /*开中断*/

2.2 接收软件设计

VxWorks系统中,在中断服务程序里不能有printf打印、取信号量、接收消息等,因为这些操作可能引起任务的阻塞.但是可以发送信号量,发送消息,在中断服务程序中应该尽可能地使用简单的原语操作,以便节省开销,同时提高可靠性,最好就是一个SemGive.在此把接收到的字符加入到环形缓冲中rngBufPut();也可以发送消息通知任务接收.根据具体的情况,可以添加一些容错处理.比如,每次退出中断前将接收缓冲寄存器(RBR)读空,退出中断时加一定很小(指令级)的延时:

for(ii=0;ii<0x400;ii++){}

软件流程如图4.

2.3 发送软件设计

RS232,RS422,RS485因为具体的电气和线路特征不一样,收发数据各不相同.抽象到软件层面,RS232和RS422可以看成相同的处理.它们发送软件具体源代码如下:

void BombSend422(void) {

while(i

if((sysInByte(COMBASE[i]+5))&0x20) {

sysOutByte(COMBASE[i],SendData[i]);

i++;

j=0; }

j++;

if(j>10 000) break; }

RS485在发送时,要先切换工作方式,然后才发送数据,最后把工作方式切换为接收.需要特别指出的是,RS485接收端和发送端的通信握手很重要,在一对正负线(L+、L-)上,不能同时又有接收又有发送,否则有可能烧毁硬件或者造成硬件工作不规则,通过示波器会看到波形失真,可能影响到系统的整体性能甚至是致命的错误. 具体在发送过程中,还要判断发送移位寄存器是否为空的TEMT位,在它为空时才表示发送缓冲区的数据已经完全送出,并且在发送完毕后加一定的延时,将其电平转换准备接收,然后才切换为接收方式:

bb=sysInByte(COMBASE[i]+5);

if(bb&0x40) /*判断TEMT位*/

{ /*发送数据*/}

for(ii=0;ii<0x400;ii++){}/*延时*/

sysOutByte(COMBASE[i]+4,0x09); /* 设置为接收方式

软件流程如图5.

3 设计中的注意问题

(1)串行字符的接收打包问题

字符设备和块设备相比,块设备可以对整个消息帧进行发送和读取,在编程实现时会相对的方便.字符设备每次收发只能按单个字符进行,其中一个不正确的字符可能干扰到整个通信系统工作不正常,尤其是报文格式不定长的时候.为此,对字符设备组成的报文进行分析很重要,需要一些容错处理.通常在一帧报文或者一个命令格式上,头2个字节加上报头、命令字,末2个字节加上校验和、结束符.接收时,判定报文的总长度,再加上以上的打包字节,这样在一帧数据中间多了几个字符的情况下,可以抛弃此帧数据,而不会连续的影响到下几帧.或者在头几个字符不正确的时候,可以滤掉多余的字节或者乱码,得出后边的正确报文.

(2)硬件进行初始化

直接在应用程序中对硬件进行初始化,而没有在板级驱动包(BSP)中.当存在多个中断但是中断级别又相同时,可以根据各个串口的不同地址来识别.在发生较多中断的时候,要对某些口进行一些读空操作,以免阻塞.

(3)看门狗的使用

此处延时很短,只用到了指令级,毫秒级以上定时使用看门狗定时器比较好,尤其在一些对实时要求比较高的场合.因为在VxWorks中,看门狗定时器是作为系统时钟中断服务程序的一部分来维护的,通常与它相联系的函数以系统时钟中断级作为中断服务代码来执行.用wdStart()启动看门狗进入延时状态,一旦计时结束,它将调用一个有wdStart()指定的一个中断服务程序,与taskDelay()延时不同,该中断服务程序在任务的上下文之外执行.所以taskDelay()可能会存在一定误差.

4 结 束 语

风河公司的VxWorks实时操作系统可靠性高,比WindowsCE的实时性好,相对于开源的嵌入式Linux,VxWorks编译环境Tornado更加简单和人性化,它已经成功应用于火星探测器和其他实时的高可靠系统中.多串口通信嵌入式系统使用了RS485的广播,Tornado下实现宿主机-目标机的连接使用RS232,它的不足之处就是下载到目标机进行调试的速度比较慢.软件固化到Doc上后,经实践证明,整个系统响应时间快,工作稳定可靠,通信流畅,满足了预期的要求.

参考文献

[1]孔祥营,柏桂枝.嵌入式实时操作系统VxWorks及其开发环境Toanado[M],2002:21-27.

[2]朱德森.微型计算机(80486)原理及接口技术[M].2003:279-288.

基于串口通信的控制系统设计 篇8

1 VB环境下的串口通信

1.1串口通信

在VB环境中,利用串口可以实现计算机设备之间的相互通信。通常情况下,主要有2种通信方式:①利用Windows提供的API函数;②利用VB提供的MSComm控件。虽然前者实现方法简单,但设计过程相对复杂,工作量比较大,对程序员有较高的要求。尽管后者实现过程比较复杂,但由于微软对其处理过程进行了封装,并向用户提供了方便的接口,因此,使用操作比较简单,只需简单地嵌入就能完成复杂的串口通信任务,设计工作量比较小,效率较高,是程序设计比较理想的方法。

1.2 MSComm控件

MSComm是一种串行通信控件,它提供事件驱动和检查CommE vent属性两种处理通信的方式。在VB 6.0系统中,通过部件设置可以将该控件添加到工具箱中,以便在设计界面中引用,通过属性设置和操作实现串口数据的发送和接收。

在数据传输和控制应用中,MSComm控件常用的属性有以下几点:①Comm Port,设置并返回通信端口号;②Settings,以字符串的形式设置并返回波特率、奇偶校验、数据位和停止位;③Port Open,设置并返回通信端口的状态——打开或关闭;④Input,从接收缓冲区返回并删除字符;⑤Output,向传输缓冲区写一个字符串。

2串口通信的信号连接

在台式计算机后部面板上,通常有一两个串行通信接口,其外部形状为梯形公插头结构,根据插针的数量可以分为25针和9针2种。前者多见于早期的AT架构计算机。目前,ATX架构计算机的串口均采用9针接口,其结构如图1所示。

9针串口各引脚的功能分别为:载波检测(DCD)、接收数据(RXD)、发送数据(TXD)、数据终端准备好(DTR)、信号地(GND)、数据准备好(DSR)、发送请求(RTS)、发送清除(CTS)、振铃指示(RI)。

通常情况下,在计算机之间进行一般的数据传输时,如果没有特别要求,只要正确连接2,3,5引脚便可。其连接方法是:2台计算机对应串口的2,3引脚相互交叉,5引脚直接连通,具体如图2所示。

3控制系统设计

3.1设计方法

在设计控制系统时,可以通过串口实现计算机之间的相互控制,其具体方法是:①从市场上购买一对如图1所示的9针串口梯形母插头,按照图2所示的连接方法用信号线连接2个插头;②选择2台需要互联的计算机的空闲串口,用做好的串口连线连接;③选择其中一台计算机作为主控机,另一台作为被控机;④在主控机上安装并运行主控程序,选择连接的串行端口,由对应的串口向被控机发送控制指令;⑤在被控机上安装并运行被控程序,选择连接的串行端口,经由对应的串口等待并接收来自主控机的控制指令;⑥当被控机串口接收到主控机发来的控制指令后,根据预设的指令功能执行控制操作,实现系统控制。

3.2主控端程序设计

假设需要通过主控机对被控机完成下列3项控制功能:打开媒体播放器、打开记事本、关闭计算机,则主控机的控制指令可以通过2台计算机的串口实现传递。因此,要先通过用户界面选择所使用的串行端口号,设计界面如图3所示。

为了实现串行通信的数据传输和端口控制,程序设计时需要在界面中添加一个MSComm控件,通过界面选择通信用“串口号”,通过“打开串口”按钮,打开对应的串行端口。设MSComm控件的实例名为MSComm1,选择的串口号为1,则相应的设置语句为:MSComm1.CommP ort=1,MSComm1.PortO pen=True.

在图3所示的样例中,如果要“打开媒体播放器”,则点击相应的按钮,通过执行下列语句便可实现控制指令由主控机向被控机的发送:MSComm1.Output="MediaP layer".

3.3被控端程序设计

被控端程序与主控端程序一样,运行时也要通过MSComm控件对端口进行初始化操作——选择端口、打开端口,然后定时检测对应串口的工作状态。

为了实现对端口状态的检测,需要增加一个定时器控件,定时检测相应串口是否有新的数据到达,以便及时处理。定时时间可根据用户需要设置。

设程序中添加的定时器控件实例名为Timer1,则相应的被控程序部分代码如下:

在该程序运行的过程中,当接收到来自串口的一组数据时,系统便自动分析判断。如果是一条预设的控制指令,则执行对应的功能,否则不予处理。在本例中,如果接收到的是一个字符串“Media Player”,则程序通过shell语句直接调用,并执行本机中的wmplayer.exe程序,打开媒体播放器。

3.4控制测试

按照上述方法,用串行线连接好主控计算机和被控计算机相应的串口1端口,打开2台计算机,在主控计算机上运行测试程序,进入图3所示的控制界面,点击“打开串口”按钮。此时,便建立了2台计算机的通信连接。然后点击“打开媒体播放器”按钮,此时,在被控计算机上便可自动播放Windows系统自带的媒体播放程序。同样,在图3界面中点击“打开记事本”按钮,也可以迅速控制被控计算机运行记事本程序,实现预期的控制效果。

多次试验表明,该程序运行稳定、可靠,在远程控制系统设计中既简单又实用,具有较高的应用价值。

3.5说明

采用串口通信实现计算机控制的关键是正确设置串口通信控件MSComm。在具体工作中,需要重点注意以下几个方面的问题:①根据控制信号的物理连接,正确选择并打开相应的串行端口。②针对不同的终端设备,采用控件的Settings属性正确设置数据传输的波特率、奇偶校验、数据位、停止位。在缺省的情况下,控件按默认参数自动设置。③当系统需要通过串口传输大量数据时,为了保证在缓冲区过载时数据不会丢失,需要通过控MSComm件的Handshaking属性设置相应的通信协议(即握手协议),通过控件的OnC omm事件捕获并处理相关的通信事件,检查设备连接和通信是否正确,确保控制系统的稳定、可靠。此时,图2所示连接的串行线已经不能满足需要,还需要正确连接RTS、CTS、DSR、DTR等信号线。

4结束语

由此实例可知,利用串口通信的数据传输功能可以方便地实现计算机之间的系统控制。由于该方法硬件连接简单,软件设计灵活,可靠性高,因此,将其应用于工业、家用电器、办公等自动化和嵌入式应用中,可以快速实现数据采集和设备控制,具有广阔的应用前景。

参考文献

[1]杜正杰,王卫锋.基于串口实现DCS数据的安全采集[J].测控技术,2014,33(3):45-48.

[2]刘建河,赵玉丹,张玉强.基于LABVIEW串口通信的电机控制技术[J].制造业自动化,2013,35(11):135-137.

[3]李志伟,铁跃焕,杨茂兴.基于串行指令的红外探测远程控制系统设计[J].计算机工程与设计,2014,35(4):1486-1490.

串口设计 篇9

串行接口的应用非常广泛, 为实现串口通信功能一般使用专用串行接口芯片, 但是这种接口芯片存在体积较大、接口复杂以及成本较高的缺点, 使得硬件设计更加复杂, 并且结构与功能相对固定, 无法根据设计的需要对其逻辑控制进行灵活的修改。介绍了一种采用FPGA实现串口通信的方法。

1 串口通信协议

对一个设备的处理器来说, 要接收和发送串行通信的数据, 需要一个器件将串行的数据转换为并行的数据以便于处理器进行处理, 这种器件就是UART (Universal Asynchronous Receiver/Transmitter) 通用异步收发器。作为接口的一部分, UART提供以下功能:

1.1 将由计算机内部传送过来的并行数据转换为输出的串行数据流;

1.2 将计算机外部来的串行数据转换为字节, 供计算机内部使用并行数据的器件使用;

1.3 在输出的串行数据流中加入奇偶校验位, 并对从外部接收的数据流进行奇偶校验:

1.4 在输出数据流中加入启停标记, 并从接收数据流中删除启停标记。

2 UART模块设计

UART主要由UART内核、信号检测器、移位寄存器、波特率发生器、计数器、总线选择器和奇偶校验器7个模块组成。 (见图1)

2.1 UART内核模块

UART内核模块是整个设计的核心。在数据接收时, UART内核模块负责控制波特率发生器和移位寄存器同步的接收并且保存RS-232接收端口上的串行数据。在数据发送时, UART内核模块首先产生完整的发送序列, 之后控制移位寄存器将序列加载到移位寄存器的内部寄存器里, 最后再控制波特率发生器驱动移位寄存器将数据串行输出。

2.2 信号检测模块

信号检测器用于对RS-232的输入信号进行实时检测, 一旦发现新的数据则立即通知UART内核。需要注意的是, 这里所说的RS-232输入输出信号都指经过电平转换后的逻辑信号, 而不是RS-232总线上的电平信号。

2.3 移位寄存器模块

移位寄存器的作用是存储输入或者输出的数据。

2.4 波特率发生器模块

由于RS-232传输必定是工作在某种波特率下, 比如9600, 为了便于和RS-232总线进行同步, 需要产生符合RS-232传输波特率的时钟。

2.5 奇偶校验器模块

奇偶校验器的功能是根据奇偶校验的设置和输入数据计算出响应的奇偶校验位, 它是通过纯组合逻辑来实现的。

2.6 总线选择模块

总线选择模块用于选择奇偶校验器的输入是数据发送总线还是数据接收总线。

2.7 计数器模块

计数器模块的功能是记录串行数据发送或者接收的数目, 在计数到某数值时通知UART内核模块。

3 UART程序设计

UART完整的工作流程可以分为接收过程和发送过程两部分。

接收过程是指UART监测到RS-232总线上的数据, 顺序读取串行数据并将其输出给CPU的过程。当信号监测到新的数据 (RS-232输入逻辑变为0, 即RS-232传输协议的起始位) 就会触发接收流程。首先UART内核会重置波特率发生器和移位寄存器, 并且设置移位寄存器的工作模式为波特率模式, 以准备接收数据。其次, 移位寄存器在波特率时钟的驱动下工作, 不断读取RS-232串行总线的输入数据, 并且将数据保存在内部的寄存器内。接收完成后, UART内核会对已接收的数据进行奇偶校验并且输出校验结果。最后, UART内核会重置信号检测器, 以准备进行下一次数据接收。

发送过程是由加载和发送两个步骤组成。加载步骤是UART内核按RS-232串行发送的顺序将起始位、数据位、奇偶校验位和停止位加载到移位寄存器内, 这个过程工作在系统时钟下, 相对于RS-232传输速度来说非常快。完成加载步骤后, UART内核会重置波特率发生器, 并且设置移位寄存器工作在波特率模式下, 于是移位寄存器便在波特率时钟的驱动下依次将加载的数据发送到RS-232的发送端TXD, 这样就产生了RS-232的数据发送时序。

4 FPGA实现

把实验板上电, 下载完成后在PC上打开串口调试助手, 在上方接收区的串口选择COM1, 波特率选择115200, 校验位选择无校验位, 8个数据位1个停止位。每按下reset, 可以在接收区看到FPGA通过串口向PC发送的一个字符串“welcome to wzu”。测试结果验证了程序的准确性。

5 结论

采用FPGA实现串口通信功能将给产品设计研发带来极大方便, 并且可以降低成本, 这种采用可编程逻辑器件代替硬件实现协议功能方案也是未来电子产品开发的发展趋势。

参考文献

[1]韩德红.基于FPGA的串口控制器设计与实现[J].空军雷达学院学报, 2008, 6 (02) :113-116.

[2]蒋璇, 臧春华.数字系统设计与PLD应用[M].北京:电子工业出版社, 2005.

基于串口通信的电站监控系统设计 篇10

小型固定及方舱电站作为应急备用电源系统, 已在银行、医院、移动通信、部队等许多领域和场合得到广泛应用。对于无人职守的备用电站, 要求电站不但能可靠、连续不间断地工作, 还要有一定的通信能力, 以实现对电站的远程 (集中) 控制及检测功能, 方便用户使用及维护。

在实时控制系统和自动化测量系统中, 串行通信是实现计算机与控制系统数据传输的主要通信手段。因此, 本文采用PLC与PC机之间的串行通信方式, 实现电站的“三遥”功能, 即远程在线实时监控电站的运行状态、性能参数及故障信息, 远程在线修改电站的保护及控制参数, 并实现对电站的启停控制。

1 系统功能要求

电站本机需设计为一个符合GB12786—91《自动化柴油发电机组通用技术条件》和GB/T4712—96《自动化柴油发电机组分级要求》的单机应急自动化电站控制系统[1,2]。系统远程监控功能:

(1) 遥测:发电机组的三相电压、三相电流、频率、输出功率、冷却水温度、机油压力及蓄电池电压, 旋转UPS (不间断电源) 的三相电压、频率。

(2) 遥信:工作状态, 工作方式, 电压/电流/频率故障, 水温高、油压低及燃油位低故障。

(3) 遥控:开/关机及ATS开关转换。

(4) 保护及控制参数修改:电压/电流/频率故障保护动作值、电站操作人员开机密码及电站初始状态。

2 系统总体结构

电站监控系统的总体结构如图1所示。

该系统的设计主要从通信传输方式、本机控制单元 (发送端) 和远端显示控制单元 (接收端) 入手。其中发送端是整个系统的核心部分。基于电站“三遥”功能要求复杂、可靠性高的特点, 经过多种技术方案的分析比较, 最终选用性价比适中的西门子SIMATIC S7-200 (CPU226, 2个RS485通信口) 型PLC作为发送端控制器, 该控制器提供的RS485串行通信接口可支持PPI、MPI、Profibus和自由模式下的用户定义通信协议。接收端采用带有RS232接口的PC机。RS232接口与RS485接口通过PLC的PC/PPI电缆实现转换。

3 发送端设计

3.1 硬件设计

发送端主要由S7-200 PLC, 电压、电流等传感器 (或变送器) 和执行元件组成, 如图2所示。

发送端工作原理:将发电机组的电压、电流、频率信号经各自的变送器转换为+5 V直流电压, 作为PLC模拟量输入信号;转速采样通过安装在发动机飞轮壳上与飞轮齿面垂直的磁性传感器测得, 磁性传感器与发动机飞轮齿顶的距离为0.5~1 mm, 传感器输出交流脉动信号, 该信号经整形后进入PLC高速计数口I0.2, 从而实现对电站发动机转速的监测功能;电站循环水温度传感器、机油压力传感器的输出为开关量, 可直接进入PLC的开关量输入口。PLC对采集的各参数进行比较、运算处理后, 得出机组及市电的工作状态。旋转UPS的工作参数通过RS485通信端口传输到PLC, PLC根据这些工作状态判断机组、旋转UPS是否投入运行, 并自动完成市电与旋转UPS、旋转UPS与机组电之间的相互切换[3,4]。

3.2 软件设计

3.2.1 软件程序流程

发送端软件设计是指PLC梯形图的编制。该软件主要完成对电站及旋转UPS参数的采集、运算、判断及控制功能, 其工作流程如图3所示。

3.2.2 PLC设置

(1) 串行通信口配置

系统采用PLC自由模式下的用户定义协议, 即用户用编制的梯形图程序来调用接收中断、发送指令、接收指令等通信操作。S7-200 PLC带有2个串行通信口, 可通过特殊寄存器SMB30 (端口0) 和SMB130 (端口1) 来配置自由模式下的通信参数。本系统采用端口0完成PLC与PC机的通信, 配置为SMB30=9, “9 600, N, 8, 1”, 即选择自由口协议、波特率为9 600 bit/s、每个字符为8 bit、不校验。

(2) 接收信息控制配置

系统通过对特殊寄存器SMB87、SMB88、SMB89、SMW92和SMW94的配置, 检测PC 机传输信息的起始字符、结束字符等信息, 以保证读/写字符的正确性。接收信息控制配置如表1所示。

4 接收端设计

系统采用一台PC机作为接收端, 实现电站“三遥”功能。本文主要介绍接收端监控软件的设计。

监控软件采用VB语言编制。VB提供了一个MSComm串行通信控件[5,6], 其属性描述及设置如表2所示。

在设置完MSComm控件后, PC机即可通过COM0口发送指令到PLC的PORT0 (或PORT1) 口, 发送的指令格式为33字节, 格式如表3所示。

启动监控程序后, PC机通过多个定时器不断地轮流读取PLC传来的数据, 每个定时器每次读取8字节数据, 并根据需要将这些数据显示在监控主界面上, 如图4所示。监控主界面主要包括菜单设置、状态显示、故障显示、参数显示、操作控制、发电机组额定参数、工作状态提示及系统时钟显示八部分。各部分的主要功能:

(1) 菜单设置:

为方便用户操作及使用, 监控主界面设计了运行、系统参数 (额定参数、电流变比、发动机齿数、启动时间) 设定、电气保护参数 (过电压、欠电压、过频率、欠频率、过电流) 、油机保护参数 (超速) 、设置操作密码及帮助6个下拉式主菜单。通过点击菜单可弹出相应设置窗体, 以重新设定参数、操作密码等。

(2) 状态显示:

对电站工作状态 (机组供电、运行等) 进行实时显示。

(3) 故障显示:

定时读取PLC故障状态显示寄存器各标志位及故障保护参数存储器, 实时显示电站的故障类型。

(4) 参数显示:

对电站及旋转UPS工作参数进行实时显示。

(5) 操作控制:

发送 (写) 启动/停机指令给PLC相应寄存器, 控制机组的启停。

(6) 电站额定参数:

上电读取PLC相应寄存器单元参数, 以提醒用户正确使用电站。

(7) 工作状态提示:

定时读取PLC工作状态标志寄存器, 用滚动条的方式不断显示电站实时工作状态及提示用户下一步操作。

(8) 系统时钟:

显示时间。

5 系统特殊设计

根据现场使用特点, 相比国内外同类产品, 该系统在任务保障性、可维修性、可操作性方面进行了特殊设计。

(1) 任务保障性:

系统具有应急、手动及自动3种控制方式。这3种方式分层次设计, 可通过一键转换独立运行, 保障了电站在紧急情况下的应急供电。

(2) 可维修性:

系统引入了专家诊断设计, 即电站发生故障后, 在本地及远端都有自动语音提示, 可提示电站故障发生的类型、故障点及排除方法, 增强了电站的可维修性。在接收端的实现方法:根据故障代码判定故障类型, 借助PC机上的声卡和VB中的MMControl多媒体控件, 执行以下代码:

6 结语

利用PLC及串行通信技术设计了一种电站监控系统, 实现了电站“三遥”及参数修改功能。该系统可应用于各种型号、功率的电站上, 如低噪声智能多制式电站、75 kW低噪声汽车电站、150 kW自行式大功率电站等, 操作方便, 性能可靠。此外, 该系统的接收端监控软件还可嵌入到大型分布式控制系统的监控软件中, 作为其监控程序的一部分, 以完成设备集中化管理任务。

参考文献

[1]GB12786—91自动化柴油发电机组通用技术条件[S].1991.

[2]GB/T4712—96自动化柴油发电机组分级要求[S].1996.

[3]王胜洪, 孙晓静, 谭坚.柴油发电机组PLC控制装置[J].移动电源与车辆, 1999 (1) :17-19.

[4]谭景文, 孙晓静, 姚琪.自动化低噪声汽车电站的研制[J].移动电源与车辆, 2003 (1) :10-12.

[5]范逸之, 陈立元.Visual Basic与RS-232串行通信控制[M].北京:清华大学出版社, 2002.

串口设计 篇11

关键词:单片机;RS-232;PC机;实时数据采集

中图分类号:TP368 文献标识码:A 文章编号:1674-7712 (2012) 16-0066-01

一、单片机与PC机串行通信的硬件系统连接

二、串口通信的通信协议

考虑到小型分散测控系统采用主从式控制结构的实际情况,可将多个单片机的通信模式设置为模式1与PC机进行远程串行通信。当PC机启动通信功能并对某一单片机实现功能控制时,将每一片单片机设置一个片识别地址,也就是站号,只有当PC机发送的信号中的地址位与单片机中的片识别地址相一致时,该单片机才能根据接收信号对PC机做出响应,按系统要求向PC端发送应答数据。

具体的寻址实现可以采用软件查找方法:单片机可以提供位寻址区,假如该单片机的寻址标志位被置为“1”,表示该单片机可以对PC端的数据进行接收;假如寻址标志位为“0”,表示该单片机无法响应PC端请求。通过对标志位的判断结果决定是否将单片机地址与PC机地址进行比较,只有地址一致的单片机才可以将寻址标志位置为“1”,然后退出中断服务程序;其他未响应单片机则直接退出中断服务程序。

在发送端和接收端的信息传输中需要进行信息校验,以保证传输信息的正确性和可靠性,一般情况下课采用累加和校验。只有校验结果正确时,收发端才能正确响应数据帧,进行数据的发送与接收,否则将反馈信息传输出错,要求发送端对数据进行重新发送。为防止“锁死”现象的出现,该校验方法需要限定重发次数,在限定次数内发送的数据可被认定为有效,超出限定次数可认为发送失败,跳过该数据传输,或结束通信返回失败信号。

三、相应的软件编程实现

在实现程序上,单片机端的通信程序采用MSC51汇编语言编程,通过中断响应的方式实现数据通信,其通信方式可通过技术手册获得;PC机端的通信程序可以采用VB编程方式实现数据通信,其通信方式采用事件驱动方式。通过MSCComm控件可以对串口进行初始化、收发数据等串行通信功能实现。

四、结语

在实际的工业过程中单片机与PC机的通信应用非常广泛。本文系统具有一定的通用性,在实际应用中可根据实际需要对相关部分进行修改,满足实际要求。实践表明,本文系统稳定可靠,能够满足单片机与PC机串行通信中的实时采集数据和控制的要求。

参考文献:

[1]甄任贺,俞寿益.单片机与PC机串行通信的实现方法[J].广东技术示范学院学,2004,6.

[2]潘方.RS 232串口通信在PC机与单片机通信中的应用[J].现代电子技术,2012,35.

单片机与组态王串口通信的设计 篇12

随着工业化要求提高, DCS控制系统发展日趋成熟, 组态软件设计的监控系统逐步普及。组态软件作为平台开发工具可以为用户定制功能。

组态王软件具有友好的人机操作界面、强大的IO设备端口驱动能力, 可与各种PLC、智能仪表、智能模块、板卡、变频器等设备实时通讯。由于在检测大量模拟量的工业现场使用PLC与组态软件通讯势必增加产品成本。而单片机接口丰富, 与A/D转换模块组合可以完成相同的工作, 并且系统可靠、成本低。

2 研究环境

组态王软件内置了通用的单片机通信模块, 客户自己开发的单片机仪表可以挂接在组态王上。组态王与单片机能够正常通讯, 需要组态王6.5监控软件, 以及单片机开发相关的Keil软件和Porteus软件。另外, 初期的研究工作可以利用Virtual Serial Ports Driver XP 5.1虚拟串口软件, 用此软件可以生成一对相互联接的虚拟串口, 这样, 初期的研究工作就在电脑上完成, 省去在硬件电路板上实验的繁琐。

3 PC机与单片机的硬件接口电路

图1是PC机与单片机的硬件接口电路, 在连接过程中单片机的TXD连接虚拟串口的TXD, 单片机的RXD连接虚拟串口的RXD, 注意不要交叉。

通过网上搜索, 用户可以找到了这个VSPD, 它的使用步骤如下:

在first后面选一个串口名, 然后在Second后面再选一个串口名, 然后点一下Add Pair即可。com1串口是真实存在的物理串口, 使用VSPD也可以把com1串口给虚拟了。这里选的是com2串口和com4串口, 选择以后可以看到在左侧的窗口中出现了这样一对互联的串口, 即从com2串口发送数据, 然后com4串口就能接收到, 同样, 从com4串口发送数据, 然后com2串口就能接收到。

4 组态王软件设置

在组态王工程管理器中打开已经创建好的工程, 在工程浏览器树状图中选择“设备—DDE—新建”, 在“设备配置向导”中选择“单片机—通用单片机ASCII—串口”, 给串口设备起个名字, 然后选择com4串口号,

在选择地址时, 需要为自己的单片机设备确定一个地址, 需要看一看地址帮助。如果在同一个串口上连接多个单片机设备, 那么就需要确定究竟与哪一个设备通信, 这就需要有个地址, 这是上面取的地址2.0中的2的由来, 而小数点后面可取0/1, 按组态王的介绍是打包还是不打包, 在这里选择不打包, 所以先取0。

5 程序编写

5.1 通讯口设置

通讯方式:RS-232, RS-485, RS-422均可。

波特率:由单片机决定 (2 4 0 0, 4 8 0 0, 9600and19200bps) 。

字节数据格式:由单片机决定。

注意:在组态王中设置的通讯参数如波特率, 数据位, 停止位, 奇偶校验必须与单片机编程中的通讯参数一致。

5.2 在组态王中定义设备地址的格式

格式:##.#

前面的两个字符是设备地址, 范围为0-255, 此地址为单片机的地址, 由单片机中的程序决定;

后面的一个字符是用户设定是否打包, “0”为不打包、“1”为打包, 用户一旦在定义设备时确定了打包, 组态王将处理读下位机变量时数据打包的工作。

5.3 在组态王中定义的寄存器格式

斜体字dd代表数据地址, 此地址与单片机的数据地址相对应。

注意:在组态王中定义变量时, 一个X寄存器根据所选数据类型 (BYTE, UINT, FLOAT) 的不同分别占用一个、两个, 四个字节, 定义不同的数据类型要注意寄存器后面的地址, 同一数据区内不可交叉定义不同数据类型的变量。为提高通讯速度建议用户使用连续的数据区。

5.4 组态王与单片机通讯的命令格式:

读写格式 (除字头、字尾外所有字节均为ASCII码)

字头:1字节1个ASCII码, 40H。

设备地址:1字节2个ASCII码, 0—255 (即0---0x0ff H) 。

标志:1字节2个ASCII码, bit0~bit7。

bit0=0::读, bit0=1:写。

bit1=0:不打包。

bit3bit2=00, 数据类型为字节。

bit3bit2=01, 数据类型为字。

bit3bit2=1x, 数据类型为浮点数。

数据地址:2字节4个ASCII码, 0x0000~0xffff。

数据字节数:1字节2个ASCII码, 1—100, 实际读写的数据的字节数。

数据:为实际的数据转换为ASCII码, 个数为字节数乘2。

异或:异或从设备地址到异或字节前, 异或值转换成2个ASCII码。

6 结束语

该设计方法实现组态王软件与单片机的实时通信, 已经在实际项目中得到应用。应用的结果表明该设计方法简单有效, 实时性好, 成本低廉, 可以在控制与监控系统中推广应用。

参考文献

[1]刘杰, 王慧.组态王与单片机多机串口通讯的设计[J].电子设计工程, 2009年第7期.[1]刘杰, 王慧.组态王与单片机多机串口通讯的设计[J].电子设计工程, 2009年第7期.

上一篇:药物政策下一篇:推荐内容