基于ARM7的高效FIFO串口双机通信设计

出处:马明龙,黄春梅,张 瑞 发布于:2011-08-24 18:54:07

 

  在通信领域内,有两种数据通信方式:并行通信和串行通信。随着计算机网络化和微机分级分布式应用系统的发展,通信的功能越来越重要。通信是指计算机与外界的信息传输,既包括计算机与计算机之间的传输,也包括计算机与外部设备,如终端、打印机和磁盘等设备之间的传输。串行通信是指 使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。其只需要少数几条线就可以在系统间交换信息,特别使用于计算机与计算机、计算机与外设之间的远距离通信。

  S3C44B0X(时钟频率为60 MHz)的UART单元提供2个独立的异步串行I/O口,每个通信口均可工作于中断或DMA模式。即UART能产生内部中断请求或DMA请求,在CPU和串行I/O口之间传送数据。它支持高达115.2 Kb/s的传输速率,每1个UART通道包含了2个16位的分别用于接收和发送信号的先进先出(FIFO)通道。S3C44B0X UART包括可编程波特率、红外发送/接收、1个开始位、1个或2个停止位、5/6/7/8位数据宽度和奇偶校验。每个UART包含1个波特率发生器、接收器、发送器和控制单元,其构成如图1所示。

  1  FIFO概述

  1.1 FIFO概念

  FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。 FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端时AD数据采集,另一端时计算机的PCI总线,假设其AD采集的速率为16位 100K SPS,那么每秒的数据量为100K×16bit=1.6Mbps,而PCI总线的速度为33MHz,总线宽度32bit,其传输速率为1056Mbps,在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。

  1.2  FIFO意义

  FIFO是数据传输系统中极其重要的一环,特别是在2个处于不同时钟域的系统接口部分,FIFO的合理使用,不但能使接口处数据传输的输入输出速率进行有效的匹配,不使数据发生复写、丢失和读入无效数据的情况,而且还会有效地提高系统中数据的传输效率。使用FIFO进行串口通信,较之传统的串口通信有更高的效率。它将要发送和已经接收的数据集中起来进行操作,避免了频繁的总线操作,减轻了CPU的负担。因此,使得基于FIFO方式的串口通信目前应用十分广泛。

  1.3  FIFO中断请求

  UART:Universal Asynchronous Receiver/Transmitter,通用异步接收/发送装置,UART是一个并行输入成为串行输出的芯片,通常集成在主板上,多数是16550AFN芯片。因为计算机内部采用并行数据,不能直接把数据发到Modem,必须经过UART整理才能进行异步传输,其过程为:CPU先把准备写入串行设备的数据放到UART的寄存器(临时内存块)中,再通过FIFO(First Input First Output,先入先出队列)传送到串行设备,若是没有FIFO,信息将变得杂乱无章,不可能传送到Modem.

  S3C44B0X的UART有7个状态(Tx/Rx/Error)信号:溢出错误、奇偶错误、帧错误、断点条件、接收FIFO/Buffer数据准备就绪、发送FIFO/Buffer空和发送移位寄存器空,这些状态信号由相应的UART状态寄存器(UTRSTATn/UERSTATn)声明[1].

  当处于接收错误状态时,如果在控制寄存器(UCONn)中接收错误状态中断使能位被置为1,则溢出错误、奇偶校验错误、帧错误及断点错误,每1个作为1种错误状态都可发出错误中断请求。当1个接收错误状态中断请求被发现时,引起中断请求信号会被读UERSTATn所识别。如果控制器中的接收模式被选定为中断模式,则当接收器从接收移位寄存器向接收FIFO传输数据时,会激活接收FIFO的可引起接收中断的"满"状态信号。同样,如果控制器中的发送模式被选定为中断模式,则当发送器从发送FIFO向发送移位寄存器传输数据时,可引起发送中断的发送FIFO"空"状态信号被激活。如表1所示。


  2  FIFO串口通信的实现

  FIFO重启时,输入和输出的指针都指向FIFO中的第1个存储位置。对FIFO的每次写入操作会使输入指针指向FIFO的下1个存储位置,相应地每次读取操作会使FIFO的输出指针指向FIFO的上1个存储位置。若指针需要从1个存储位置移动到第1个存储位置,则FIFO会自动实现这一过程而不需要任何对指针的重启操作。FIFO内部除了包含输入和输出端口之外,通常还有其他状态标志输出,如空状态和满状态。当FIFO已空或者已满时,空状态和满状态标志位就会有相应的输出,即当FIFO已空时不能进行读取操作,当FIFO已满时不能进行写入操作.

  2.1  配置特殊寄存器

  为了使目标系统能正常工作,必须配置相关的寄存器,如I/O口寄存器、串口控制寄存器和串口源/目的寄存器等。S3C44B0X有2个串口,这里以串口0为例,进行相关寄存器的配置。

  /*I/O口配置,定义各相关引脚功能和上拉电阻状态 */

  rPCONC |=0xf0000000;

  rPUPC |=0xc000;

  rPCONE=(rPCONE &0x3ffeb)|0x28;

  rPUPE |=0x6;

  rPCONF=(rPCONF &0x3ff)+0x124800;

  rPUPF |=0x1e0;

  /* 定义串口0工作寄存器组 */

  rULCON0=0x3; //正常模式,无奇偶校验,1位停止位,8位数据位

  rUCON0=0x245;    //Rx为边沿触发,Tx为电平触发,禁

  //止超时中断,产生接收错误中断,普通传送、

  //发送与接收为中断或轮询模式

  rUFCON0=(2《6)|(1《4)|(6)|1; //FIFO启动需先复位

  rUBRDIV0=(mclk/(baud*16));  //mclk为60000000,baud为115200

  2.2  FIFO串口发送模块

  串口数据发送帧格式是可编程的,它包含1个开始位,5~8个数据位,1个可选的奇偶位和1~2个停止位,这些都可以通过线控制寄存器(UCONn)来设置。发送器也能够产生发送中止条件。中止条件迫使串口输出保持在逻辑0状态,这种状态保持超过1个传输帧的时间长度。通常在1帧传输数据完整地传输完之后,再通过这个全0状态将中止信号发送给对方。中止信号发送之后,传送数据将持续地放入到输出FIFO中。要发送的数据被存放在定义的字符串指针uart0TxStr 中,串口发送模块通过读该字符串中的字符进行数据发送,源代码如下:

  void __irq Uart0_TxFifoInt(void)

  {

  /* 判断FIFO发送缓冲区是否为满或字符串结束 */

  while( !(rUFSTAT0 & 0x200) && (*uart0TxStr !='\0'))

  {

  rUTXH0=*uart0TxStr++;

  for(i=0;i<700;i++);  //延迟,防止FIFO误写

  }

  rI_ISPC=BIT_UTXD0;

  if(*uart0TxStr == '\0')

  {

  rINTMSK |= BIT_UTXD0;

  rI_ISPC=BIT_UTXD0;

  }

  }

  2.3  FIFO串口接收模块

  接收的数据帧格式与发送一样都是可编程的。它包括了1个起始位,5~8个数据位,1个可选的奇偶校验位和1~2个停止位,这些都可以通过线控制寄存器(UCONn)来设置。接收器还可以检测到溢出错误、奇偶校验错误、帧错误和中止状况,每种情况下都会将1个错误标志置位。

  (1)溢出错误表示新的数据已经覆盖了旧的数据,因为旧的数据没有及时被读入。

  (2)奇偶校验错误表示接收器检测到了意料之外的奇偶校验结果。

  (3)帧错误表示接收到的数据没有有效的停止位。

  (4)中止状况表示RxDn的输入被保持为0状态超过了1个帧传输的时间.

  (5)在FIFO模式下接收FIFO不为空,但接收器已经在3个字时间内没有接收到任何数据,就认为发生了接收超时状况。

  接收模块将数据从接收移位寄存器中读出后,首先被存储到接收缓存数组keyBuf[ ]中。变量keyBufWrPt和keyBufRdPt指向缓存数组中当前写数据和读数据,当接收模块往缓存数组中写入1个字节后,keyBufWrPt加1;当Uart_IntGetKey从缓存数组中读出1个字节后,keyBufRdPt加1.两变量值为KEY_LEN,超过值时置零。接收模块的代码如下:

  /* 接收模块将移位寄存器中的数据读出到接收缓存数组中 */

  void __irq Uart0_RxFifoInt(void)

  {

  rI_ISPC=BIT_URXD0;

  if(rUFSTAT0==0)

  Uart_Printf("time out\n");

  while( (rUFSTAT0&0xf) >0 )     //循环直到FIFO

  //发送缓冲区为空

  {

  keyBuf[keyBufWrPt++]=rURXH0;   //读取接收缓冲区数据存入缓存数组

  if(keyBufWrPt==KEY_BUFLEN)

  keyBufWrPt=0;

  }

  }

  /* 定义1个函数从接收缓存数组中读取数据 */

  char Uart_IntGetkey(void)

  {

  if(keyBufRdPt==KEY_BUFLEN)

  keyBufRdPt=0;

  while(keyBufWrPt==keyBufRdPt);//等待直到FIFO被触发

  return keyBuf[keyBufRdPt++];

  }

  2.4 FIFO容错模块

  除了接收FIFO寄存器之外,UART还具有1个状态FIFO.状态FIFO表示了在FIFO寄存器中,哪一个数据被毫无错误地接收。假设UART的FIFO连续接收到A、B、C、D、E字符,并且在接收B字符时发生了帧错误(即该字符没有停止位),在接收D字符时发生了奇偶校验错。虽然UART错误发生了,但不会产生错误中断,因为含有错误的字符还没有被CPU读取。当字符被读出时错误中断才会发生,而且只有在读出URXHn和UERSTATn寄存器后,FIFO错误状态寄存器才会被清除[5].容错模块代码如下[6].

  void __irq Uart0_RxFifoErrorInt(void)

  {

  rI_ISPC=BIT_UERR01;

  Uart_Printf("UERSTAT0=0x%x\n",rUERSTAT0& 0xf);

  while( (rUFSTAT0&0xf) >0 )

  {

  keyBuf[keyBufWrPt++]=rURXH0;

  if(keyBufWrPt==KEY_BUFLEN);

  keyBufWrPt=0;

  }

  }

  3  实验结果

  本实验在S3C44B0X和ADS1.2平台上实现,取得了预期的效果。在同等条件下(忽略温度、电压等外部因素变化),在带FIFO(FIFO)和不带FIFO(Non-FIFO)时发送和接收所花时间如表2所示。

  以传输4 KB数据为例,由表2可知,使用FIFO时,发送和接收分别节省0.547 076 s和0.042 832 s时间。假定传输1 bit的数据用时为θs,传输数据量为n,则可知使用FIFO和不使用FIFO两种情况下的用时差为15nθ/16s.由此可见,当传输数据量n越大时,采用FIFO的串口传输模式的用时越少、优越性越明显。这也显示了FIFO在串口传输较大数据量的工程应用中的重要性和必要性。

  在串口通信应用越来越广的背景下,提高串口通信速度显得格外重要。本文以S3C44B0X微处理器为平台,介绍的基于FIFO的串口双机通信的原理和实现方法,该方法同时也适用于其他配置FIFO缓冲区的微处理器,具有很强的适用性和通用性,在学习、研究的同时,也为工程应用中的串口通信提供了参考模型。

 


  

