关于GPIO实现RS485/422通信的研究

发布者:SereneMelody最新更新时间:2015-06-19 来源: eepw关键字:GPIO  RS485  422通信 手机看文章 扫描二维码
随时随地手机看文章
1.引言

工程实践中,对于解决同一个问题,我们常面临两种选择:要么硬件简单软件复杂,要么软件复杂硬件简单。如某引信系统的DSP电路,需要与内部两个组部件以及外部多个系统进行接口或者信息交互,且总体要求采用异步串口方式进行通信。此类问题主要有三种解决方案:第一,在DSP的并行总线上扩展UART芯片,通过硬件转换实现,软件最简单;第二,在DSP的McBSP串行总线上扩展UART芯片,软件有一定的复杂度;第三,不扩展其他硬件直接利用IO引脚通过软件控制实现,该方法软件最复杂。根据以往文献可知在硬件资源允许的前提下,前两种方法已经得到了广泛的研究。

然而在产品的研制过程中,常出现引信硬件资源紧张的情况,无法扩展满足需求的UART,只能选择第三种解决方式,总体的高波特率和高可靠性要求增加软件设计的难度。笔者通过软件的合理设计,成功地解决了以上问题。

2.串行通信基本原理

串行通信的基本原理是以改变数字电平的方式将数据按照一定的时间宽度(波特率)按位(通常低位在前高位在后)顺序传输,分为同步串口和异步串口两类。同步串口通信主要应用于传输速率高但传输距离要求不高的场合,异步串口则侧重于传输速率要求稍低的情形。

图1给出了异步串行通信的数据基本格式,对于一个完整的字节,传输时包含起始位、数据位、校验位。

 

 

实现同步串口通信通常需要6根总线,即收、发数据线,收、发帧同步线,收、发位时钟线。而异步串口则最少可只需2条总线(最多4条)便实现数据通信,如果采用差分传输还可以有效地提高传输距离,根据能否同时收发数据又分为全双工和半双工两种工作模式。

图2是应用最普遍的串口形式之一的RS485/422串口总线,RS485半双工传输采用一对差分信号,由主控端的RE和DE来控制当前数据收发,收发不能同时进行;RS422全双工传输采用两对差分信号,主控端直接独立收发,且收发可同时进行。

 

 

本研究通过软件控制改变GPIO端口的状态,完成RS485/422串口通信的时序。

3.基本流程设计

为提高软件的质量和可维护性,收发通讯实现时均采用位、字节和帧三个处理层次。每层相对独立,低层处理的结果通过状态传递方式通知上一层。

研究中采用的数据传输格式:1bit起始位“0”,8bit数据位(先低后高),无校验位,1bit停止位“1”,每个字节累计为10bit.

3.1 发送通信流程

主动发送数据形式的流程如下:

1)底层:位发送。在波特率控制的时间间隔内将发送数据管脚置为和当前bit一致的电平状态。

2)中间层:字节发送,如图3所示。发送当前bit,发送完位计数器+1,如果位数达到10位,则当前字节发送结束,并通知顶层;3)顶层:帧发送,如图4所示。首先检测串口当前状态是否为发送允许,如果不是则将串口置为接收禁止、发送允许状态,确定了发送允许后进入帧发送。帧发送按照报文格式顺序发送各字节,发送结束将串口设为发送禁止、接收允许状态。

 

 

 

 

3.2 接收通信流程

接收通信需要把每一个bit的数据准确地检测出来,确定字节的起止位,判断帧的起止字节,也就是说通过分析和计算将数据格式和通信协议所规定的每一个细节精确定位。对于帧起始时刻的判断,根据图1数据格式知在数据传输的过程中,即使数据位为全“1”或全“0”,由于有起始位和停止位的存在,也不会出现连续10个bit的“1”或“0”的情况,于是当连续出现10个bit的“1”时,则数据线处于停止传输的状态;而连续出现10个bit的“0”时,则数据线处于异常状态。于是接收通信开始后至少连续10个bit的“1”之后的“0”可以作为帧的起始位。这里的“帧”不是指通信协议中的完整报文,只是指收到的一段数据,至于当前字节是否为报文头,则需根据协议判断。好处是不漏任何数据,可靠接收约定报文。

接收通信流程如下:

1)底层:位接收,如图5所示。位接收在由波特率确定的时间间隔到达时,采样接收数据线的电平状态作为当前bit值,同时判断帧起始位,帧开始后的位接收完成,通知中间层进行字节处理。

 

2)中间层:字节接收,如图6所示。当新bit接收完成时,将当前Bit值按照格式组合到字节数据。当字节位计数器满一个字节时,如果满足起始位“0”和停止位“1”的条件,字节接收完成,并通知顶层进行帧接收控制,否则字节无效。[page]

 

