s3c2440的uart知识点

发布者:心灵之舞最新更新时间:2020-06-14 来源: eefocus关键字:S3C2440  UART  时钟频率 手机看文章 扫描二维码
随时随地手机看文章

s3c2440的uart和stm32、51的uart都是大同小异的。但是还是专门写一下。其实是自己作总结而已。(本文只是涉及uart的基本情况,程序的话,只有查询模式。fifo、中断、DMA还没学,后面可能会补上)


以下是它的特点:

s3c2440有三个独立的uart模块,都支持查询、中断模式或者DMA模式。

这三个uart都可以选择(非)fifo模式。Fifo适用于大规模数据传送,可能在DMA需要用到。

uart0和uart1可支持自动流控制(Auto Flow Control)模式,用来检测是否可用。有特殊的位的对应引脚。(但好像stm32的uart功能更多点,深入学习后作比较)


时钟来源和时钟频率的设定

uart的时钟源有两个选择:内部的PCLK分配的单元时钟(不管FCLK是晶振提供的,还是EXTCLK提供的),或者直接由外部EXTCLK提供的时钟频率。使用前者,uart的baud rate可以达到921.6kbps(最高),而接EXTCLK,可以达到更多的baud rate。

存储波特率寄存器是16位的UBRDIVn ,具体应该存放的值,是如下计算的:

UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1

( UART clock: PCLK, FCLK/n or UEXTCLK )


中断

具体的中断情况实际中是一定要用的,等到以后学了中断,再补充(后面寄存器那里,有稍微提及)。

在no-fifo mode下产生的中断(就是说,有多种error情况,但都是进入这两个interrupt里,再读取对应的位,做判断):

Rx interrupt :当数据从移位器shifter在代码的控制下,成功传给其他地区时,产生中断(这时的shifter还没有清空,需要程序清除)

Tx interrupt :当数据在代码的控制下成功地从其他地区传给shifter时,产生中断。

Error interrupt:所有报错的error都会导致中断,但是一次只能有一个。

在fifo mode下产生的中断(就是说,有多种error情况,但都是进入这两个interrupt里,再读取对应的位,做判断):

Rx interrupt :当fifo接收的数据达到溢出/触发中断标准时,产生中断。或者是没有达到溢出,但是等待了3个word的时间,仍没有收到数据。

Tx interrupt :当fifo所有待发送的数据都发送出去时,产生中断

Error interrupt:所有报错的error都会导致中断

UART除了Rx FIFO寄存器外,还有FIFO错误状态寄存器。错误状态FIFO表示其中的哪些数据具有一个错误(具体的错误就是上面写的那些frame error之类的)。只有当数据有错误时,才会发出错误中断,准备好读出来了。要清除错误状态FIFO,必须读出带有错误和UERSTATn的URXHn(就是上面写的那些frame error之类的)


DMA

DMA也是很重要的,学了后要补充。


fifo与非fifo的区别

S3C2440A的UART内部对于接收和发送各有64字节的缓冲区,当使用FIFO模式时,UART将使用这个缓冲区进行数据暂存操作,这样可以增加数据吞吐量,提高传输速率。其实,非FIFO模式也可以看作是特殊的FIFO模式,即只有一个字节(注意,只有一个字节)缓冲区的FIFO模式。

二者的主要不同在于读取缓冲区状态的方式:非FIFO模式下,通过UTRSTAT寄存器得知收发缓冲区状态;FIFO模式下,则从UFSTAT寄存器获得缓冲区状态。要注意的是,在FIFO模式下,只有达到触发级别后才会发起Rx或Tx中断。比如说,如果设置接收触发级别为16字节,则只有在接收缓冲区中有16个字节以上数据时,才会发起Rx中断请求。如果需要进行输入回显,即是立即显示,则可能导致不能立即回显用户在串口工具中输入的字符(如果用fifo模式的话,字节数达不到中断,即回复的要求)。所以这时,就要使用非fifo模式。


Auto Flow Control(自动流控制)

