S3C2440 UART串口驱动

++++++++++++++++++++++++++++++++++++++++++

本文转载自mr_raptor的专栏,感谢mr_raptor大神。

http://blog.csdn.net/mr_raptor/article/details/6556133

++++++++++++++++++++++++++++++++++++++++++

  通用异步接收器和发送器(Universal Asynchronous Receiver and Transmitter)简称UART。通常是嵌入式设备中默认都会配置的通信接口。这是因为,很多嵌入式设备没有显示屏,无法获得嵌入式设备实时数据信息,通过UART串口和超级终端相连,打印嵌入式设备输出信息。并且在对嵌入式系统进行跟踪和调试时,UART串口是必要的通信手段。比如:网络路由器,交换机等都要通过串口来进行配置。UART串口还是许多硬件数据输出的主要接口,如GPS接收器就是通过UART串口输出GPS接收数据的。

  S3C2440 UART控制器,提供了三个独立的异步串行I/O端口,每个端口都可以在中断模式或DMA模式下工作,换而言之,UART可以生成中断或DMA请求用于CPU和UART之间的数据传输。UART串口挂接在APB总线上,APB总线最高可以达到50MHz工作频率,在使用APB时钟频率时可以达到最高115.2Kbps波特率的通信速度。如果UART串口接收外部设备提供UEXTCLK(外部时钟),UART可以在更高的速度下工作。每个UART串口在接收装置和发送装置里分别包含一个64Byte的FIFO缓冲区,用于缓存发送数据和接收数据。

  由于UART是串行异步通信方式,因此在UART通信过程中每次只能传输1bit,若干位组成一个数据帧(frame),帧是UART通信中最基本单元,它主要包含:开始位,数据位,校验位(如果开启了数据校验,要包含校验位),和停止位,帧结构如图1所示。

图1 UART数据帧结构

UART在通信之前要在发送端和接收端约定好帧结构,也就是约定好传输数据帧格式。

开始位:必须包含在数据帧中,表示一个帧的开始。

数据位:可选5/6/7/8位,该位长度可由编程人员指定。

校验位:如果在开启了数据校验时,该位必须指定。

停止位:可选1,2位,该位长度可由编程人员指定。

通信双方约定好帧格式后,指定同一波特率,以保证双方数据传输的同步。

S3C2440 UART串口工作原理

每个UART包含一个波特率产生器,发送器,接收器和一个控制单元,如图2所示

图2 UART硬件结构

  UART是以异步方式实现通信的,其采样速度由波特率决定,波特率产生器的工作频率可以由PCLK(外围设备频率),FCLK/n(CPU工作频率的分频),UEXTCLK(外部输入时钟)三个时钟作为输入频率,波特率设置寄存器是可编程的,用户可以设置其波特率决定发送和接收的频率。发送器和接收器包含了64Byte的FIFO和数据移位器。UART通信是面向字节流的,待发送数据写到FIFO之后,被拷贝到数据移位器(1字节大小)里,数据通过发送数据管脚TXDn发出。同样道理,接收数据通过RXDn管脚来接收数据(1字节大小)到接收移位器,然后将其拷贝到FIFO接收缓冲区里。

  (1)数据发送

  发送的数据帧是可编程的,它的一个帧长度是用户指定的,它包括一个开始位,5~8个数据位,一个可选的奇偶校验位和1~2个停止位,数据帧格式可以通过设置ULCONn寄存器来设置(如图3)。发送器也可以产生一个终止信号,它由一个全部为0的数据帧组成。在当前发送数据被完全传输完以后,该模块发送一个终止信号。在终止信号发送后,它可以继续通过FIFO或发送保持寄存器(NON-FIFO)发送数据。

  (2)数据接收

  同样接收端数据也是可编程的,接收器可以侦测到溢出错误奇偶校验错误,帧错误和终止条件,每个错误都可以设置一个错误标志。

  溢出错误是指在旧数据被读取到之前,新数据覆盖了旧数据

  奇偶校验错误是指接收器侦测到了接收数据校验结果失败,接收数据无效

  帧错误是指接收到的数据没有一个有效的停止位,无法判定数据帧结束

  终止条件是指RxDn接收到保持逻辑0状态持续长于一个数据帧的传输时间

  (3)自动流控AFC(Auto Float Control)

  UART0和UART1支持有nRTS和nCTS的自动流控,UART2不支持流控。在AFC情况下,通信双方nRTS和nCTS管脚分别连接对方的nCTS和nRTS管脚。通过软件控制数据帧的发送和接收。

  在开启AFC时,发送端接收发送前要判断nCTS信号状态,当接收到nCTS激活信号时,发送数据帧。该nCTS管脚连接对方nRTS管脚。接收端在准备接收数据帧前,其接收器FIFO有大于32个字节的空闲空间,nRTS管脚会发送激活信号,当其接收FIFO小于32个字节的空闲空间,nRTS必须置非激活状态。如图3所示。

图3 自动流控数据传输

  (4)波特率

  在UART中波特率发生器为发送器和接收器提供工作时钟。波特率发生器的时钟源可以选择S3C2440A的内部系统时钟(PCLK,FCLK/n)或UEXTCLK(外部时钟源),可以通过设置UCONn寄存器来设置波特率发生器的输入时钟源。通常我们选择使用PCLK作为UART工作时钟。

  UART控制器中没有对波特率进行设置的寄存器,而是通过设置一个除数因子,来决定其波特率。其计算公式如下:

  UART除数(UBRDIVn) = (int) ( UART时钟 / (buadrate * 16 ) ) - 1

  其中:

  UBRDIVn的取值范围应该为1~2^16-1。

  UART时钟,可以选择 PCLK,FCLK/n或者UEXTCLK

  例如:

  波特率为115200bps,PCLK时钟为其工作频率,采用50MHz,则UBRDIVn为:

  UBRDIVn = (int) (50M / (115200 x 16) ) - 1 = 26

  在系统时钟未初始化时,PCLK = 12MHz,如果波特率采用57600bps,那么UBRDIVn为:

  UBRDIVn = (int) (12M / (57600 x 16)) - 1 = 12

  当然,UBRDIVn应该是从1~(2^16-1),只有在使用小于PCLK的UEXTCLK时设置为0(旁路模式)。

  (5)波特率的错误容忍率(Baud-Rate Error Torlerance)

  数据信号在传输过程中由于外界电磁干扰,信号减弱等原因,当时钟频率较低,传输速率较高时会产生误差,当误差达到一定值时,会出现数据信号不能正常识别,造成通信异常。好比如,在普通列车轨道上试图行驶高速列车一样,由于高速列车对轨道要求很高,当速度达到一定程度,很可能造成事故。业界的波特率的错误容忍率为1.87%(3 / 160),如果大于该值则应该选择较低的波特率或提高输入时钟频率。

  错误容忍率计算公式为:

  UART Error = (tUPCLK - tUEXACT) / tUEXACT * 100%

  注:

  tUPCLK为UART的真实工作时钟频率:tUPCLK = (UBRDIVn + 1) * 16 * 1Frame / PCLK

  tUEXACT为UART理想工作时钟频率:tUEXACT = 1Frame / baudrate

  其中:1Frame 为数据帧的长度 = 开始位 + 数据位 + 可选校验位 + 停止位

  假如,波特率采用115200bps,PCLK时钟为50MHz,波特率除数因子UBRDIVn为26(通过前面UBRDIVn计算公式算出),采用1个停止位,8个数据位,无校验的8N1方式通信时,其错误容忍率为:

tUPCLK = 27 * 16 * 10 / 50M = 0.0000864

tUEXACT = 10 / 115200 = 0.0000868

UART Error  = | 0.0000864 - 0.0000868 | / 0.0000868 = 0.46%

  在开发板没有初始化系统时钟前,开发板工作在12MHz下,假如我们将波特率设置为115200bps,采用PCLK为系统默认时钟12MHz,8N1数据帧格式通信,那么:

  UBRDIVn = (int)(12M / (115200 * 16)) - 1 = 6

  其错误容忍率:

tUPCLK = 7 * 16 * 10 / 12M = 0.0000933

tUEXACT = 10 / 115200 = 0.0000868

UART Error = | 0.0000933 - 0.0000868 | / 0.0000868 = 7.5%

  其错误容忍率大于1.86%,因此在12MHz频率下,波特率不能设置为115200,现在将波特率设置为56700bps,采用8N1数据帧格式通信,那么:

UBRDIVn = (int)(12M / (57600 * 16)) - 1 = 12

tUPCLK = 13 * 16 * 10 / 12M = 0.000173

tUEXACT = 10 / 57600 = 0.0001736

UART Error = | 0. 000173 - 0. 0001736 | / 0. 0001736 = 0.345%

  采用波特率为56700bps,8N1数据帧格式通信时,其错误容忍率小于标准的1.86%,因此可以正常工作。

MINI2440 UART串口

图4 MINI2440开发板串口硬件图

  图4为MINI2440开发板引出UART串口接线图,它采用DB9接口公头,其有9根信号线,UART通信过程中用到了信号线2 RSTXD0(数据发送管脚)它和串口线母头TXDx信号线相接(x代表0号,1号,2号串口),信号3 RSRXD0(数据接收管脚)和串口线母头RXDx相接(x代表0号,1号,2号串口),信号线5(接地管脚),信号线7 RSCTS0(数据发送流控制管脚)和串口线母头nCTSx相接,信号线8 RSRTS0(数据接收流控制管脚)和串口线母头nRTSx相接。如果UART中没有开启AFC流控的话,只要用到信号线2,信号线3和信号线5。

  

图5 MIMI2440串口管脚接线

  由图5可以看出,TXD0和RXD0连接到CPU的GPH2和GPH3管脚上的,而GPH2和GPH3是CPU复用管脚,因此我们要对GPH2和GPH3对应寄存器进行设置,其对应寄存器为GPHCON,如图6所示。

图6 GPHCON寄存器

  CPHCON[5:4]和GPHCON[7:6]为TXD和RXD管脚设置位,将其功能设置为UART专用通信管脚,因此设置为0b10,分别用于UART数据的发送和接收,即GPHCON |= 0xa0

图7 GPHUP上拉电阻设置寄存器

  GPHUP上拉电阻设置寄存器:上拉电阻用来稳定电平信号,保障传输数据的正确,GPHUP里设置其内部上拉,即GPHUP=0x0

图8 ULCONn寄存器

  通过设置ULCON0来设置UART0通信方式,ULCON0[6]选择通信方式为普通模式操作或红外Tx/Rx模式,ULCON[5:3]设置串口0校验方式,ULCON0[2]设置串口0停止位数,ULCON0[1:0]设置串口0的数据位数。

  我们选择普通通信模式,无校验位,1个停止位,8个数据位的数据通信方式,因此:ULCON0=0x03;

图9 UART0串口控制器寄存器(UCON0)

  通常UART串口采用PCLK作为输入工作时钟,采用简单的轮询方式进行数据接收和发送,不开启数据接收超时,数据产生错误时不产生错误状态中断,因此,UCON0=0x05

图10 UART FIFO控制寄存器(UFCON0)

图11 UART MODEM控制寄存器(UMCON0)

图11 UART 发送/接收状态寄存器

图12 UART 发送缓存寄存器(UTXH0)

图13 UART接收缓存寄存器(URXH0)

图14 UART波特率除数寄存器(UBRDIV0)

  上述寄存器是和UART通信相关的寄存器,使用简单的无FIFO,无自动流控AFC时,设置如下:

  UFCON0 = 0x00;  //不使用FIFO

  UMCON0 = 0x00;  //不使用流控

  UBRDIV0 = 26;  //波特率为115200,PCLK=50MHz

  UBRDIV0 = 53;  //波特率为57600,PCLK=50MHz

  UBRDIV0 = 12;  //波特率为57600,PCLK=12MHz

  UTXH0和URXH0分别是数据发送和接收寄存器,发送数据时通过轮询方式判断发送状态寄存器的状态,当可以发送数据时,执行UTXH0寄存器写入操作,接收数据时,以轮询方式检测接收状态寄存器状态,当有数据到达时,读取URXH0寄存器里的数据即可取得串口数据。

 1 #define  TXD0READY   (1<<2)  //发送数据状态OK
 2 #define  RXD0READY   (1)     //接收数据状态OK
 3
 4 /* UART串口单个字符打印函数 */
 5 extern void putc(unsigned char c)
 6 {
 7     while( ! (UTRSTAT0 & TXD0READY) );
 8     UTXH0 = c;
 9 }
10
11 /* UART串口接受单个字符函数 */
12 extern unsigned char getc(void)
13 {
14     while( ! (UTRSTAT0 & RXD0READY) );
15     return URXH0;
16 }
时间: 2024-10-16 17:56:40

S3C2440 UART串口驱动的相关文章

Tiny4412之串口(Uart)驱动编写

一:tiny4412串口驱动编写 1.串口通信简介 串口通信指串口按位(bit)发送和接收字节,串口通信的概念非常简单,串口按位(bit)发送和接收字节.尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线 接收数据.它很简单并且能够实现远距离通信.比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间的长度不得超过2 米:而对于串口而言,长度可达1200米. 串口通信所采用的通信协议为RS-232,RS-232通信方式允许简单连