3)顶层:帧接收,如图7所示。首先检测串口当前状态是否为接收允许,如果不是则将串口置为接收允许、发送禁止状态,在确任接收允许后开始收数。在新字节接收完成后,将新字节写入接收缓冲区,同时根据通信协议启动报文识别,直到收到一帧完整的报文,结束接收通信。根据实际需要可以加入通信超时控制。

 

 

4.面向对象实现方法

在DSP中,对某一个GPIO管脚操作,需要对某一个寄存器的某一位进行置位或者清零。

为避免每次对管脚操作时去寻找寄存器的地址和位地址这个易出错的缺点,软件设计时采用C++类结构的方式进行数据封装,使用时只需在初始化时一次性的传入寄存器及其位地址,其余用处均采用交互性良好的助记符。

4.1 GPIO管脚类数据结构

在构建GPIO管脚类时,围绕寄存器以及位地址操作和电平操作进行。

软件数据类型与处理器的型号相关,本文采用TMS3206713处理器,为有效控制数制,将硬件支持数制和编译系统符号相对应,将C6000数据类型重定义,在GPIO操作中主要使用无符号数。

4.2 串口类数据结构

为了区分当前使用的串口类型,故定义串口类型号枚举,为串口操作程序提供识别入口。

由类的构造函数知,由于RS422和RS485所使用的管脚不同,为了将每种操作统一到一个函数中,采用了swtich结构,其他成员函数类似。其中发射函数Sending()对应图3、4中的流程,接收函数Receving()对应图5、6、7中的流程。

软件设计以定时器为中心,由使用目的属性来区分发送还是接收,以中断方式控制通信时序,能够实现全双工通信。在全双工通信中,当出现收发定时中断冲突的极端情况时,可设定发送优先,由于端口操作时间为纳秒级,接收滞后处理的影响可以忽略不计。

5.位检测与接收通信可靠性

由于每一个bit的检测结果直接决定着接收数据是否正确,按照波特率所确定的时间间隔对端口电平采样一次来确定bit的值来实现的软件,实验室拷机时存在误码现象,因此通过提高bit的检测能力,降低误码率。bit检测改进方法如下:

(1)接收通信的位采样仍然采用由波特率确定的时间间隔,但对于位检测时,采用读3次管脚电平然后进行表决的方式确定当前bit的值,有效降低了误码率,但仍有字节出错的问题,因为3取2的方式可以部分地剔除纳秒级的高频毛刺,但不能有效抑制强干扰引起的电平翻转,需进一步改进。

( 2 )将每一b i t检测的时间间隔缩短到1/3,即对每一个bit进行三次检测,然后做3取2判决,并将连续30个1/3bit的高电平后的首个1/3bit低电平作为帧起点的先决条件,确保正常情况下每一bit的3个1/3bit都是同样的电平值,这样做的好处是每一个bit的检测可以允许一个1/3bit出错。

以下进行简要分析,令改进之前的误码率是p,引起误码的噪声为非相干的,第一次改进后,对于任一bit的三次检测中允许有一次出错,因此在理想状态下的误码率为检测出错两次和三次的条件概率:

 

 

如果p=10-6,那么最终的误码率可以降低到约为1.4×10-25,分析表明改进措施应该有效。

经改进的软件在实验室进行了30小时通讯强度试验,试验中20ms完成一轮收发,报文长度为20个字节,在约1.08×108字节的接收通信中,未发现一个字节的通信错误。此后在产品8个月的调试与外场试验统计数据表明,除了有一次因通信接口芯片损坏以及一次不明原因的通信出错以外,没有出现因为软件产生的通信故障,证实了接收通信的可靠性。

6.结论

本文在GPIO模拟通用RS485/422串口通信的研究中,采用分层处理技术、优化bit检测方法、面向对象设计手段,实现了全双工通讯,具有逻辑清晰、易于实现、可靠性高和易于改进、维护和移植的优点;但也存在一定的局限性,如软件不宜采用汇编语言实现,全双工通信是以定时器为中心进行统筹实现的,并不是真正独立意义上的全双工,其波特率受工作频率的限制较大。

关键字:GPIO  RS485  422通信 引用地址:关于GPIO实现RS485/422通信的研究

上一篇:RS485串行通讯需注意
下一篇:一种提高RS485总线实时性的设计方案

推荐阅读最新更新时间:2024-05-02 23:45