用于通讯双方都是使用uart口时。S3C2440中的UART用nRTS(发送请求信号)和nCTS(清除发送信号)来支持自动流控制,以此实现UART之间的互联。

在AFC模式下,nRTS依赖于接收器的条件和nCTS信号控制发送器的运行。UART的发送器只当nCTS信号被激活(AFC模式下,nCTS信号意味另一个UART的FIFO已经准备好接收数据了)才发送数据到另一个UART的FIFO里。在UART接收数据的时候,当接收FIFO有大于32-byte的空闲空间时nRTS必须被激活 ,在接收FIFO的空闲空间小于32-byte(在AFC模式下,nRTS信号意味自己的接收FIFO准备好接收数据)时nRTS必须被取消激活。

UART2不支持AFC功能。


uart的工作流程

首先,发射器和接收器各包含64字节(不是64位,是64字节)的fifo和数据移位器。

如果是fifo,初始化uart之后,是先将数据写入FIFO,然后复制到传输移位器在传输之前。然后由传输数据pin (TxDn)将数据移出。同时,接收数据为从接收数据pin (RxDn)进行移位,然后从移位器复制到FIFO。

使用的是非fifo模式的话,其实也是用了FIFO中的一个字节的空间,作为先存进去的地方而已,不存在直接放进传输移位器的做法(如果是这样做的话,就是需要通过程序一位一位放进去了)。

接收到的数据是放到接收缓存器URXHn中,要发送数据时,是把数据放入发送缓存器UTXHn中。由于UART是通过字节方式传输数据的,因此要区分是大端模式还是小端模式,也就是说这两个寄存器在这两种模式下,读取出来的结果是不同的(有默认的情况,不修改就好了)。


Uart的状态和与interrupt、DMA的对应

每个uart都有7种状态信号(其实也是一些1位的寄存器位): Overrun error, Parity error, Frame error, Break, Receive buffer data ready, Transmit buffer empty, and Transmit shifter empty。分别是overrun错误,校验错误,帧错误,断点,接收缓冲区准备好,发送缓冲区为空,发送移位寄存器为空

前面四个是作为错误信号的,有相应的寄存器位,所以当这四个位被自动置1时,且中断允许位被打开,如果发生错误,就会去进入receive error status中断(硬件自身检测的),然后需要在中断子程序里代码自己去if()查询对应的位,到底是哪个error,并作出解决方案。

后面三个是作为正确信号的,通过读取,来执行下一步的程序,当然都可以进入中断。一般判断发送是否完成的是,判断Transmit buffer empty对应的那个位,因为这个位是Transmit shifter empty成立前提下,才会成立的。


自己之前的疑问:如果不是auto-flow的模式的话,要关闭auto-flow的位,但是, nRTS 和nCTS还要不要在程序里进行控制?

看了些资料发现是,如果不是auto-flow的模式的话,要关闭auto-flow的位,但是在fifo模式下,nRTS 和nCTS还要在程序里进行控制,非fifo不需要。


没有使用自动流控的例子(需要软件控制nRTS和nCTS)


1)使用FIFO的接收操作

选择接收模式(interrupt or DMA mode);

检查UFSTATn寄存器里的RX FIFO计数值 。假如这个值小于32,用户需要设置UMCONn[0]为‘1’(激活nRTS),如果等于或者大于32,用户需要设置这个值为‘0’(使nRTS无效);

一直重复步骤2。

2)使用FIFO的发送操作

选择发送模式(interrupt or DMA mode)

检查UMSTATn[0]的值。如果该值为‘1’(nCTS被激活),用户可以写数据到Tx FIFO寄存器


其余的几种模式

Loopback Mode :就是自发自收。当然,需要线来连接引脚的

Infrared (IR) mode :紫外线模式,不知道是什么。

可以看下面这个链接,感觉里面的内容是直接翻译2440手册的。

https://www.cnblogs.com/sky-heaven/p/5031783.html

寄存器方面

Uart line控制寄存器:ULCONx(UART LINE CONTROL REGISTER )

Register Address R/W Description Reset Value

ULCON0 0x50000000 R/W UART channel 0 line control register 0x00

ULCON1 0x50004000 R/W UART channel 1 line control register 0x00

ULCON2 0x50008000 R/W UART channel 2 line control register 0x00

内部的位的作用:

在这里插入图片描述

Uart 控制寄存器(uart control register)


Register Address R/W Description Reset Value

UCON0 0x50000004 R/W UART channel 0 control register 0x00

UCON1 0x50004004 R/W UART channel 1 control register 0x00

UCON2 0x50008004 R/W UART channel 2 control register 0x00

位的作用:


在这里插入图片描述
在这里插入图片描述

注意的是:

FCLK Divider 这一部分的位,对于uart0、1、2是不一样的。(为什么要设置有FCLK/n这个呢,而不是全用PCLK,是考虑到APB上挂了不同的外设单元,用FCLK/n这种情况,可以有效地使各种外设得到自己合适的外设。

时钟来源选择是FCLK/n的话,是需要使用延时的:Delay(1); // about 100us

Rx/Tx Interrupt Type这两个位,类型是pulse(脉冲式)和level(电平式)。前者是as soon as,后者是while,需要等待一段时间的。


Uart的fifo控制寄存器:UART FIFO CONTROL REGISTER


Register Address R/W Description Reset Value

UFCON0 0x50000008 R/W UART channel 0 FIFO control register 0x0

UFCON1 0x50004008 R/W UART channel 1 FIFO control register 0x0

UFCON2 0x50008008 R/W UART channel 2 FIFO control register 0x0

位的内容是: ![](https://img-blog.csdnimg.cn/20190225202542290.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MTgxODEx,size_16,color_FFFFFF,t_70) Uart调制解调器控制寄存器:UART MODEM CONTROL REGISTER

Register Address R/W Description Reset Value

UMCON0 0x5000000C R/W UART channel 0 Modem control register 0x0

UMCON1 0x5000400C R/W UART channel 1 Modem control register 0x0

Reserved 0x5000800C – Reserved Undef

位的内容是:

在这里插入图片描述

(这个寄存器内容是关于AFC的,所以uart2没有很正常)


Uart的发送/接收状态寄存器:UART TX/RX STATUS REGISTER


Register Address R/W Description Reset Value

UTRSTAT0 0x50000010 R UART channel 0 Tx/Rx status register 0x6

UTRSTAT1 0x50004010 R UART channel 1 Tx/Rx status register 0x6

UTRSTAT2 0x50008010 R UART channel 2 Tx/Rx status register 0x6

位的内容:

在这里插入图片描述

Uart的错误情况寄存器:UART ERROR STATUS REGISTER


Register Address R/W Description Reset Value

UERSTAT0 0x50000014 R UART channel 0 Rx error status register 0x0

UERSTAT1 0x50004014 R UART channel 1 Rx error status register 0x0

UERSTAT2 0x50008014 R UART channel 2 Rx error status register 0x0

位的内容:

在这里插入图片描述

注意:该寄存器的这些位,在被读取之后会硬件自动置零。


Uart的fifo状态寄存器(只能读取):UART FIFO STATUS REGISTER


Register Address R/W Description Reset Value

UFSTAT0 0x50000018 R UART channel 0 FIFO status register 0x00

UFSTAT1 0x50004018 R UART channel 1 FIFO status register 0x00

UFSTAT2 0x50008018 R UART channel 2 FIFO status register 0x00

位的内容:

在这里插入图片描述

这个寄存器只是显示了fifo是否被填满了,以及fifo到底有多少位而已,但是还是没有透漏出fifo的物理地址。


Uart的调制器状态寄存器:UART MODEM STATUS REGISTER


Register Address R/W Description Reset Value

UMSTAT0 0x5000001C R UART channel 0 modem status register 0x0

UMSTAT1 0x5000401C R UART channel 1 modem status register 0x0

Reserved 0x5000801C – Reserved Undef

位的内容·:

在这里插入图片描述

Uart的发送缓冲区寄存器:UART TRANSMIT BUFFER REGISTER (HOLDING REGISTER & FIFO REGISTER)


Register Address R/W Description Reset Value

UTXH0 0x50000020(L) 0x50000023(B) W (by byte) UART channel 0 transmit buffer register –

UTXH1 0x50004020(L) 0x50004023(B) W (by byte) UART channel 1 transmit buffer register –

UTXH2 0x50008020(L) 0x50008023(B) W (by byte) UART channel 2 transmit buffer register –

每一个UTXHn都有一个8位的数据缓冲区:

UTXHn Bit Description Initial State

TXDATAn [7:0] Transmit data for UARTn –

注意:

L是指尾端(endian)模式是小尾端模式

B是指尾端(endian)模式是大尾端模式


Uart的接收缓存区寄存器:UART RECEIVE BUFFER REGISTER (HOLDING REGISTER & FIFO REGISTER)


Register Address R/W Description Reset Value

URXH0 0x50000024(L) 0x50000027(B) R (by byte) UART channel 0 receive buffer register –

URXH1 0x50004024(L) 0x50004027(B) R (by byte) UART channel 1 receive buffer register –

URXH2 0x50008024(L) 0x50008027(B) R (by byte) UART channel 2 receive buffer register –

每一个URXHn都有一个8位的数据缓冲区:


URXHn Bit Description Initial State

RXDATAn [7:0] Receive data for UARTn –

注意:

1—原来2440的接收buffer和发送buffer是物理上不同地区的,真是新奇。(但是只有8位吗?Fifo又有16、32之类的选择,难道是多个8位一起组成了一个fifo??)

2—当发生overrun error时,必须读取URXHn。如果没有,下一个接收到的数据也会溢出错误,尽管UERSTATn的溢出位已被清除。


Uart的baud rate寄存器:UART BAUD RATE DIVISOR REGISTER

计算公式:

UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1

( UART clock: PCLK, FCLK/n or UEXTCLK )


Register Address R/W Description Reset Value

UBRDIV0 0x50000028 R/W Baud rate divisior register 0 –

UBRDIV1 0x50004028 R/W Baud rate divisior register 1 –

UBRDIV2 0x50008028 R/W Baud rate divisior register 2 –

每一个寄存器对应的内容:


UBRDIVn Bit Description Initial State

UBRDIV [15:0] Baud rate division value UBRDIVn > 0 .If using the UEXTCLK as input clock,UBRDIVn can be set‘0’. -

以下是查询模式的程序:

start.S



.text

.global _start


_start:

  

    /***

  关闭watchdog 

****/


    ldr r0, = 0x53000000   @将看门狗寄存器的地址写入到r0里,将要赋的值写入r1中,并传给r0。 

ldr r1, = 0            @值得说明的是,这只是关闭watchdog,不是去喂它 

str r1, [r0]  


    /***

  设置时钟,FCLK = 400MHz  FCLK : HCLK: PCLK = 4:2:1  

****/

  

    ldr r0, = 0x4C000000    @设置locktime 

ldr r1, = 0xFFFFFFFE

str r1, [r0]

ldr r0, = 0x4C000004      @设置MPLL的输出频率(在这里,输出频率是等于了FCLK) 

ldr r1, = (92<<12)|(1<<4)|(1<<0)    @数值格式可能有错,没错,这样写也是16进制数,同时<<的优先级低于 |  

str r1, [r0]

ldr r0, = 0x4C000014     @设置HCLK,PCLK  

ldr r1, = (1<<1)|(1<<0) 

str r1, [r0]

mrc p15,0,r0,c1,c0,0      @因为FCLK:HCLK != 1:1,则设置异步模式 

orr r0,r0,#0xc0000000     @注意数值是0xc0000000 

mcr p15,0,r0,c1,c0,0



/******

   判断是nor启动还是nand启动。相等的话,是nand启动。如果是nor启动的话,  

******/


mov r1, #0

ldr r0, [r1]

str r1, [r1]

ldr r2, [r1] 

cmp r1, r2

ldr sp, =0x40000000+4096    @先默认是nor启动 

moveq sp, #4096

streq r0, [r1]              @修改了的值,要在这里恢复 

/*** 

真正运行的内容,前面都是初始化的东西:clock、nor/nand的选择 

***/ 

/* 设置内存: sp 栈 */

@ldr sp, =4096  /* nand启动,先不执行这一行代码 */

    //ldr sp, =0x40000000+4096  /* nor启动 */


/* 调用main */

bl main


halt:

b halt

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

main.c


#include"s3c2440_soc.h"

#include"uart0.h"


#define uchar unsigned char




int main()

{

uart0_init();

putString("this is uart0n");  // 先打印出来 

uchar tmp;

while(1){

tmp = (uchar) getchar();     //这就是重复打印了 

putchar(tmp);

}

return 0;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

uart0.c:


#include"s3c2440_soc.h"

#include"uart0.h"

/***

   使用引脚,GPH2——txd0 GPH3——rxd0 

   用PCLK(100m)作为时钟源、normal模式,无中断,非fifo,非AFC,

[1] [2]
关键字:S3C2440  UART  时钟频率 引用地址:s3c2440的uart知识点

上一篇:s3c2440串口接收中断(OK2440III)
下一篇:s3c2440串口详解

推荐阅读最新更新时间:2024-11-11 06:28

11.S3C2440 中断实验(五)定时器中断实验
定时器中断实验 S3C2440提供了3种时钟:FCLK用于CPU核;HCLK用于AHB总线上的设备,比如存储器控制器、中断控制器、LCD控制器、DMA和USB主机模块,同时也可以在特殊情况下用于CPU核;而PCLK则用于APB总线上的设备,比如看门狗、IIS、IIC、PWM定时器、ADC、UART、GPIO、RTC和SPI等。 总的来说,AHB总线主要用于高性能模块,APB总线主要用于低带宽的周边外设之间的连接。 S3C2440定时器的总时钟源为PCLK,首先通过两个8位的预分频器降低频率,定时器0、1共用第一个预分频器,定时器2、3、4共用第二个预分频器;之后预分频器的输出将被第二级的五路选择分频
[单片机]
11.S3C2440 中断实验(五)定时器中断实验
05-S3C2440学习之内核(移植)linux3.4.2移植(2)之yffs2文件系统移植+内核裁剪+内核制作补丁
一、移植YFFS2文件系统 yffs文件系统更加支持nand设备 上节移植了jffs2文件系统(点击查看)到移植的内核中,这节我们将yffs2文件系统移植到刚移植好的内核中。 (1)获取源码并解压 git clone git://www.aleph1.co.uk/yaffs2 tar xjf yaffs2.tar.bz2 (2)给内核打上yffs2补丁 ./patch-ker.sh c m /home/book/linux-3.4.2 ++ (3) 配置内核支持YAFFS 1. ls fs/yaffs2 (4)编译、生成uImage 出错,制作yffs2 source工程.
[单片机]
05-S3C2440学习之内核(移植)linux3.4.2移植(2)之yffs2文件系统移植+内核裁剪+内核制作补丁
S3C2440的RTC解析
S3C2440拥有一个实时时钟模块, 可以在当系统电源关闭后通过备用电池工作。RTC可以通过使用STRB/LDRB ARM操作发送8位二-十进制交换码(BCD)值数据给CPU。这些数据包括年、月、日、星期、时、分和秒的时间信息。RTC单元工作在外部32.768kHz晶振并且可以执行闹钟功能 实时时钟模块保存的数据是DCD码形式. 框图如下 可以看到,要使用实时时钟依靠以下几个寄存器 包含时钟使能和时钟复位(还有两个寄存器是测试模式,我们用不到) 关联着时钟节拍中断,也就是每增加1S发生一次中断 时钟中断,时钟的时分秒年月日都是可以进行使能的 接下来是时分秒年月日闹钟点设置 有六个就不一一列举了,意思是当到达这个时间
[单片机]
<font color='red'>S3C2440</font>的RTC解析
s3C2440 Memory controller
硬件设计篇 首先是BANK0 的选择, 如果是把BANK0 选择连接NAND Flash,需要引脚OM1 和OM0的状态 如果是都设置成0 是NAND FLASH 模式。。 NANDFlash 模式会自动的 NANDFLASH前4MB的内容拷贝到内存中来。 其次是S3C2440 的SDRAM的引脚如下: nSRAS: SDRAM行选择引脚  nSCAS: SDRAM 列选择引脚 nSCS: 片选信号 DQM : 掩码,就是为了屏蔽不需要的位, 比如一个连接了32位的芯片需要写入一个8bit的数据,那么其他的的位就会被掩码屏蔽 SCLK:时钟 SCKE: 时钟使能 nBE :DATA mask。 因为每次SDRAM只能从内核
[单片机]
STM32L0xx_HAL_Driver库的使用——UART
单片机型号:STM32L051C8T6 开发环境MDK5.12 库版本:STM32L0xx_HAL_Driver V1.1.0 主机环境:Windows XP 之前一直使用的STM32F030C8T6单片机来做开发,因需求更改更换了一个新型号STM32L051C8T6,主要是用到了其低功耗特性,本以为直接把代码拷贝一下就可以使用了,结果是太天真了,STM32F030C8T6使用的库是STM32F0_StdPeriph_Lib而STM32L051C8T6使用的库是STM32L0xx_HAL_Driver两者的差别还是很大的,而且官方也推荐使用后者,没办法,重新学习一下吧。。。参考其例程磕磕绊绊的勉强可以写一个工程了,
[单片机]
S3C2440裸奔触摸屏
S3C2440对于触摸屏的相关interface有以下几个模式: 1.普通转换模式,手册是这么说的:most likely used for General Purpose ADC Conversion.(不了解这个,所以用原文) 2.分开X/Y转换模式,就是分开来转换X位置和Y位置。X位置的信息会保存在ADCDAT0的低10位,而Y位置信息则保存在ADCDAT1的低10位。 3.自动X/Y转换模式,就是会把和X和Y一起转换,然后X,Y位置信息保存跟上面一样,也是在ADCDAT0,ADCDAT1的低10位。(我想一般会用这个模式) 4.等待中断模式,也就是等待触摸屏的中断,ADCTSC=0xd3就是等待笔尖放下时产生中
[单片机]
RS232与RS485谁才是UART中的高速公路
串口通讯是电子工程师面对的最基本的一个通讯方式,RS-232是其中最简单的一种。然而,很多初学者往往搞不清楚UART和RS-232、RS-422、RS-485的联系和区别,本文将谈谈我对这几个概念的理解,帮助大家理清它们之间的关系。 通讯问题,和交通问题一样,也有高速、低速、拥堵、中断等等各种情况。如果把串口通讯比做交通,UART比作车站,那么一帧的数据就好比汽车。汽车跑在路上,要遵守交通规则。如果是市内,一般限速30、40,而高速公路则可以到120。而汽车走什么路,限速多少,就要看协议怎么规定了。常见的串口协议有RS-232、RS-422、RS-485等,那么谁才是UART中的高速公路?下面我们就一起来探讨一下。 一、U
[单片机]
RS232与RS485谁才是<font color='red'>UART</font>中的高速公路
S3C2440裸机------NandFlash编程_芯片id读取
1.芯片id读取时序图 我们先看一下NandFlash芯片手册中读取id的时序图,后面我们要根据这个时序图去写代码。 2.使能芯片 从前面的时序图我们可以看出,我们首先要发出片选信号,我们通过设置下图寄存器的Reg_nCE位来进行设置, void nand_select(void) { /*使能片选*/ NFCONT &=~(1 1); } void nand_deselect(void) { /*禁止片选*/ NFCONT |= (1 1); } 3.发送命令函数 我们从最前面的时序图可以看到,要想读取设备id,首先要向NandFlash发送90命令,然后相应的CLE和WE信号要使能,这里
[单片机]
<font color='red'>S3C2440</font>裸机------NandFlash编程_芯片id读取
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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