参考文献:

[1]. S3C44B0X datasheet https://www.dzsc.com/datasheet/S3C44B0X_589522.html.
[2]. PCI datasheet https://www.dzsc.com/datasheet/PCI_1201469.html.


版权与免责声明

凡本网注明“出处:维库电子市场网”的所有作品,版权均属于维库电子市场网,转载请必须注明维库电子市场网,https://www.dzsc.com,违反者本网将追究相关法律责任。

本网转载并注明自其它出处的作品,目的在于传递更多信息,并不代表本网赞同其观点或证实其内容的真实性,不承担此类作品侵权行为的直接责任及连带责任。其他媒体、网站或个人从本网转载时,必须保留本网注明的作品出处,并自负版权等法律责任。

如涉及作品内容、版权等问题,请在作品发表之日起一周内与本网联系,否则视为放弃相关权利。

上传BOM文件: BOM文件
*公司名:
*联系人:
*手机号码:
QQ:
应用领域:

有效期:
OEM清单文件: OEM清单文件
*公司名:
*联系人:
*手机号码:
QQ:
有效期:

扫码下载APP,
一键连接广大的电子世界。

在线人工客服

买家服务:
卖家服务:

0571-85317607

客服在线时间周一至周五
9:00-17:30

关注官方微信号,
第一时间获取资讯。

建议反馈

联系人:

联系方式:

按住滑块,拖拽到最右边
>>
感谢您向阿库提出的宝贵意见,您的参与是维库提升服务的动力!意见一经采纳,将有感恩红包奉上哦!