STM32从入门到精通—GPIO简介
今天通过这篇文章带大家简单地了解一下GPIO,让大家有一个简单的认识,能够尽快应用。 GPIO简介 每个通用I/O端口包括4个32位配置寄存器、2个32位数据寄存器、1个32位置位/复位寄存器、1个32位锁定寄存器和2个32位复用功能选择寄存器。 GPIO主要特性 受控I/O多达16个 输出状态:推免或开漏+上拉/下拉 从输出数据寄存器或外设输出数据 可为每个I/O选择不同的速度 输入状态:浮空、上拉/下拉、模拟 将数据输入到输入寄存器或外设 置位和复位寄存器,对GPIO_ODR具有按位写权限 锁定机制,可冻结I/O配置 模拟功能 复用功能输入/输出选择寄存器 快速翻转,每次翻转最快最需要两个时钟周期
[单片机]
STM32从入门到精通—<font color='red'>GPIO</font>简介
STM8S105 GPIO寄存器方法
GPIO寄存器配置位及模式
[单片机]
STM8S105 <font color='red'>GPIO</font>寄存器方法
stm32GPIO中的8种模式
一、推挽输出:可以输出高、低电平,连接数字器件;推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由IC的电源决定。 推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。 二、开漏输出:输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行。适合于做电流型的驱动,其吸收电流的能力相对强(一般20mA以内)。开漏形式的电路有以下几个特点:
[单片机]
cortex M3S811学习笔记-GPIO-INT
首先是通用IO口,不管学什么单片机,IO口都是最重要和最好学的。重要是因为他是单片机与处围器件的接口,同样也是我们通常所说的人机接口,好学是因为它的控制容易,无非就是使能端口,设方向,然后就是写数据或是读数据了(根据你设的方向而定),这款超强的arm核的32位的小东西的IO口也有不同之处,毕竟是ARM核,IO的寄存器也丰富了不少。下面就来看看与IO口有关的函数。 1.按顺序来,先使能IO口。只有使能了他才能用,所以当然是第一步了。 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA) 这就是使能A端口函数,即A端口可以用了,他的大门向你敞开了 。 A端口不是在物理特征上有6个脚吗?GPIOA就
[单片机]
RS485总线接口电路及设计
测试仪通过RS485工业总线与PC机进行通信,其硬件接口电路如图5所示。 2 软件设计 2.1 总体设计 测试仪的软件开发环境采用的是Keil C,所有代码采用C语言编写。为了方便程序调试和提高可靠性,软件采用模块化结构设计,主要由初始化程序、主程序、子程序、中断服务程序等组成。单片机上电后即开始循环执行温湿度、照度测量程序,并以设定的时间间隔在数码管上轮流动态显示;按键切换和通信功能部分由于使用频率相对较低,为降低设备功耗,其程序以中断响应的方式执行。在此要注意中断优先级的设置:按键中断优先级应高于串口中断,否则将无法进行显示切换。主程序流程如图6所示。 2.2 传感器驱动程序 本系统采用的传感器均为集成数字芯片且都具有
[嵌入式]
STM32入门——第一天学习GPIO
第一步 学习GPIO,以按键控制跑马灯为例 GPIO是相对于stm32来说的,也就是芯片上的IO引脚,如C51上的P0口。但是stm32上的io口拥有更强大的功能,有GPIOA~G。每个GPIOx共15个引脚,刚开始学习时对于每个IO口的N多个功能没必要深究,但要记住几个重要的功能:输入上拉,输入下拉,推挽输出。这是本次试验用到的。 输入上拉:当IO口作为输入时,比如按键输入,而按键是与地连接,按下时为低电平,则没按下时该IO口应为高电平,上拉即是该IO口通过一个电阻与电源相连,则没按下时为高电平,按下即为低电平。 输入下拉:同理此时按键与电源相连,按下即为高电平,下拉就是该IO口通过一个电阻与地相连,没按下
[单片机]
STM32入门——第一天学习<font color='red'>GPIO</font>
GPIO复位函数void GPIO_DeInit(GPIO_TypeDef* GPIOx) 的理解
通常我们需要对ST单片机的整个IO进行复位操作,这是我们可以用到复位函数void GPIO_DeInit(GPIO_TypeDef* GPIOx); 先来看一下这个函数的定义 void GPIO_DeInit(GPIO_TypeDef* GPIOx) { /* Check the parameters */ assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); if (GPIOx == GPIOA) { RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Pe
[单片机]
STM32入门学习之GPIO(STM32F030F4P6基于CooCox IDE)(三)
先直接上代码 #include stm32f0xx.h #include stm32_lib/inc/stm32f0xx_rcc.h #include stm32_lib/inc/stm32f0xx_gpio.h int main(void) { //1、使能时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //定义一个IO GPIO_InitTypeDef PORT_LED; //设置IO引脚,模式,输出类型,速度 PORT_LED.GPIO_Pin=GPIO_Pin_4;//IO引脚,第4脚(个人的小板子PA4有连接LE
[单片机]
STM32入门学习之<font color='red'>GPIO</font>(STM32F030F4P6基于CooCox IDE)(三)
小广播
最新嵌入式文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved