1. 串口(物理)
串口硬件主要是4条线,rx tx gnd和电源四条硬件线
2. 串口(协议)
串口是计算机上一种非常通用的设备通信的协议(不要与通用串行总线Universal Serial Bus或者USB混淆)。大多数计算机包含两个基于RS232的串口。串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。同时,串口通信协议也可以用于获取远程采集设备的数据。串口通信的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。比如IEEE488定义并行通行状态时,规定设备线总常不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。
典型地,串口用于ASCII码字符的传输。通信使用3根线完成:(1)地线,(2)发送,(3)接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配.
-
波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。例如300波特表示每秒钟发送300个bit。当我们提到时钟周期时,我们就是指波特率例如如果协议需要4800波特率,那么时钟是4800Hz。这意味着串口通信在数据线上的采样率为4800Hz。通常电话线的波特率为14400,28800和36600。波特率可以远远大于这些值,但是波特率和距离成反比。高波特率常常用于放置的很近的仪器间的通信,典型的例子就是GPIB设备的通信。
-
数据位:这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据不会是8位的,标准的值是5、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码是0~127(7位)。扩展的ASCII码是0~255(8位)。如果数据使用简单的文本(标准ASCII码),那么每个数据包使用7位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。
-
起始位:线路空闲的时候是高电平,当检测到低电平认为有数据传输开始,所以是低电平。
-
停止位:用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
-
奇偶校验位:在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。如果是奇校验,校验位位1,这样就有3个逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步。
RS232与RS485
PLC各型主机均内建2个通信接口的标准配置,即一个RS232和一个RS485通信接口,其RS232接口主要用于上下载程序或用来与上位机、触摸屏通信,而RS485接口主要用于组建使用RS485协议的网络,实现通信控制。
-
RS232接口
RS232-C接口连接器一般使用型号为DB-9的9芯插头座,只需3条接口线,即"发送数据"、"接收数据"和"信号地"即可传输数据,其9个引脚的定义如图11-3所示。RS-232(ANSI/EIA-232标准)是IBM-PC及其兼容机上的串行连接标准。可用于许多用途,比如连接鼠标、打印机或者Modem,同时也可以接工业仪器仪表。用于驱动和连线的改进,实际应用中RS-232的传输长度或者速度常常超过标准的值。RS-232只限于PC串口和设备间点对点的通信。RS-232串口通信最远距离是50英尺。
RS232-C接口连接器定义
在RS232的规范中,电压值在+3V~+15V(一般使用+6V)称为"0"或"ON"。电压在-3V~-15V(一般使用-6V)称为"1"或"OFF";计算机上的RS232"高电位"约为9V,而"低电位"则约为-9V。
RS232为全双工工作模式,其信号的电压是参考地线而得到的,可以同时进行数据的传送和接收。在实际应用中采用RS232接口,信号的传输距离可以达到 15m。不过RS232只具有单站功能,即一对一通信。
-
RS485接口
RS485采用正负两根信号线作为传输线路。两线间的电压差为+2V~6V表示逻辑"1":两线间的电压差为-2V~6V表示逻辑"0"。
RS485为半双工工作模式,其信号由正负两条线路信号准位相减而得,是差分输入方式,抗共模干扰能力强,即抗噪声干扰性好;实际应用中其传输距离可达1200米。RS485具有多站能力,即一对多的主从通信。
RS-485(EIA-485标准)是RS-422的改进,因为它增加了设备的个数,从10个增加到32个,同时定义了在最大设备个数情况下的电气特性,以保证足够的信号电压。有了多个设备的能力,你可以使用一个单个RS-422口建立设备网络。出色抗噪和多设备能力,在工业应用中建立连向PC机的分布式设备网络、其他数据收集控制器、HMI或者其他操作时,串行连接会选择RS-485。RS-485是RS-422的超集,因此所有的RS-422设备可以被RS-485控制。RS-485可以用超过4000英尺的线进行串行通信。
-
RS-422
RS-422(EIA RS-422-A Standard)是Apple的Macintosh计算机的串口连接标准。RS-422使用差分信号,RS-232使用非平衡参考地的信号。差分传输使用两根线发送和接收信号,对比RS-232,它能更好的抗噪声和有更远的传输距离。在工业环境中更好的抗噪性和更远的传输距离是一个很大的优点。
通信方式
在串行通信中,数据通常是在两个站之间传送,按照数据在通信线路上的传送方向可分为3种基本的传送方式:单工、半双工和全双工,如图11-4所示。
单工、半双工和全双工通信
单工通信使用一根导线,信号的传送方和接收方有明确的方向性。也就是说,通信只在一个方向上进行。
若使用同一根传输线既作为接收线路又作为发送线路,虽然数据可以在两个方向上传送,但通信双方不能同时收发数据,这样的传送方式称为半双工。采用半双工方式时,通信系统每一端的发送器和接收器,通过收发开关分时转接到通信线上,进行方向的切换。
当数据的发送和接收,分别由两根不同的传输线传送时,通信双方都能在同一时刻进行发送和接收操作,这样的传送方式就是全双工。在全双工方式下,通信系统的每一端都设置了发送器和接收器,因此,能控制数据同时在两个方向上传输。全双工方式无须进行方向的切换。
串行通信可分为两种类型,一种是同步通信,另一种是异步通信。采用同步通信时,将所有字符组成一个组,这样,字符可以一个接一个地传输,但是,在每组信息的开始要加上同步字符,在没有信息要传输时,填上空字符,因为同步传输不允许有空隙。采用异步通信时,两个字符之间的传输间隔是任意的,所以,每个字符的前后都要用一些数据位来作为分隔位。比较起来,在传输率相同时,同步通信方式下的信息有效率要比异步方式高,因为同步方式的非数据信息比例比较小。但是,从另一方面看,同步方式要求进行信息传输的双方必须用同一个时钟进行协调,正是这个时钟确定了同步串行传输过程中每一个信息位的位置。这样一来,如果采用同步方式,那么,在传输数据的同时,还必须传输时钟信号。而在异步方式下,接收方的时钟频率和发送方的时钟频率不必完全一样,而只要比较相近,即不超过一定的允许范围就行了。在数据传输中,较为广泛采用的是异步通信,异步通信的标准数据格式如图11-5所示。
异步通信数据格式
从图11-5所列格式可以看出,异步通信的特点是一个字符一个字符地传输,并且每个字符的传送总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。每一次有一个起始位,紧接着是5~8个的数据位,再后为校验位,可以是奇检验,也可以是偶校验,也可不设置,最后是1比特,或1比特半,或2比特的停止位,停止位后面是不定长度的空闲位。停止位和空闲位都规定为高电平,这样就保证起始位开始处一定有一个下降沿,以此标识开始传送数据。这里给定的是裸机电平,实际硬件中的电平可能是不一样的,实际如两种类型的硬件实现:
什么是握手?
RS-232通行方式允许简单连接三线:Tx、Rx和地线。但是对于数据传输,双方必须对数据定时采用使用相同的波特率。尽管这种方法对于大多数应用已经足够,但是对于接收方过载的情况这种使用受到限制。这时需要串口的握手功能。在这一部分,我们讨论三种最常用的RS-232握手形式:软件握手、硬件握手和Xmodem。
a,软件握手:我们讨论的第一种握手是软件握手。通常用在实际数据是控制字符的情况,类似于GPIB使用命令字符串的方式。必须的线仍然是三根:Tx,Rx和地线,因为控制字符在传输线上和普通字符没有区别,函数SetXModem允许用户使能或者禁止用户使用两个控制字符XON和XOFF。这些字符在通信中由接收方发送,使发送方暂停。
例如:假设发送方以高波特率发送数据。在传输中,接收方发现由于CPU忙于其他工作,输入buffer已经满了。为了暂时停止传输,接收方发送XOFF,典型的值是十进制19,即十六进制13,直到输入buffer空了。一旦接收方准备好接收,它发送XON,典型的值是十进制17,即十六进制11,继续通信。输入buffer半满时,LabWindows发送XOFF。此外,如果XOFF传输被打断,LabWindows会在buffer达到75%和90%时发送XOFF。显然,发送方必须遵循此守则以保证传输继续。
b,硬件握手:第二种是使用硬件线握手。和Tx和Rx线一样,RTS/CTS和DTR/DSR一起工作,一个作为输出,另一个作为输入。第一组线是RTS(Request to Send)和CTS(Clear to Send)。当接收方准备好接收数据,它置高RTS线表示它准备好了,如果发送方也就绪,它置高CTS,表示它即将发送数据。另一组线是DTR(Data Terminal Ready)和DSR(Data Set Ready)。这些线主要用于Modem通信。使得串口和Modem通信他们的状态。例如:当Modem已经准备好接收来自PC的数据,它置高DTR线,表示和电话线的连接已经建立。读取DSR线置高,PC机开始发送数据。一个简单的规则是DTR/DSR用于表示系统通信就绪,而RTS/CTS用于单个数据包的传输。
在LabWindows,函数SetCTSMode使能或者禁止使用硬件握手。如果CTS模式使能,LabWindows使用如下规则:
当PC发送数据:
RS-232库必须检测CTS线高后才能发送数据。
当PC接收数据:
如果端口打开,且输入队列有空接收数据,库函数置高RTS和DTR。
如果输入队列90%满,库函数置低RTS,但使DTR维持高电平。
如果端口队列近乎空了,库函数置高RTS,但使DRT维持高电平。
如果端口关闭,库函数置低RTS和DTR。
c,XModem握手:最后讨论的握手叫做XModem文件传输协议。这个协议在Modem通信中非常通用。尽管它通常使用在Modem通信中,XModem协议能够直接在其他遵循这个协议的设备通信中使用。在LabWindows中,实际的XModem应用对用户隐藏了。只要PC和其他设备使用XModem协议,在文件传输中就使用LabWindows的XModem函数。函数是XModemConfig,XModemSend和XModemReceive。
XModem使用介于如下参数的协议:start_of_data、end_of_data、neg_ack、wait_delay、start_delay、max_tries、packet_size。这些参数需要通信双方认定,标准的XModem有一个标准的定义:然而,可以通过XModemConfig函数修改,以满足具体需要。这些参数的使用方法由接收方发送的字符neg_ack确定。这通知发送方其准备接收数据。它开始尝试发送,有一个超时参数start_delay;当超时的尝试超过max发出包的数目很可能增加到XON/OFF控制字符的值,从而导致通信故障。
-
波特率:衡量传输速率的快慢,每秒钟传输数据的位数(bit)
-
数据位:有效数据
-
起始位:线路空闲的时候是高电平,当检测到低电平认为有数据传输开始,所以是低电平。
-
奇偶校检位:检测数据传输是否正确
-
停止位:表明一帧数据传输结束
串口的工作原理 引言 串行端口一直被视作计算机最基础的外部连接设备之一,在过去的20多年时间里,它一直是大多数计算机不可或缺的组成部分。虽然许多较新的系统在采用USB连接设备后,已经彻底放弃了串行端口,但大多数调制解调器都仍然在使用,一些打印机、掌上型电脑 和数码相机也是如此。不过,计算机所带的串行端口一般都不会超过两个。从本质上说,串行端口可提供标准的连接器和协议,允许我们将调制解调器等设备连接到计算机上。 串行端口怎样传输数据 当今人们使用的所有计算机操作系统都支持串行端口,因为其“入驻”计算机已有数十年的历史了。而并行端口的发明要晚得多,速度也比串行端口快得多。USB端口的历史只有数年,它很可能在接下来的几年内全面取代串行端口和并行端口。 之所以取名为“串行”端口,是因为这种端口会将数据“串行化”。更具体地说,它一次获取一个字节的数据并传输该字节的8位。这样做的优势在于,串行端口只需要一条线路就能传输8个位,而并行端口则需要8条。相应的劣势在于,其传输数据的用时是拥有八条线路时的8倍。此外,串行端口还可以降低线缆成本,使线缆更加小巧。在发送数据的每个字节之前,串行端口会发送一个开始位,这是一个值为0的单个位。在发送完数据的每个字节之后,它将发送一个停止位,表示该字节已传输完成。此外,它还可以发送奇偶校验位。 串行端口也称为通信(COM)端口,是一种双向端口。在双向通信中,每个设备都可以接收数据和传输数据。串行设备使用不同的针脚来接收和传输数据——如果使用相同的针脚,通信将限制为半双工模式,这表示信息一次只能在一个方向上传播。使用不同的针脚可以实现全双工通信,在这种模式中,信息可以同时在两个方向上传播。串行端口依靠特殊的控制器芯片通用异步接收/传输器(UART)来实现自己的功能。UART芯片从计算机的系统总线获得并行输出,然后将其转换成串行形式,以便通过串行端口传输。为了提高效率,大多数UART芯片都内置有16到64千字节的缓冲区。利用这个缓冲区,芯片便可以在处理要流向串行端口的数据的同时,缓存从系统总线流入的数据。大多数标准串行端口的最大传输速率为115Kbps(千比特每秒),增强型串行端口(ESP)和超级增强型串行端口(Super ESP)等高速串行端口可以实现460Kbps的数据传输速率。 串行连接设备 适用于串行端口的外部连接器可以是9针脚的,也可以是25针脚的。最初,串行端口的主要用途是将调制解调器连接到计算机上。针脚的功能分配反映了这一点。下面,让我们详细了解一下在连接调制解调器时,每个针脚都有何作用。
2.1 S3C2440串口控制器
串口控制器功能模块图如下:
串口同通信数据传输不需要时钟线进行驱动,控制器内部的时钟驱动波特率发生器进行数据的传送和接受。也就是传输设备两端的波特率如果设置不同,对于数据发送解析时间周期不一致,数据传输失败。
FIFO先进先出硬件实现数据内容的搬移,读数据时寄存器固定不变,数据的搬移由硬件实现向前依次推进的效果。
错误为解析能够实现复杂的数据链路层数据传输,与MAC芯片不同,复杂的解析和重新传送需要双方复杂的软件协议约定过程来实现。
嵌入式Linux应用开发完全手册186页
编程实现
确定了基本硬件实现、数据协议、控制器功能图,根据开发板原理图确定链接的引脚情况,然后进行基本的引脚配置和控制器配置。
Operate process
-
初始化
-
设置引脚工作模式RX/TX
-
设置数据格式(ULCON)
-
设置工作模式(DMA,轮询,中断),(UCON)
-
设置波特率(UBRDIV)
-
-
发送
-
UTRSTAT
-
(UTXH)
-
-
接收
-
(UTRSTAT)
-
(URXH)
-
使用中断,不使用DMA,不使用FIFO的汇编代码处理流程。
uart:
/* 设置引脚用于串口 */
/* GPH2,3用于TxD0, RxD0 */
ldr r2, =0x56000070
ldr r3, =0x56000070
ldr r3, [r3]
bic r3, r3, #240
orr r3, r3, #160
str r3, [r2]
/* GPH2,3使能内部上拉 */
ldr r2, =0x56000078
ldr r3, =0x56000078
ldr r3, [r3]
bic r3, r3, #12
str r3, [r2]
/* PCLK,中断/查询模式 */
ldr r2, =0x50000004
mov r3, #5
str r3, [r2]
/* 设置波特率 */
/* UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
* UART clock = 50M
* UBRDIVn = (int)( 50000000 / ( 115200 x 16) ) –1 = 26
*/
ldr r3, =0x50000028
mov r2, #26
str r2, [r3]
/* 设置数据格式 */
/* 8n1: 8个数据位, 无较验位, 1个停止位 */
ldr r2, =0x50000000
mov r3, #3
str r3, [r2]
putchar:
/* 查看transfer是否empty, 空直接发送数据 */
ldr r3, =0x50000010
ldr r3, [r3]
and r3, r3, #4
cmp r3, #0
bne putcharloop
b putchar
putcharloop:
ldr r3, =0x50000020
strb r2, [r3] /* 发送数据 */
getchar:
/* 未使能FIFO情况下,查看buf是否收到数据 */
ldr r3, =0x50000010
ldr r3, [r3]
and r3, r3, #1
cmp r3, #0
bne getcharloop
b getchar
getcharloop:
ldr r3, =0x50000024
ldrb r2, [r3] /* 取出一个数据 */
and r2, r2, #255 /* 只保留一字节数据 */
b putchar
Control pantform
uboot控制台分为解析型控制台、菜单型控制台,控制台关键实现printf/scanf函数。
协助函数
-
va_list args;声明一个变参列表
-
unsigned char str[1024];声明一个字符数组,用来存放转换以后的字符串
-
va_start(args,fmt);开始生成可变参数列表里的元素
-
vsprintf(str,fmt,args);将可变参数列表args里的元素按照fmt的格式写入字符串str
-
va_end();结束转换,清空变参列表,使得args指针无效(因为他是一个列表,所以相当于一个”数组“,故数组名是一个指针)。
移植函数库
(1)将提供的lib和include文件夹复制到junboot目录下,主要是编译lib目录(2)由下面内容可以看出lib目录下的文件最终编译的结果是得到lib.o,所以我们要将lib.o整合到前面产生的jun-boot中修改顶层Makefile,使得将当前路径下lib目录的编译结果加入到原有的jun-boot一起进行新的编译。(3)最终目标jun-boot.bin,(4)jun-boot.elf是由.o文件产生的,将这些.o文件赋值给一个变量,当然这个截图里少了uart.o文件。
则jun-boot.elf的产生:
(5)将print.c剪切到lib下(6)将OBJS添加上lib/lib.o
(7)添加编译子目录下的lib.o的规则,以及clean伪目标规则。其中-C指明后面的目录lib,all是由于在lib子目录的Makefile中最终目标就是all。
(8)此时编译会出现以下错误
但是查看ctype.c里,发现引用的头文件里已经定义了这些符号,原因在于交叉编译器寻找头文件的路径没有包含这个路径。所以我们要利用-I选项添加头文件路径。而这个选项则应该加在lib子目录下的Makefile文件中,打开该文件发现
已经有了一个CFLAGS变量,该变量用来保存一些编译选项,我们只要在改变量里面添加-I选项就可以。但是这个变量一般应该出现在顶层目录的Makefile中,打开顶层 Makefile发现并未定义,所以在顶层Makefile中定义:
最后还要输出CFLAGS以供子目录使用(9)此时编译还有以下错误
原因是我们没有添加必要的头文件vsprintf.h,于是在print.c里面添加头文件。(10)再次编译发现还是有错误
原因是内联函数造成的,所以编译选项还要再改进。即CFLAGS
同时现在的CFLAGS主要使用到main.c所以还要修改main.c的编译选项,即加进去CFLAGS编译选项
(11)printf以及scanf的实现(print.c)
代码结构优化
-
将一般外设.c文件剪切到新建的dev子目录
-
编写dev子目录的Makefile
-
修改顶层的Makefile
210查错
加头程序有bug,限制了bin的大小,检查又只能检查前面161024-168的部分。
-
多用排除法去调试代码
-
大胆的修改代码进行实验。
MAX202E
MAX202器件是专为RS-232和V.28通信接口设计的收发器,尤其是±12V供压无法实现的情况。MAX202板载的电荷泵将+5V的输入电压转换为RS-232协议所要求的±10V输出电平。 MAX202发送器和接收器的数据传输速率达20kbps,完全符合EIA/TIA-232E和CCITT V.28的规格。只要根据EIA/TIA-232E的规格接入负载,当数据传输速率超过120kbps时,MAX202驱动器仍将保持±5V的EIA/TIA-232E输出信号电平。