linux串口驱动分析

linux串口驱动分析 硬件资源及描写叙述 s3c2440A 通用异步接收器和发送器(UART)提供了三个独立的异步串行 I/O(SIO)port,每一个port都能够在中断模式或 DMA 模式下操作.UART 使用系统时钟能够支持最高 115.2Kbps 的波特率.每一个 UART 通道对于接收器和发送器包含了 2 个 64 位的 FIFO. 寄存器 名称 地址 在linux中的描写叙述 (2410 和 2440 处理器对内存地址映射关系同样) UART 线性控制寄存器(ULCONn) ULC

Smart210学习记录------linux串口驱动

转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=27025492&id=327609 一.核心数据结构 串口驱动有3个核心数据结构,它们都定义在<#include linux/serial_core.h> 1.uart_driver uart_driver包含了串口设备名.串口驱动名.主次设备号.串口控制台(可选)等信息,还封装了tty_driver(底层串口驱动无需关心tty_driver). struct

(三) UART 串口通讯

UART  : university asynchronous receiver and transmitter UART  // 通用异步接收器和发送器 为什么要有串口:因为许多嵌入式设备没有显示屏,无法获得设备的实事数据信息,所以可以通过 UART 串口和超级终端相连,打印嵌入式设备输出信息.也可以通过串口跟踪和调试. 比如设备: 网络路由器.交换机通过串口配置, GPS接收器通过串口输出GPS接收的数据. 1.异步通信技术:发送和接收方没有同步时钟,只有数据线,但是协商好了协议,(固定频率

串口驱动

一.串口驱动中的数据结构 尽管一个特定的UART设备驱动完全可以按照tty驱动的设计方法来设计,即定义tty_driver并实现tty_operations其中 的成员函数,但是Linux已经在文件serial_core.c中实现了UART设备的通用tty驱动层,称为串口核心层,这样,UART驱动的主要任 务变成了实现serial_core.c中定义的一组uart_xxx接口而非tty_xxx接口. 1.1下图描述了串行系统间的层次结构关系,可以概括为: 用户应用层 --> 线路规划层 -->

tiny4412 串口驱动分析 --- u-boot中的串口驱动

作者:彭东林 邮箱:[email protected] 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 u-boot:U-Boot 2010.12 Linux内核版本:linux-3.0.31 Android版本:android-4.1.2 我们以tiny4412为例分析串口驱动,下面我们从u-boot开始分析,然后再分析到Linux. 串口初始化 关于这部分代码流程参考件:tiny4412 u-boot 启动

12.2440串口驱动程序设计

12.2440串口驱动程序设计 串口的功能就是接受数据跟发送数据的,在上一节已经了解串口的引脚信号.但是数据的收发需要一定的条件,也就是串口的初始化.所以所以今天的内容就会被划分为三个部分: 1.串口的初始化: 创建一个uart.c来对串口进行处理,然后把它加入到Makefile工程文件里: 接着就是串口处理程序的实现了. 程序的刚开始是对串口进行初始化,初始化的步骤: 配置引脚功能 设置数据模式 设置工作模式 设置波特率. 1)配置引脚功能: 在2440里的串口底板原理图: 上面的11 TXD

串口驱动程序设计详解---串口初始化(上)

TTY驱动程序架构: 1. TTY概念解析 1.1 /dev/ttySCA0 1.2 /dev/tty1-n 1.3 /dev/console 在linux系统中,终端是一类字符型设备,它包括多种类型,通常使用tty来简称各种类型的终端设备. . 串口终端(/dev/ttyS*) 串口终端是使用计算机串口连接的终端设备.Linux把每个串行端口都看做是一个字符设备.这些串行端口所对应的设备名称是/dev/ttySAC*; .控制台终端(/dev/console) 在Linux系统中,计算机的输出

Linux下使用putty进行UART串口调试【转】

本文转载自:http://blog.csdn.net/xzongyuan/article/details/11593101 版权声明:本文为博主原创文章,未经博主允许不得转载. 使用putty进行串口调试,非常简单.只需要设置好端口(Serial Line),Linux中默认接上串口后,端口为ttyS0,或者ttyUSB0(对应USB转串口),如果再多接一个,就会显示ttyS1或者ttyUSB1:Window中,普通串口对应的是COM1.COM2,USB对应COM3(需要安装驱动,在设备管理器查