第6章 部件工作原理与编程示例(1)
本章主要以S3C4510B的几个常用功能部件为编程对象,介绍基于S3C4510B的系统的程序设计与调试,同时简介BootLoader的基本原理和编程方法,通过对本章的阅读,可以使读者了解S3C4510B各功能部件的工作原理及基本编程方法。
本章的主要内容包括:
- 嵌入式系统应用程序设计的基本方法。
- S3C4510B通用I/O口的工作原理与编程示例。
- S3C4510B串行通信控制器的工作原理与编程示例。
- S3C4510B中断控制器的工作原理与编程示例。
- S3C4510B定时器的工作原理与编程示例。
- S3C4510B DMA控制器的工作原理与编程示例。
- S3C4510B IIC总线控制器的工作原理。
- S3C4510B 以太网控制器的工作原理。
- Flash存储器的工作原理与编程示例。
- BootLoader简介
6.1 嵌入式系统的程序设计方法
一 般说来,对于一个完整的嵌入式应用系统的开发,硬件的设计与调试工作仅占整个工作量的一半,应用系统的程序设计也是嵌入式系统设计一个非常重要的方面,程 序的质量直接影响整个系统功能的实现,好的程序设计可以克服系统硬件设计的不足,提高应用系统的性能,反之,会使整个应用系统无法正常工作。
本章从应用的角度出发,以S3C4510B的各个功能模块为编程对象,介绍一些实用的程序段,读者既可按自己的需要修改,也可吸收其设计思想和方法,以便设计出适合于自己特定应用系统的实用程序。同时,由于ARM体系结构的一致性,尽管以下的应用程序段是针对特定硬件平台开发的,其编程思路同样适合于其他类型的ARM微处理器。
不同于基于PC平台的程序开发,嵌入式系统的程序设计具有其自身的特点,程序设计的方法也会因系统或因人而异,但其程序设计还是有其共同的特点及规律的。在编写嵌入式系统应用程序时,可采取如下几个步骤:
(1) 明确所要解决的问题:根据问题的要求,将软件分成若干个相对独立的部分,并合理设计软件的总体结构。
(2) 合理配置系统资源:与基于8位或16位微控制器的系统相比较,基于32位微控制器的系统资源要丰富得多,但合理的资源配置可最大限度的发挥系统的硬件潜能,提高系统的性能。对于一个特定的系统来说,其系统资源,如Flash 、EEPROM、SDRAM、中断控制等,都是有限的,应合理配置系统资源。
(3) 程序的设计、调试与优化:根据软件的总体结构编写程序,同时采用各种调试手段,找出程序的各种语法和逻辑错误,最后应使各功能程序模块化,缩短代码长度以节省存储空间并减少程序执行时间。
此外,由于嵌入式系统一般都应用在环境比较恶劣的场合,易受各种干扰,从而影响到系统的可靠性,因此,应用程序的抗干扰技术也是必须考虑的,这也是嵌入式系统应用程序不同于其他应用程序的一个重要特点。
6.2 部件工作原理与编程示例
6.2.1 通用I/O口工作原理与编程示例
S3C4510B提供了18个可编程的通用I/O端口,用户可将每个端口配置为输入模式、输出模式或特殊功能模式,由片内的特殊功能寄存器IOPMOD和IOPCON控制。
端口0~端口7的工作模式仅由IOPMOD寄存器控制,但通过设置IOPCON寄存器,端口8~端口11可用作外部中断请求INTREQ0~INTREQ3的输入,端口12、端口13可用作外部DMA请求XDREQ0、XDREQ1的输入,端口14、端口15可作为外部DMA请求的应答信号XDACK0、XDACK1,端口16可作为定时器0的溢出TOUT0,端口17可作为定时器1的溢出TOUT1。
I/O端口的功能模块如图6.2.1所示:
图6.2.1 通用I/O口的功能模块
控制I/O口的特殊功能寄存器一共有3个:IOPMOD、IOPCON和IOPDATA,简要描述如下:
I/O口模式寄存器(IOPMOD):
I/O口模式寄存器IOPMOD用于配置P17~P0。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
IOPMOD | 0x5000 | 读/写 | I/O口模式寄存器 | 0x0000,0000 |
[0]P0口的I/O模式位
0=输入
1=输出
[1]P1口的I/O模式位
0=输入
1=输出
[2]P2口的I/O模式位
0=输入
1=输出
[3~17]P3~P17口的I/O模式位
0=输入
1=输出
I/O口控制寄存器(IOPCON):
I/O口控制寄存器IOPCON用于配置端口P8~P17的特殊功能,当这些端口用作特殊功能(如外部中断请求、外部中断请求应答、外部DMA请求或应答、定时器溢出)时,其工作模式由IOPCON寄存器控制,而不再由IOPMOD寄存器。
对于特殊功能输入端口,S3C4510B提供了一个滤波器用于检测特殊功能信号的输入,如果输入信号电平宽度等于三个系统时钟周期,该信号被认为是诸如外部中断请求或外部DMA请求等特殊功能信号。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
IOPCON | 0x5004 | 读/写 | I/O口控制寄存器 | 0x0000,0000 |
[4:0]控制端口8的外部中断请求信号0(xIRQ0)输入
[4]端口8用作外部中断请求信号0
0 = 禁止 1 = 使能
[3] 0 = 低电平有效 1 = 高电平有效
[2] 0 = 滤波器关 1 = 滤波器开
[1:0] 00 = 电平检测 01 = 上升沿检测
10 = 下降沿检测 11 = 上升、下降沿均检测
[9:5]控制端口9的外部中断请求信号1(xIRQ1)输入
使用方法同端口8。
[14:10]控制端口10的外部中断请求信号2(xIRQ2)输入
使用方法同端口8。
[19:15]控制端口11的外部中断请求信号3(xIRQ3)输入
使用方法同端口8。
[22:20]控制端口12的外部DMA请求信号0(DRQ0)输入
[22]端口12用作外部DMA请求信号0(nXDREQ0)
0 = 禁止 1 = 使能
[21] 0 = 滤波器关 1 = 滤波器开
[20] 0 = 低电平有效 1 = 高电平有效
[25:23]控制端口13的外部DMA请求信号1(DRQ1)输入
[25]端口13用作外部DMA请求信号1(nXDREQ1)
0 = 禁止 1 = 使能
[24] 0 = 滤波器关 1 = 滤波器开
[23] 0 = 低电平有效 1 = 高电平有效
[27:26]控制端口14的外部DMA应答信号0(DAK0)输出
[27]端口14用作外部DMA信号0(nXDACK0)
0 = 禁止 1 = 使能
[26] 0 = 低电平有效 1 = 高电平有效
[29:28]控制端口15的外部DMA应答信号1(DAK1)输出
[29]端口15用作外部DMA信号1(nXDACK1)
0 = 禁止 1 = 使能
[28] 0 = 低电平有效 1 = 高电平有效
[30]控制端口16作为定时器0溢出信号(TOEN0)
0 = 禁止 1 = 使能
[31]控制端口17作为定时器1溢出信号(TOEN1)
0 = 禁止 1 = 使能
I/O口数据寄存器(IOPDATA):
当配置为输入模式时,读取I/O口数据寄存器IOPDATA的每一位对应输入状态,当配置为输出模式时,写每一位对应输出状态。位[17:0]对应于18个I/O引脚P17~P0。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
IOPDATA | 0x5008 | 读/写 | I/O口数据寄存器 | 未定义 |
[17:0]对应I/O口P17~P0的读/写值。I/O口数据寄存器的值反映对应引脚的信号电平。
以上简述了S3C4510B的通用I/O口的基本工作原理,更详细的内容可参考S3C4510B的用户手册。
作为本章的第一个例子,将比较详细的描述建立项目、编写程序的过程,同时可参考第八章关于ADS集成编译调试环境的使用方法。
打开CodeWarrior for ARM Developer Suite(或ARM Project Manager),新建一个项目,并新建一个文件,名为Init.s,具体内容如下:
;**************************************************************
;Institute of Automation, Chinese Academy of Sciences
;File Name: Init.s
;Description:
;Author: JuGuang.Lee
;Date:
;**************************************************************
IMPORT Main
AREA Init,CODE,READONLY
ENTRY
LDR R0, =0x3FF0000
LDR R1, =0xE7FFFF80 ;配置SYSCFG,片内4K Cache,4K SRAM
STR R1, [R0]
LDR SP, =0x3FE1000 ;SP指向4K SRAM的尾地址,堆栈向下生成
BL Main
B .
END
该段代码完成的功能为:
配置SYSCFG特殊功能寄存器,将S3C4510B片内的8K一体化的SRAM配置为4K Cache,4K SRAM,并将用户堆栈设置在片内的SRAM中。
4K SRAM的地址为0x3FE,0000~(0x3FE,1000-1),由于S3C4510B的堆栈由高地址向低地址生成,将SP初始化为0x3FE,1000。
完成上述操作后,程序跳转到Main函数执行。
保存Init.s,并添加到新建的项目。
再新建一个文件,名为main.c,具体内容如下:
/*****************************************************************
* Institute of Automation,Chinese Academy of Sciences
* File Name: main.c
* Description:
* Author: JuGuang.Lee
* Date:
***************************************************************/
#define IOPMOD (*(volatile unsigned *)0x03FF5000) //IO port mode register
#define IOPDATA (*(volatile unsigned *)0x03FF5008) //IO port data register
void Delay(unsigned int);
int Main()
{
unsigned long LED;
IOPMOD=0xFFFFFFFF; //将IO口置为输出模式
IOPDATA=0x01;
for(;;){
LED=IOPDATA;
LED=(LED<<1);
IOPDATA=LED;
Delay(10);
if(!(IOPDATA&0x0F))
IOPDATA=0x01;
}
return(0);
}
void Delay(unsigned int x)
{
unsigned int i,j,k;
for(i=0;i<=x;i++)
for(j=0;j<0xff;j++)
for(k=0;k<0xff;k++);
}
保存main.c,并添加到新建的项目。此时可对该项目进行编译链接,生成可执行的映象文件。
可执行的映象文件主要用于程序的调试,一般在系统的SDRAM中运行,并不烧写入Flash,因此,项目文件在链接时,注意程序的入口点应与系统中SDRAM的实际配置地址相对应。链接器默认程序的入口地址为0x8000,该值应根据实际的SDRAM映射地址进行修改。
在编译链接项目文件时,将链接器程序的入口地址为0x0040,0000。
打开AXD Debugger(或ARM Debugger for Windows)的命令行窗口,执行obey命令:
>obey C:/memmap.txt
系统中SDRAM被映射到0x0040,0000~(0x0140,0000-1),从0x0040,0000处装入生成的可执行的映象文件,并将PC指针寄存器修改为0x0040,0000,就可单步调试或运行生成的可执行的映象文件。
该程序的运行效果为接在P0~P3口的LED显示器轮流被点亮。
6.2.2 串行通讯工作原理与编程示例
串行通讯是微计算机之间一种常见的近距离通讯手段,因使用方便、编程简单而广泛使用,几乎所有的微控制器、PC都提供串行通讯接口。
S3C4510B的UART单元提供两个独立的异步串行I/O口(Asynchronous Serial I/O,SIO),每个通讯口均可工作在中断模式或DMA模式,也即UART能产生内部中断请求或DMA请求在CPU和串行I/O口之间传送数据。
S3C4510B的UART单元特性包括:
- 波特率可编程
- 支持红外发送与接收
- 1~2个停止位
- 5、6、7或8个数据位
- 奇偶校验
每一个异步串行通讯口都具有独立的波特率发生器、发送器、接收器和控制单元。波特率发生器可由片内系统时钟MCLK驱动,或由外部时钟UCLK(Pin64)驱动;发送器和接收器都有独立的数据缓冲寄存器和数据移位器。
待发送的数据首先传送到发送缓冲寄存器,然后拷贝到发送移位器并通过发送数据引脚UATXDn发送出去。接收数据首先从接收数据引脚UARXDn移入移位器,当接收到一个字节时就拷贝到接收缓冲寄存器。
SIO的控制单元通过软件控制工作模式的选择、状态和中断产生。
当使用UART的发送中断功能时,应在初始化UART之前先写一个字节数据到UART的发送缓冲寄存器,这样,当发送缓冲寄存器空时就可以产生UART的发送中断。
图6.2.2为串行口的功能模块。
图6.2.2 串行口功能模块。
表6-2-1为UART特殊功能寄存器描述
表6-2-1 UART特殊功能寄存器
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
ULCON0 | 0xD000 | 读/写 | UART0行控制寄存器 | 0x00 |
ULCON1 | 0xE000 | 读/写 | UART1行控制寄存器 | 0x00 |
UCON0 | 0xD004 | 读/写 | UART0控制寄存器 | 0x00 |
UCON1 | 0xE004 | 读/写 | UART1控制寄存器 | 0x00 |
USTAT0 | 0xD008 | 读 | UART 0状态寄存器 | 0xC0 |
USTAT1 | 0xE008 | 读 | UART1状态寄存器 | 0xC0 |
UTXBUF0 | 0xD00C | 写 | UART0发送保持寄存器 | 未定义 |
UTXBUF1 | 0xE00C | 写 | UART1发送保持寄存器 | 未定义 |
URXBUF0 | 0xD010 | 读 | UART0接收缓冲寄存器 | 未定义 |
URXBUF1 | 0xE010 | 读 | UART1接收缓冲寄存器 | 未定义 |
UBRDIV0 | 0xD014 | 读/写 | UART0波特率除数因子寄存器 | 0x00 |
UBRDIV1 | 0xE014 | 读/写 | UART1波特率除数因子寄存器 | 0x00 |
BRDCNT0 | 0xD018 | 写 | UART0波特率计数寄存器 | 0x00 |
BRDCNT1 | 0xE018 | 写 | UART1波特率计数寄存器 | 0x00 |
BRDCLK0 | 0xD01C | 写 | UART0波特率时钟****器 | 0x00 |
BRDCLK1 | 0xE01C | 写 | UART1波特率时钟****器 | 0x00 |
UART行控制寄存器(UART Line Control Registers,ULCON0、ULCON1):
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
ULCON0 | 0xD000 | 读/写 | UART0行控制寄存器 | 0x0000,0000 |
ULCON1 | 0xE000 | 读/写 | UART1行控制寄存器 | 0x0000,0000 |
表6-2-2为UART行控制寄存器描述
表6-2-2 UART行控制寄存器描述
位 | 位名 | 功能描述 |
[1:0] | 每帧字长 | 该两位指示发送或接收的每帧的数据位:‘00’=5位,‘01’= 6位,‘10’= 7位,‘11’= 8位。 |
[2] | 停止位数 | 该位指示每帧数据的停止位数:‘0’= 每帧一个停止位,‘1’= 每帧两个停止位。 |
[5:3] | 校验模式 | 该三位指示在数据的发送与接收过程中如何生成校验并进行检测:‘0XX’= 无校验,‘100’= 奇校验,‘101’= 偶校验,‘100’= 奇校验,‘110’=校验强制/检测为1,‘111’=校验强制/检测为0。 |
[6] | 串行时钟选择 | 该位用于选择时钟源: 0 = 内部时钟(MCLK) 1 = 外部时钟(UCLK) |
[7] | 红外模式选择 | S3C4510B的UART模块支持红外(IR)发送与接收。要使能红外模式,需设置ULCON[7]为1,否则选择正常UART模式。 |
00=5位 01=6位
10=7位 11=8位
[2]帧末尾停止位(STB)
0 = 每帧一个停止位
1 = 每帧两个停止位
[5:3]校验模式(PMD)
0xx = 无校验
100 = 奇校验
101 = 偶校验
110 = 校验强制/检测为1
111 = 校验强制/检测为0
[6]串行时钟选择(SC)
0 = 内部时钟(MCLK)
1 = 外部时钟(UCLK)
[7]红外模式选择(IR)
0 = 正常操作模式
1 = 红外发送模式
UART控制寄存器(UART Control Registers,UCON0、UCON1):
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
UCON0 | 0xD004 | 读/写 | UART0控制寄存器 | 0x0000,0000 |
UCON1 | 0xE004 | 读/写 | UART1控制寄存器 | 0x0000,0000 |
表6-2-3为UART控制寄存器描述
表6-2-3 UART控制寄存器描述
位 | 位名 | 功能描述 |
[1:0] | 接收模式选择 | 该两位的值决定当从UART接收缓冲寄存器中读取数据时的当前功能: ‘00’=禁止Rx模式, ‘01’=产生中断请求, ‘10’=产生GDMA通道0请求, ‘11’=产生GDMA通道1请求。 |
[2] | 接收状态中断使能 | 该位决定当在数据的接收过程中发生异常(如发生间断、帧错误、校验错误或Overrun错误)时是否让UART产生中断请求: ‘0’= 不产生接收状态中断请求, ‘1’= 产生接收状态中断请求。 |
[4:3] | 发送模式选择 | 该两位的值决定当写数据到UART发送缓冲寄存器中时的当前功能: ‘00’=禁止Tx模式, ‘01’=产生中断请求, ‘10’=产生GDMA通道0请求, ‘11’=产生GDMA通道1请求。 |
[5] | 数据设备准备好 | 该位选择是否产生数据设备准备好(DSR)信号输出: 0 = 不产生DSR输出, 1 = 产生DSR输出(nUADSR引脚)。 |
[6] | 发送间隔 | 该位选择是否发送间隔信号: 0 = 不发送间隔信号, 1 = 发送间隔信号。 |
[7] | 回环模式选择 | 该位选择UART是否进入回环模式。在回环模式下,发送的数据的输出置为高电平,发送缓冲寄存器UTXBUF在内部直接连接到接收缓冲寄存器URXBUF。 回环模式仅用于测试目的,在正常操作模式下,该位应为‘0’。 |
[1:0]接收模式选择(RxM)
00 = 禁止
01 = 产生中断请求
10 = 产生GDMA通道0请求
11 = 产生GDMA通道1请求
[2]接收状态中断使能(RxSI)
0 = 不产生接收状态中断
1 = 产生接收状态中断
[4:3]发送模式选择(TxM)
00 = 禁止
01 = 产生中断请求
10 = 产生GDMA通道0请求
11 = 产生GDMA通道1请求
[5]数据设备准备好(DSR)
0 = 不产生DSR输出(nUADSR引脚)
1 = 产生DSR输出(nUADSR引脚)
[6]发送间隔(SBK)
0 = 发送间隔信号
1 = 不发送间隔信号
[7]回环使能(LPB)
0 = 正常工作模式
1 = 使能回环模式(仅用于测试)
UART状态寄存器(UART Status Registers,USTAT0、USTAT1):
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
USTAT0 | 0xD008 | 读 | UART0状态寄存器 | 0x0000,00C0 |
USTAT1 | 0xE008 | 读 | UART1状态寄存器 | 0x0000,00C0 |
表6-2-4为UART状态寄存器描述
表6-2-4 UART状态寄存器描述
位 | 位名 | 功能描述 |
[0] | Overrun错误 | 在接收串行数据的操作中,当发生Overrun错误时,该位自动置为‘1’。在先前接收到的数据还未读出,而被新收到的数据所覆盖时发生Overrun错误。 如果接收状态中断使能位UCON[2]为‘1’,则当Overrun错误发生时产生接收状态中断。 任何时候读取UART状态寄存器USTAT,该位都会自动清零。 |
[1] | 校验错误 | 在接收串行数据的操作中,当发生校验错误时,该位自动置为‘1’。 如果接收状态中断使能位UCON[2]为‘1’,则当校验错误发生时产生接收状态中断。 任何时候读取UART状态寄存器USTAT,该位都会自动清零。 |
[2] | 帧错误 | 在接收串行数据的操作中,当发生数据帧错误时,该位自动置为‘1’。当检测到停止位为‘0’时发生帧错误。 如果接收状态中断使能位UCON[2]为‘1’,则当帧错误发生时产生接收状态中断。 任何时候读取UART状态寄存器USTAT,该位都会自动清零。 |
[3] | 间隔中断 | 当接收到间隔信号时,该位自动置为‘1’。 如果接收状态中断使能位UCON[2]为‘1’,则当接收到间隔信号时产生接收状态中断。 任何时候读取UART状态寄存器USTAT,该位都会自动清零。。 |
[4] | 数据终端准备好 (DTR) | 该位指示数据终端准备好引脚(nUADTR)的当前信号电平。 当该位为‘1’时,数据终端准备好引脚(nUADTR)为低电平,当该位为‘0’时,数据终端准备好引脚(nUADTR)为高电平。 |
[5] | 接收数据准备好 | 当接收缓冲寄存器URXBUF从串行口接收到一个有效数据时,该为自动置为‘1’,然后就可以从URXBUF中读取接收到的有效数据。 当该位为‘0’时表示还未接收到一个有效的数据。 当该位为‘1’时,根据当前UART接收模式位UCON[1:0]的设置,可以产生中断或DMA请求。 |
[6] | 发送缓冲寄存器空 | 当发送缓冲寄存器UTXBUF为空时,该位自动置为‘1’,此时可以向UTXBUF写入下一个要发送的数据。 当该位为‘0’时,表示UTXBUF中的数据还未全部拷贝到发送移位寄存器中,此时不能向UTXBUF中写入新的发送数据。 当该位为‘1’时,根据当前SIO发送模式位UCON[4:3]的设置,可以产生中断或DMA请求。 |
[7] | 发送完成(TC) | 当发送缓冲寄存器UTXBUF为空且发送移位寄存器也为空时,该位自动置为‘1’。该位用于指示软件是否可以在此时禁用发送功能模块。 |
0=在接收过程中未产生Overrun错误
1=Overrun错误(如果UCON[2]置为1,则会产生接收状态中断)
注:当已接收到的数据还未被读取,而新接收的数据覆盖了原有的数据时,就会产生Overrun错误。
[1]校验错误(PE)
0=在接收过程中无校验错误
1=校验错误(如果UCON[2]置为1,则会产生接收状态中断)
[2]帧错误(FE)
0=在接收过程中无帧错误
1=帧错误(如果UCON[2]置为1,则会产生接收状态中断)
[3]间隔信号检测(BKD)
0=未收到间隔信号
1=收到间隔信号(如果UCON[2]置为1,则会产生接收状态中断)
[4]数据终端准备好(DTR)
0=DTR引脚(nUADTR)置高
1=DTR引脚(nUADTR)置低
[5]接收数据准备好(RDR)
0=接收缓冲寄存器中无有效数据
1=接收缓冲寄存器中有有效数据(若设置UCON[1:0],则产生中断或DMA请求)
[6]发送缓冲寄存器空(TBE)
0=发送保持寄存器中有有效数据
1=发送保持寄存器中无数据(若设置UCON[4:3],则产生中断或DMA请求)
[7]发送结束(TC)
0=正在发送数据
1=发送数据结束
UART发送缓冲寄存器(UART Transmit Buffer Registers,UTXBUF0、UTXBUF1):
UART发送缓冲寄存器UTXBUF0、UTXBUF1,存放待发送的8位数据。当把待发送的数据写入该寄存器时,UART的状态寄存器USTAT[6]自动清零。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
UTXBUF0 | 0xD00C | 写 | UART0发送缓冲寄存器 | 未定义 |
UTXBUF1 | 0xE00C | 写 | UART1发送缓冲寄存器 | 未定义 |
表6-2-5为UART发送缓冲寄存器描述
表6-2-5 UART发送缓冲寄存器描述
位 | 位名 | 功能描述 |
[7:0] | 发送数据 | 该位存放要发送的数据。 当向该寄存器写入数据时,状态寄存器中的发送缓冲寄存器空位USTAT[6]清‘0’,以防UTXBUF中的数据被覆盖。 任何时候向UTXBUF中写入新的数据,发送缓冲寄存器空位USTAT[6]都会被清‘0’。 |
[7:0]UART要发送的数据
UART接收缓冲寄存器(UART Receive Buffer Register,URXBUF0、URXBUF1):
UART接收缓冲寄存器URXBUF0、URXBUF1,存放接收到的8位串行数据。当UART接收完一个数据帧,UART的状态寄存器USTAT[5]置为1。当读取URXBUF时,USTAT[5]自动清零。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
URXBUF0 | 0xD010 | 读 | UART0接收缓冲寄存器 | 未定义 |
URXBUF1 | 0xE010 | 读 | UART1接收缓冲寄存器 | 未定义 |
表6-2-6为UART接收缓冲寄存器描述
表6-2-6 UART接收缓冲寄存器描述
位 | 位名 | 功能描述 |
[7:0] | 接收数据 | 该位存放接收到的数据。 当接收完一帧数据时,UART状态寄存器中的接收数据准备好位USTAT[5]被置为‘1’,以防从URXBUF中的读出的数据无效。 任何时候读取URXBUF,接收数据准备好位USTAT[5]都会自动清‘0’。 |
[7:0]UART接收到的数据
UART波特率除数因子寄存器(UART Baud Rate Divisor Registers,UBRDIV0、UBRDIV1):
UART波特率除数因子寄存器UBRDIV0、UBRDIV1的值,决定发送、接收的波特率。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
UBRDIV0 | 0xD014 | 读/写 | UART0波特率除数因子寄存器 | 0x0000,0000 |
UBRDIV1 | 0xE014 | 读/写 | UART1波特率除数因子寄存器 | 0x0000,0000 |
[3:0] 波特率除数因子值(CNT1)
xxx0=除1
xxx1=除16
[15:4]时间常数值(CNT0)
CNT0的计算公式如下:
CNT0=MCLK/(32×BR)-1
MCLK:系统的工作频率。
BR: 通讯的波特率。
UART波特率示例:
UART的波特率发生器的输入时钟可以为系统时钟,也可以从外部引入时钟信号。
若选用系统时钟为波特率发生器的输入时钟,当系统时钟为50MHz时,则最大的波特率时钟输出为MCLK2/16(= 1.5625MHz),其中MCLK2为系统时钟MCLK除以2。
UCLK引脚为UART0、UART1的外部时钟输入引脚。UART波特率发生器的输入时钟MCLK2或UCLK,由寄存器UCCON[6]选择。
下图为UART波特率发生器的结构图和典型的波特率。
关于UART工作原理和使用方法的更详细内容,可参考S3C4510B用户手册。
以下的示例完成通过串行口UART0发送数据的功能,接收功能的编程与之类似。该示例的通讯协议为:19200波特、8位数据、1位停止、无校验。
打开CodeWarrior for ARM Developer Suite(或ARM Project Manager),新建一个项目,并新建一个文件,名为Init.s,具体内容与第一个例子相同。
保存Init.s,并添加到新建的项目。
再新建一个文件,名为main.c,具体内容如下:
/*******************************************************************
* Institute of Automation, Chinese Academy of Sciences
* File Name: main.c
* Description:
* Author: JuGuang.Lee
* Date:
*************************************************************/
#define ULCON0 (*(volatile unsigned *)0x03FFD000) //UART channel0 line control register
#define UCON0 (*(volatile unsigned *)0x03FFD004) //UART channel0 control register
#define USTAT0 (*(volatile unsigned *)0x03FFD008) //UART channel0 status register
#define UTXBUF0 (*(volatile unsigned *)0x03FFD00c) //UART channel0 transimit holding register
#define URXBUF0 (*(volatile unsigned *)0x03FFD010) //UART channel0 recieve buffer register
#define UBRDIV0 (*(volatile unsigned *)0x03FFD014) //Baud rate divisor register0
#define ULCON1 (*(volatile unsigned *)0x03FFE000) //UART channel1 line control register
#define UCON1 (*(volatile unsigned *)0x03FFE004) //UART channel1 control register
#define USTAT1 (*(volatile unsigned *)0x03FFE008) //UART channel1 status register
#define UTXBUF1 (*(volatile unsigned *)0x03FFE00c) //UART channel1 transimit holding register
#define URXBUF1 (*(volatile unsigned *)0x03FFE010) //UART channel1 recieve buffer register
#define UBRDIV1 (*(volatile unsigned *)0x03FFE014) //Baud rate divisor register1
void InitUART(int Port,int Baudrate);
void PrintUART(int Port,char *s);
int Main()
{
InitUART(0,0x500); //19200bps CPU工作频率50MHz 0=COM1;1=COM2
for(;;){
PrintUART(0,"Communcation Testting! /r/n");
}
return(0);
}
void PrintUART(int Port,char *s)
{
if(Port==0)
for(;*s!='/0';s++)
{
for(;(!(USTAT0&0x40)););
UTXBUF0=*s;
}
if(Port==1)
for(;*s!='/0';s++)
{
for(;(!(USTAT1&0x40)););
UTXBUF1=*s;
}
}
void InitUART(int Port,int Baudrate)
{
if(Port==0)
{
ULCON0=0x03;
UCON0=0x09;
UBRDIV0=Baudrate;
}
if(Port==1)
{
ULCON1=0x03;
UCON1=0x09;
UBRDIV1=Baudrate;
}
}
保存main.c,并添加到新建的项目。此时可对该项目进行编译链接,生成可执行的映象文件,当可执行的映象文件运行时,会不停的向UART0发送字符串“Communcation Testting!”。
6.2.3 中断控制器工作原理与编程示例
中断是计算机的一种基本工作方式,几乎所有的CPU都支持中断,S3C4510B的支持多达21个中断源,中断请求可由内部功能模块和外部引脚信号产生。
ARM7TDMI核可以识别两种类型的中断:正常中断请求(Normal Interrupt Request,IRQ)和快速中断请求(Fast Interrupt Request,FIQ),因此,S3C4510B的所有中断都可以归类为IRQ或FIQ。S3C4510B的中断控制器对每一个中断源都有一个中断悬挂位(Interrupt Pending Bit)。
S3C4510B用如下四个寄存器控制中断的产生和对中断进行处理:
- 中断优先级寄存器(Interrupt Priority Register):每一个中断源的索引号写入一个预定义的中断优先级寄存器,以获得特定的优先级。中断优先级预定义为从0~20。
- 中断模式寄存器(Interrupt Mode Register):为每一个中断源定义中断模式,是IRQ还是FIQ。
- 中断悬挂寄存器(Interrupt Pending Register):指示中断请求处于悬挂状态(未处理)。如果中断悬挂位被置位,则中断悬挂状态会一直保存,直到CPU通过写‘1’到中断悬挂寄存器的相应位清除(注意是写‘1’清除,而不是写‘0’)。当中断悬挂位被置位时,无论中断屏蔽寄存器是否为‘0’,中断服务程序都开始执行。在中断服务程序中,必须通过向中断悬挂寄存器的相应位写‘1’来清除中断悬挂标志,以避免由于同一个中断悬挂位导致中断服务程序的反复执行。
- 中断屏蔽寄存器(Interrupt Mask Register):如果中断屏蔽位为‘1’
则对应的中断会被禁止,如果中断屏蔽位为‘0’,则对应的中断请求能正常响应。但如果全局中断屏蔽位(位21)为‘1’,则所有的中断都会被禁止。当有中断请求产生时,对应的中断悬挂位会被置为‘1’,在全局中断屏蔽位和对应的中断屏蔽位为‘0’时,中断请求就会被响应。
S3C4510B的中断源(Interrupt Sources)
S3C4510B可支持21个中断源,如表6-2-7所示:
表6-2-7 S3C4510B的中断源
索引号 | 中断源 |
[20] | IIC总线中断 |
[19] | 以太网控制器MAC接收中断 |
[18] | 以太网控制器MAC发送中断 |
[17] | 以太网控制器BDMA接收中断 |
[16] | 以太网控制器BDMA发送中断 |
[15] | HDLC通道B接收中断 |
[14] | HDLC通道B发送中断 |
[13] | HDLC通道A接收中断 |
[12] | HDLC通道A发送中断 |
[11] | 定时器1中断 |
[10] | 定时器0中断 |
[9] | GDMA通道1中断 |
[8] | GDMA通道0中断 |
[7] | UART1接收与错误中断 |
[6] | UART1发送中断 |
[5] | UART0接收与错误中断 |
[4] | UART0发送中断 |
[3] | 外部中断3 |
[2] | 外部中断2 |
[1] | 外部中断1 |
[0] | 外部中断0 |
中断控制器的特殊功能寄存器(Interrupt Controller Special Registers)
中断模式寄存器(Interrupt Mode Register)
中断模式寄存器INTMOD通过每一位的设置决定每一种中断是按快速中断(FIQ)还是按正常中断(IRQ)响应。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
INTMOD | 0x4000 | 读/写 | 中断模式寄存器 | 0x0000,0000 |
[20:0]中断模式位
INTMOD的21个位分别对应于表6-2-7中所描述的21个中断源,当中断模式位被置为‘1’时,ARM7TDMI核按FIQ方式处理对应的中断,否则按IRQ方式处理中断。21个中断源映射如下:
[20] IIC中断
[19] 以太网控制器MAC接收中断
[18] 以太网控制器MAC发送中断
[17] 以太网控制器BDMA接收中断
[16] 以太网控制器BDMA发送中断
[15] HDLC通道B接收中断
[14] HDLC通道B发送中断
[13] HDLC通道A接收中断
[12] HDLC通道A发送中断
[11] 定时器1中断
[10] 定时器0中断
[9] GDMA通道1中断
[8] GDMA通道0中断
[7] UART1接收与错误中断
[6] UART1发送中断
[5] UART0接收与错误中断
[4] UART0发送中断
[3] 外部中断3
[2] 外部中断2
[1] 外部中断1
[0] 外部中断0
中断悬挂寄存器(Interrupt Pending Register)
中断悬挂寄存器INTPND保持每一个中断源的中断悬挂位。该寄存器对应的中断悬挂位应在中断服务程序中首先清除,以避免由于同一个中断悬挂位导致中断服务程序的反复执行。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
INTPND | 0x4004 | 读/写 | 中断悬挂寄存器 | 0x0000,0000 |
[20:0]中断悬挂位
INTPND的21个位分别对应于表6-2-7中所描述的21个中断源,当中断请求产生时,对应的中断悬挂位被置为‘1’,在中断服务程序中应通过向对应位写入‘1’的方式清除中断悬挂位。21个中断源映射如下:
[20] IIC中断
[19] 以太网控制器MAC接收中断
[18] 以太网控制器MAC发送中断
[17] 以太网控制器BDMA接收中断
[16] 以太网控制器BDMA发送中断
[15] HDLC通道B接收中断
[14] HDLC通道B发送中断
[13] HDLC通道A接收中断
[12] HDLC通道A发送中断
[11] 定时器1中断
[10] 定时器0中断
[9] GDMA通道1中断
[8] GDMA通道0中断
[7] UART1接收与错误中断
[6] UART1发送中断
[5] UART0接收与错误中断
[4] UART0发送中断
[3] 外部中断3
[2] 外部中断2
[1] 外部中断1
[0] 外部中断0
中断屏蔽寄存器(Interrupt Mask Register)
中断屏蔽寄存器INTMSK保持每一个中断源的中断屏蔽位。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
INTMSK | 0x4008 | 读/写 | 中断屏蔽寄存器 | 0x003F,FFFF |
[20:0]中断屏蔽位
INTMSK的21个位分别对应于表6-2-7中所描述的21个中断源,当中断屏蔽位被置为‘1’时,对应的中断请求不能被CPU响应,当中断屏蔽位为‘0’时,中断请求会被响应。但如果全局屏蔽位(位21)为‘1’时,所有的中断请求都不能被响应(但只要中断请求产生,对应的中断悬挂位都会被设置),当全局屏蔽位被清除时,中断请求会得到响应。21个中断源映射如下:
[20] IIC中断
[19] 以太网控制器MAC接收中断
[18] 以太网控制器MAC发送中断
[17] 以太网控制器BDMA接收中断
[16] 以太网控制器BDMA发送中断
[15] HDLC通道B接收中断
[14] HDLC通道B发送中断
[13] HDLC通道A接收中断
[12] HDLC通道A发送中断
[11] 定时器1中断
[10] 定时器0中断
[9] GDMA通道1中断
[8] GDMA通道0中断
[7] UART1接收与错误中断
[6] UART1发送中断
[5] UART0接收与错误中断
[4] UART0发送中断
[3] 外部中断3
[2] 外部中断2
[1] 外部中断1
[0] 外部中断0
[21]全局中断屏蔽位
0 = 使能中断请求
1 = 禁止所有的中断请求
关于S3C4510B的中断控制器的工作原理和使用方法的更详细内容,可参考S3C4510B用户手册。
6.2.4 定时器工作原理与编程示例
S3C4510B提供两个32位的定时器T0和T1,均可工作在间隔模式(Interval Mode)或触发模式(Toggle Mode),对应的信号输出为TOUT0和TOUT1。
通过设置定时器控制寄存器TCON中的控制位可以禁止或使能T0和T1。无论何时当定时器计数溢出(减计数)时都会产生中断请求。
间隔模式(Interval Mode)
在这种模式下,当定时器计数溢出时产生一个脉冲输出,该脉冲输出产生定时中断请求,同时从定时器配置输出引脚(TOUTn)Pin196、Pin199输出。引脚的输出脉冲频率可按下式计算:
fOUT = fMCLK/定时器的数据值
触发模式(Toggle Mode)
在触发模式下,定时器的输出电平会持续到下一次的计数溢出时触发产生翻转。当发生定时器计数溢出时,会产生定时器中断请求,同时由配置引脚输出电平状态。
在该模式下,定时器输出引脚输出占空比为50%的时钟信号。引脚的输出脉冲频率可按下式计算:
fOUT = fMCLK/(2×定时器的数据值)
图6.2.3为定时器输出信号的时序。
图6.2.3 定时器输出信号时序
定时器的工作描述
图6.2.4为定时器的功能模块图。其工作描述如下:
图6.2.4 定时器的功能模块图
- 当使能计数器时,会向计数器的计数寄存器装入一个数据值,然后计数寄存器开始递减。
- 当定时器计数溢出时,会产生相应的中断请求,同时重新装入原来的数据值并开始递减。
- 在禁用定时器的情况下,可以向定时器的寄存器写入一个新的数据。
- 如果定时器在运行时暂停,原来的数据值不会被自动重新装入。
定时器模式寄存器(Timer Mode Register,TMOD)
定时器模式寄存器TMOD用于控制两个32位定时器的操作。TMOD寄存器的设置描述如下:
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
TMOD | 0x6000 | 读/写 | 定时器模式寄存器 | 0x0000,0000 |
[0]定时器0使能(TE0)
0 = 禁用定时器0
1 = 使能定时器0
[1]定时器0模式选择(TMD0)
0 = 间隔模式
1 = 触发模式
[2]定时器0初始化TOUT0的值(TCLR0)
0 = 在触发模式下初始化TOUT0为0
1 = 在触发模式下初始化TOUT0为1
[3]定时器1使能(TE1)
0 = 禁用定时器1
1 = 使能定时器1
[4]定时器1模式选择(TMD1)
0 = 间隔模式
1 = 触发模式
[5]定时器1初始化TOUT1的值(TCLR1)
0 = 在触发模式下初始化TOUT1为0
1 = 在触发模式下初始化TOUT1为1
定时器数据寄存器(Timer Data Registers,TDATA0,TDATA1)
定时器数据寄存器TDATA0和TDATA1的值决定每一个定时器的计数溢出时间的长短。该时间的计算公式为:(定时器数据+1)个时钟周期。
TDATA寄存器描述如下:
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
TDATA0 | 0x6004 | 读/写 | 定时器0数据寄存器 | 0x0000,0000 |
TDATA1 | 0x6008 | 读/写 | 定时器1数据寄存器 | 0x0000,0000 |
[31:0]定时器0或定时器1 的数据值
定时器计数寄存器(Timer Count Register)
定时器计数寄存器TCNT0和TCNT1保存定时器0或定时器1在正常工作情况下的当前计数值。
TCNT寄存器描述如下:
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
TCNT0 | 0x600C | 读/写 | 定时器0计数寄存器 | 0xFFFF,FFFF |
TCNT1 | 0x6010 | 读/写 | 定时器1计数寄存器 | 0xFFFF,FFFF |
[31:0]定时器0或定时器1 的计数值
关于S3C4510B定时器的工作原理和使用方法的更详细内容,可参考S3C4510B用户手册。
以下的示例显示定时中断服务程序的设计方法,其他中断服务的编程与之类似。
打开CodeWarrior for ARM Developer Suite(或ARM Project Manager),新建一个项目,并新建一个文件,名为Init.s,具体内容如下:
;************************************************************
; Institute of Automation, Chinese Academy of Sciences
;File Name: Init.s
;Description: Timer interrupt test.
;Author: JuGuang,Lee
;Date:
;**************************************************************
IOPMOD EQU 0x3FF5000 ;I/O口模式寄存器
IOPDATA EQU 0x3FF5008 ;I/O口数据寄存器
TMOD EQU 0x3FF6000 ;定时器模式寄存器
TDATA0 EQU 0x3FF6004 ;定时器数据寄存器
INTMOD EQU 0x3FF4000 ;中断模式寄存器
INTPND EQU 0x3FF4004 ;中断悬挂寄存器
INTMASK EQU 0x3FF4008 ;中断屏蔽寄存器
AREA Init,CODE,READONLY
ENTRY
B Reset_Handler ;复位异常向量,跳转到程序开始位置。
B . ;未定义指令异常,跳转到当前位置。
B . ;SWI异常,跳转到当前位置。
B . ;指令预取中止异常,跳转到当前位置。
B . ;数据访问中止异常,跳转到当前位置。
NOP
B IRQ_Handler ;IRQ异常,跳转到响应中断服务程序。
B . ;FIQ异常,跳转到当前位置。
Reset_Handler
;*********************************
;LED Display
;*********************************
LDR R1,=IOPMOD
LDR R0,=&ff
STR R0,[R1]
LDR R1,=IOPDATA
LDR R0,=&03
STR R0,[R1]
EOR R0,R0,R0
LEDDELAY
ADD R0,R0,#1
CMP R0,#&180000
BNE LEDDELAY
LDR R1,=IOPDATA
LDR R0,=&0
STR R0,[R1]
;***************************************
;User Stack
;***************************************
LDR R0, =0x3FF0000
LDR R1, =0xE7FFFF80 ;配置SYSCFG,片内4K Cache,4K SRAM
STR R1, [R0]
LDR SP, =0x3FE1000 ;SP指向4K SRAM的尾地址,堆栈向下生成
;***************************************
;Interrupt Special Registers
;***************************************
LDR R1,=INTMOD ;设置中断模式寄存器
LDR R0,=&0
STR R0,[R1]
LDR R1,=INTMSK ;设置中断屏蔽寄存器,只允许定时器0中断
LDR R0,=&1FFbFF
STR R0,[R1]
;**************************************
;Timer0 Special Registers
;**************************************
LDR R1,=TDATA0 ;定时器0的数据寄存器装入初始化值
LDR R0,=&3FFFFFF
STR R0,[R1]
LDR R1,=TMOD ;使能定时器0
LDR R0,=&01
STR R0,[R1]
B . ;循环等待中断发生
;*************************************************
;Timer0 Interrupt Service Routine
;*************************************************
IRQ_Handler
STMFD SP!,{R0-R6,LR} ;保护现场
LDR R1,=INTPND ;清INTPND中的对应位
LDR R0,=&400
STR R0,[R1]
LDR R0,=IOPDATA ;读IOPDATA的值加一并送回
LDR R1,[R0]
ADD R1,R1,#1
STR R1,[R0]
LDMFD SP!,{R0-R6,LR} ;恢复现场,中断返回
SUBS PC,LR,#4
END
保存Init.s,并添加到新建的项目。此时可对该项目进行编译链接,生成可执行的映象文件。由于异常向量地址是固定不变的,注意在连接该文件时应保证载入地址为0x0,否则程序不能正常运行。
当可执行的映象文件运行时,会按程序中定义的时间间隔产生定时器中断,通过外部的LED显示器显示中断服务程序的执行。
6.2.5 GDMA工作原理与编程示例
DMA用于在模块之间进行高速的数据传输,在进行大量数据传输时经常使用,S3C4510B内建两通道的通用DMA控制器(General DMA Controller,GDMA)。在没有CPU的干预下,两通道的GDMA可完成如下的数据传输:
- 存储器到存储器的双向数据传输。
- UART到存储器的双向数据传输。
片内的GDMA控制器可由软件请求或外部的DMA请求(nXDREQ)启动。当一次DMA操作完成以后,可由软件再次启动。
S3C4510B的DMA控制器能自动增减源地址与目标地址,同时能以8位、16位或32位的方式传送数据。
图6.2.5为GDMA控制器的功能模块图。
图6.2.5 GDMA控制器的功能模块图
GDMA特殊功能寄存器(GDMA Special Registers)
表6-2-8为GDAM特殊功能寄存器概述。
表6-2-8 GDAM特殊功能寄存器概述
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
GDMACON0 | 0xB000 | 读/写 | GDMA通道0控制寄存器 | 0x0000,0000 |
GDMACON1 | 0xC000 | 读/写 | GDMA通道1控制寄存器 | 0x0000,0000 |
GDMASRC0 | 0xB004 | 读/写 | GDMA通道0源地址寄存器 | 未定义 |
GDMASRC1 | 0xC004 | 读/写 | GDMA通道1源地址寄存器 | 未定义 |
GDMADST0 | 0xB008 | 读/写 | GDMA通道0目的地址寄存器 | 未定义 |
GDMADST1 | 0xC008 | 读/写 | GDMA通道1目的地址寄存器 | 未定义 |
GDMACNT0 | 0xB00C | 读/写 | GDMA通道0传输计数寄存器 | 未定义 |
GDMACNT1 | 0xC00C | 读/写 | GDMA通道1传输计数寄存器 | 未定义 |
GDMA控制寄存器(GDMA Control Registers)
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
GDMACON0 | 0xB000 | 读/写 | GDMA通道0控制寄存器 | 0x0000,0000 |
GDMACON1 | 0xC000 | 读/写 | GDMA通道1控制寄存器 | 0x0000,0000 |
GDMA控制寄存器描述如表6-2-9:
表6-2-9 GDMA控制寄存器描述
位 | 位名 | 功能描述 |
[0] | 运行使能/禁止 | 该位置‘1’启动DMA操作。要停止DMA操作,该位必须清‘0’。用户可通过对GDMA运行位控制地址(GDMACON偏移地址+0x20)的操作控制该位。当使用运行位控制地址时,其他的GDMA控制寄存器不受影响。 |
[1] | 忙状态 | 当GDMA操作启动时,该状态位(只读)自动置为‘1’, 当GDMA空闲时,该位为‘0’。 |
[3:2] | GDMA模式选择 | GDMA支持4种传输模式: 1) 软件请求模式(存储器到存储器), 2) 外部DMA请求(nXDREQ) 3) UART0块传输 4) UART1块传输 |
[4] | 目的地址 增减方式 | 该位控制在DMA操作中目的地址是递增(‘0’)还是递减(‘1’)。 |
[5] | 源地址 增减方式 | 该位控制在DMA操作中源地址是递增(‘0’)还是递减(‘1’)。 |
[6] | 目的地址固定控制 | 该位决定在DMA操作中目的地址是否固定。使用该特性可以完成从多个源地址向一个目的地址的数据传输。 |
[7] | 源地址固定控制 | 该位决定在DMA操作中源地址是否固定。使用该特性可以完成从一个源地址向多个目的地址的数据传输。 |
[8] | 停止中断使能 | 可以通过设置或清除运行使能位来启动或停止DMA操作。如果在DMA启动时将该位置‘1’,则当DMA操作停止时会产生停止中断,否则不产生。 |
[9] | 4-数据猝发使能 | 当该位置‘1’时,GDMA控制器工作于4-数据猝发模式。在该模式下,一次可完成从4个连续的源地址数据的读取,然后传送到4个连续的目的地址,此时应注意传输计数寄存器,因为它的值只会递增或递减一次。 |
[10] | 外设传输方向 | 当模式位[3:2]=‘10’(UART0与存储器之间的数据传输)或‘11’(UART1与存储器之间的数据传输)时,该位规定数据的传输方向。 当该位为‘1’,由存储器到外设。 当该位为‘0’,由外设到存储器。 |
[11] | 单/块模式 | 该位决定外部DMA请求DMA操作的次数。 在单模式下(该位为‘0’),每一次DMA操作都需要外部的DMA请求。 在块模式下(该位为‘1’),只需要一次外部的DMA请求即可完成整个DMA操作,直到传输计数值为0。 注意不能同时使用块模式和查询模式,也不能同时使用单模式和连续模式。 |
[13:12] | 传输宽度 | 该两位决定传输数据的宽度(8位、16位或32位)。 如果选择字节传输,每次传输完成源地址与目标地址递增或递减1。 如果选择半字传输,每次传输完成源地址与目标地址递增或递减2。 如果选择字传输,每次传输完成源地址与目标地址递增或递减4。 |
[14] | 连续模式 | 该位可使DMA控制器占用系统总线直到DMA传输计数器的值为零。必须小心操作该位,使DMA传输操作不要超过一个可以接受的时间间隔(例如,不要超过DRAM的刷新周期)。 可以同时使用连续模式和软件请求模式。 |
[15] | 查询模式 | 使用该模式可以提高外部DMA操作的速度。当该位为‘1’时,在外部DMA请求信号(nXDREQ)有效期间都进行DMA数据传输操作,信号的有效时间决定传输的数据量。当nXDREQ信号有效且DMA控制器取得控制总线权,会一直控制系统总线直到nXDREQ信号变为无效。因此,必须小心控制nXDREQ信号的有效时间,不要超过一个可以接受的时间间隔(例如,不要超过DRAM的刷新周期)。 注意在查询模式下必须清除单/块控制位[11]和连续模式位[14]。 |
注意:要确保DMA操作可靠,必须小心的单独配置GDMA控制寄存器的每一位。
[0]运行使能(RE)
0 = 禁用DMA操作
1 = 使能DMA操作
[1]忙状态(BS)
0 = DMA空闲
1 = DMA工作
[3:2]模式选择(MODE)
00 = 软件请求模式(存储器到存储器)。
01 = 外部请求模式(用于外设)。
10 = UART0块模式。
11 = UART1块模式。
[4]目的地址增减方向(DA)
0 = 目的地址递增
1 = 目的地址递减
[5]源地址增减方向(SA)
0 = 源地址递增
1 = 源地址递减
[6]目的地址固定控制(DF)
0 = 增/减目的地址
1 = 目的地址不改变(固定)
[7]源地址固定控制(SF)
0 = 增/减源地址
1 = 源地址不改变(固定)
[8]停止中断使能(SI)
0 = 当DMA操作停止时不产生停止中断请求
1 = 当DMA操作停止时产生停止中断请求
[9]4-数据猝发使能(FB)
0 = 禁止4-数据猝发模式
1 = 使能4-数据猝发模式
[10]数据传输方向(仅用于UART0/1)(TD)
0 = UART0/1到存储器
1 = 存储器到UART0/1
[11]单/块模式(SB)
0 = 一次nXDREQ初始化一次DMA操作
1 = 一次nXDREQ初始化整个DMA操作
[13:12]传输宽度(TW)
00 = 字节(8位) 01 = 半字(16位)
10 = 字(32位) 11 = 未使用
[14]连续模式(CN)
0 = 正常操作模式
1 = 占用总线直到整个DMA操作完成
[15]查询模式(DM)
0 = 正常外部DMA模式
1 = 查询模式
GDMA源/目的地址寄存器(GDMA Source/Destination Registers)
GDMA源/目的地址寄存器为DMA通道0/1保留26位的源/目的地址。根据GDMA控制寄存器的设置,在DMA操作中源地址和目的地址可以保持不变,也可以递增或递减。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
GDMASRC0 | 0xB004 | 读/写 | GDMA通道0源地址寄存器 | 未定义 |
GDMASRC1 | 0xC004 | 读/写 | GDMA通道1源地址寄存器 | 未定义 |
GDMADST0 | 0xB008 | 读/写 | GDMA通道0目的地址寄存器 | 未定义 |
GDMADST1 | 0xC008 | 读/写 | GDMA通道1目的地址寄存器 | 未定义 |
[25:0]源/目的地址
GDMA传输计数寄存器(GDMA Transfer Count Registers)
GDMA传输计数寄存器为DMA通道0/1保留在传输完成后的24位当前计数值。
在每一次DMA操作完成时计数值总是按1增减,无论GDMA传输数据的宽度或是处于4-数据猝发模式。
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
GDMASRC0 | 0xB004 | 读/写 | GDMA通道0源地址寄存器 | 未定义 |
GDMASRC1 | 0xC004 | 读/写 | GDMA通道1源地址寄存器 | 未定义 |
GDMADST0 | 0xB008 | 读/写 | GDMA通道0目的地址寄存器 | 未定义 |
GDMADST1 | 0xC008 | 读/写 | GDMA通道1目的地址寄存器 | 未定义 |
[23:0]传输计数值
GDMA功能描述
GDMA可以在请求者和目标之间直接进行数据传输,无需CPU的干预。请求者或目标是指存储器、UART和外设。外设可以通过nXDREQ信号请求GDMA服务。每一个DMA通道都可以通过向相应的寄存器写入数据来进行编程控制,这些寄存器保留有请求者地址、目标地址、传输的数据量以及其他的一些控制内容。UART、外部I/O或通过编程(只用于存储器到存储器)都可以请求DMA服务。UART部件与GDMA部件在片内已经相连。
当GDMA从nXDREQ引脚、UART或软件接收到服务请求时,就开始传输数据,当整个缓冲区的数据传输完毕时,GDMA就处于空闲状态,如果要进行再一次的数据传输,必须对GDMA重新编程,即使是对同一个缓冲区的数据进行重传。
GDMA的数据传输有三种模式:单模式、块模式和查询模式。
在单模式下,当4-数据猝发模式处于禁用状态时,每一次GDMA请求(可由外部或内部产生)只能传输一个字节数据、或一个半字数据、或一个字数据。当4-数据猝发模式处于使能状态时,每一次GDMA请求可完成4次数据传输。在单模式下,每一次的数据传输均需要DMA请求。
在块模式下,一次GDMA请求(可由外部或内部产生)会完成按寄存器设置的所有数据的传输,直到传输计数器的值为0。
而在查询模式下,只要检测到nXDREQ信号有效,就会持续进行数据的传输。
关于GDMA工作原理和使用方法的更详细内容,可参考S3C4510B用户手册。
以下的示例完成GDMA通道0的数据传输,采用软件方式启动DMA控制器。
打开CodeWarrior for ARM Developer Suite(或ARM Project Manager),新建一个项目,并新建一个文件,名为Init.s,具体内容如下:
;************************************************************
; Institute of Automation, Chinese Academy of Sciences
;File Name: Init.s
;Description: DMA test.
;Author: JuGuang,Lee
;Date:
;**************************************************************
SRC_ADD EQU 0x100000 ;源地址
DST_ADD EQU 0x200000 ;目的地址
COUNT EQU 0x100 ;传输数量量
IOPMOD EQU 0x3FF5000 ;I/O口模式寄存器
IOPDATA EQU 0x3FF5008 ;I/O口数据寄存器
GDMACON0 EQU 0x3FFB000 ;GDMA通道0控制寄存器
GDMASRC0 EQU 0x3FFB004 ;GDMA通道0源地址寄存器
GDMADST0 EQU 0x3FFB008 ;GDMA通道0目的地址寄存器
GDMACNT0 EQU 0x3FFB00C ;GDMA通道0传输计数寄存器
AREA Init,CODE,READONLY
ENTRY
;*********************************
;LED Display
;*********************************
LDR R1,=IOPMOD
LDR R0,=&ff
STR R0,[R1]
LDR R1,=IOPDATA
LDR R0,=&03
STR R0,[R1]
EOR R0,R0,R0
LEDDELAY
ADD R0,R0,#1
CMP R0,#&180000
BNE LEDDELAY
LDR R1,=IOPDATA
LDR R0,=&0
STR R0,[R1]
;***************************************
;User Stack
;***************************************
LDR R0, =0x3FF0000
LDR R1, =0xE7FFFF80 ;配置SYSCFG,片内4K Cache,4K SRAM
STR R1, [R0]
LDR SP, =0x3FE1000 ;SP指向4K SRAM的尾地址,堆栈向下生成
;**************************************
;Data Initialize
;**************************************
LDR R1,=SRC_ADD ;R1指向源地址,将连续的0x100个存储单元初始化
LDR R0,=0x0
LOOP
STR R0,[R1]
ADD R1,R1,#1
ADD R0,R0,#1
CMP R0,COUNT
BNE LOOP
;***************************************
; GDMA0 Controll Register
;***************************************
LDR R1,=GDMASRC0 ;设置GDMA的源地址
LDR R0,=SRC_ADD
STR R0,[R1]
LDR R1,=GDMADST0 ;设置GDMA的目的地址
LDR R0,=DST_ADD
STR R0,[R1]
LDR R1,=GDMACNT0 ;设置GDMA的传输计数器
LDR R0,=COUNT
STR R0,[R1]
LDR R1,=GDMACON0 ;设置GDMA的控制寄存器
LDR R0,=0x0801
STR R0,[R1]
B . ;循环等待DMA传输完毕
END
保存Init.s,并添加到新建的项目。此时可对该项目进行编译链接,生成可执行的映象文件。
当可执行的映象文件运行时。位于0x100000的数据块会以DMA方式传输到0x200000处。
6.2.6 IIC总线控制器工作原理
S3C4510B片内的IIC总线控制器具有如下重要特性:
- 仅需要两根传输线。一根为串行数据线(Serial Data Line,SDA),另一根为串行时钟线(Serial Clock Line,SCL)。当IIC总线处于空闲状态时,两根传输线均为高电平。
- 连接到总线上的每一个设备都可以通过一个主控器使用唯一的地址进行软件寻址。总线主控器既可以是一个主发送器,也可以是一个主接收器。但S3C4510B的IIC总线控制器仅支持单主控器模式。
- 支持8位、双向,串行数据传输。
- 连接到IIC总线的器件数目仅受到最大总线电容(400PF)的限制。
图6.2.6为S3C4510B IIC总线控制器的功能模块。
图6.2.6 S3C4510B IIC总线控制器的功能模块图
功能描述(Functional Description)
S3C4510B的IIC总线控制器为一个串行IIC总线主控器。可通过设置预分频寄存器(Prescaler Register,IICPSR)对串行时钟频率进行编程。串行时钟频率可由下式计算:
MCLK/(16×(预分频寄存器的值+1)+3)
可通过对控制状态寄存器(IICCON)的位[5:4]写入“01”发送启动码初始化串行IIC总线,然后总线控制器发送7位的从设备地址并通过移位缓冲寄存器发送读/写控制位,接收器则在主控器的SCL脉冲期间通过将SDA线从高电平下拉到低电平作为应答信号。
写数据的操作:先设置控制状态寄存器的BF位,然后写入数据到移位缓冲寄存器。移位缓冲寄存器无论是被读还是写,BF位均会自动清零。若要进行连续的读/写操作,必须设置控制状态寄存器的ACK位。
读数据的操作:在设置控制状态寄存器的BF位以后,可以进行读数据的操作,当读/写完最后一个字节时,可对ACK位进行复位通知发送器/接收器读数据操作的结束。
在读/写操作完成以后,可通过设置IICCON[5:4]=“10”生成结束码。
IIC总线概念(IIC-BUS Concepts)
基本操作(Basic Operation):IIC总线通过两根传输线,一根串行数据线SDL,一根串行时钟线SCL,在连接到总线上的IC器件之间传递信息,每一个IC器件通过唯一的地址进行识别,根据其特性,可作为发送器或接收器工作。
IIC总线是一种多主控器总线,有多个IC器件具有控制总线的能力。
IIC总线的数据传输过程描述如下:
第一种情况,一个主IC器件要传送数据到其他的从IC器件,可分为如下三个步骤:
1、 主IC器件寻址从IC器件。
2、 主IC器件发送数据到从IC器件(此时,主器件为发送器,从器件为接收器)。
3、 主IC器件终止数据的传输。
第二种情况,一个主IC器件要从其他的从IC器件获取数据,可分为如下三个步骤:
1、 主IC器件寻址从IC器件。
2、 主IC器件从从IC器件接收数据(此时,主器件为接收器,从器件为发送器)。
3、主IC器件终止数据的传输。
即使是在第二种情况,也由主IC器件产生时序信号并终止数据的传输。
通用特性(General Characteristics):SDL和SCL均为双向传输线,各通过一个上拉电阻连接到电源正端,当IIC总线空闲时,SDL和SCL传输线均为高电平,连接在总线上的IIC接口在输出阶段通过漏极开路(Open-drain)或集电极开路(Open-collector)的方式完成线与(Wired-AND)功能。IIC总线的数据传输速率最高可达到100Kb/S。可连接到总线上的IC器件数目仅受到总线电容的限制(400PF)。
位传输(Bit Transfers):由于连接到IIC总线上的器件各不相同(如有CMOS器件,NMOS器件,TTL器件等),逻辑0或逻辑1的电平会根据电源电压的高低发生变化,因此,每传输一个位就产生一个时钟脉冲。
数据有效性(Data Validity):在时钟信号的高电平期间,SDA传输线上的电平必须稳定,只有在SCL传输线上的时钟信号为低电平时,数据线上的高低电平才允许发生变化。
开始与停止条件(Start and Stop Conditions):开始和停止条件总是由主器件产生。在开始条件产生后,总线被认为处于忙状态,在完成数据传输产生停止条件后,总线被认为处于空闲状态。
- 开始条件:当SCL为高电平时,SDA产生由高电平到低电平的跳变。
- 停止条件:当SCL为高电平时,SDA产生由低电平到高电平的跳变。
图6.2.7为开始与停止条件:
图6.2.7 开始与停止条件
数据传输操作(Data Transfer Operations)
数据字节格式(Data Byte Format):每一个写到SDA传输线上的数据字节必须为8位的长度,每一次传输的字节数没有限制,每传输一个字节必须跟一个应答位ACK(如图6.2.7),传输字节时最高位在前(MSB-first)。
如果接收器因为执行其他功能(如中断服务)而不能接收其他剩余的数据字节时,接收器就保持时钟线SCL为低电平强制发送器进入等待状态,只有当接收器准备接收其他字节并释放SCL传输线时,数据传输才会继续进行。
应答过程(Acknowledge Procedure):在数据的传输过程中必须带有应答信号,与应答信号相关的时钟脉冲必须由总线主控器产生。在应答时钟脉冲期间,发送器释放SDA传输线(为高电平),但此时接收器必须下拉SDA传输线,以便在时钟脉冲的高电平期间SDA能够保持稳定的低电平。
通常,被寻址的接收器在接收到每一个字节后必须产生一个应答信号,当从接收器不能产生应答信号时,必须释放数据线,然后由主控器产生停止条件中止数据传输。
数据传输格式(Data Transfer Format):图6.2.8显示传输数据的格式。当产生开始条件后,首先发送7位的从器件地址,第八位为数据方向位(R/W),“0”表示发送数据(写),“1”表示请求数据(读)。
图6.2.8 数据传输的格式
数据传输一般总是在主控器产生停止条件后中止。但当主控器还要利用总线进行通讯时,主控器可以在不产生前一个停止条件的情况下,再产生开始条件并寻址另一个从器件,该特性可用于支持不同数据传输读/写格式的联合使用。
IIC总线寻址(IIC-Bus Addressing):IIC总线的寻址过程为在开始条件后发送的第一个字节,该字节地址决定主控器选择哪一个从器件。通常,第一个字节总是紧跟在开始过程之后。
还可以通过“广播”寻址方式同时寻址所有的IC器件,当使用广播寻址时,理论上所有的IC器件都应该返回应答信号,但器件也可以忽略这个这个地址。广播寻址的第二个字节决定其后的操作。
第一个数据字节的位定义(Definition of Bits in the First Data Byte
第一个数据字节的前7位为从器件地址,第8位为方向位,决定数据的传输方向(读/写)。
当地址字节发出以后,总线上的每一个IC器件将该地址与自己的地址进行比较,若地址匹配,则这个IC器件就认为自身被主控器寻址为一个从发送器或从接收器。
广播寻址(General Call Address):广播寻址方式可用于寻址连接在IIC总线上的每一个IC器件,但当某个IC器件不需要进行数据传输时,将忽略广播寻址而不作任何应答。
如果某个IC器件需要获取数据,将发出应答信号并作为一个从接收器。
开始字节(Start Byte):在每一次的数据传输之前都有一个开始过程,描述如下:
- 一个开始条件,S
- 一个开始字节,“00000001”
- 一个应答时钟脉冲
- 一个重复开始条件,Sr
当需要访问总线的主控器在发送完开始条件S后,接着发送开始字节(“00000001”),总线上其余的IC器件以较低的采样率对SDA传输线进行采样,一直到检测到开始字节中七个零中的某一个。当检测到SDA传输线上的低电平时,IC器件就切换到较高的采样率检测重复开始条件Sr用于同步,接收器在检测到重复开始条件Sr后复位,忽略该开始字节。
在开始字节发送完毕之后产生一个应答时钟脉冲。
IIC总线特殊功能寄存器(IIC Bus Special Registers)
IIC总线控制器由三个特殊功能寄存器:一个控制状态寄存器(IICON),一个预分频寄存器(IICPS)和一个移位缓冲寄存器(IICBUF)。
控制状态寄存器(Control Status Register,IICON):
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
IICCON | 0xF000 | 读/写 | 控制状态寄存器 | 0x0000,0000 |
IIC总线的控制状态寄存器描述如表6-2-10。
表6-2-10 IICCON寄存器描述
位 | 位名 | 功能描述 |
[0] | 缓冲标志(BF) | 在发送模式下缓冲区空时,或在接收模式下缓冲区满时,BF置位。 通过对该位写“0”可以清除缓冲区。 IICBUF寄存器无论是被读还是写,BF位都自动清零。 如果将该位置为“1”,IIC总线停止工作,要激活IIC总线,应将该位清零。 |
[1] | 中断使能(IEN) | 该位置“1”,使能IIC总线中断 |
[2] | 最后接收位(LRB) | LRB位为只读。该位保持IIC总线上最后接收到的位。通常该位为从器件的应答信号。要检测从器件的应答信号,可以测试LRB位。 |
[3] | 应答使能(ACK) | ACK位通常置为“1”,以便IIC总线控制器在每一个字节后自动发送一个应答信号。 当IIC总线控制器工作在接收器模式,且不需要从从发送器接收数据时,该位必须清零。 |
[5:4] | COND1,COND0 | 该两位控制开始条件、停止条件和重复开始条件的生成: “00”= 无影响 “01”= 开始 “10”= 停止 “11”= 重复开始 |
[6] | 总线忙(BUSY) | 该位为只读,用以指示IIC总线是否被使用。为“1”表示总线忙。该位由开始条件和停止条件置位或清零。 |
[7] | Reset | 如果向该位写“1”,IIC总线控制器复位为初始化状态。 |
[31:8] | 保留 | 无 |
[0]缓冲标志(BF)
0 = 当IICBUF寄存器被读或写时,该位自动清零。可通过写“0”手动清除BF。
1 = 在发送模式下缓冲区空时,或在接收模式下缓冲区满时,BF自动置位。
[1]中断使能(IEN)
0 = 禁止
1 = 使能;BF位为“1”时产生中断。
[2] 最后接收位(LRB)
使用该只读状态位可以检测接收器(从器件)的应答信号,或当写“11”到IICCON[5:4]重复开始时监控SDA操作。
0 = 最近SDA为低电平(接收到ACK)。
1 = 最近SDA为高电平(未接收到ACK)。
[3]应答使能(ACK)
在接收模式下控制产生ACK信号。
0 = 在第9个SCL脉冲时不产生ACK信号。
1 = 在第9个SCL脉冲时产生ACK信号。。
[5:4]COND1和COND0
用于总线控制信号的生成,如开始或停止信号。
00 = 无影响。
01 = 产生开始条件。
10 = 产生停止条件。
11 = SCL被释放为高电平产生重复开始条件。
[6]总线忙(BUSY)
0 = 总线当前未被使用(空闲)。
1 = 总线正被使用(忙)。
[7]Reset
0 = 正常工作状态。
1 = 复位IIC总线控制器。
[31:8]系统保留
移位缓冲寄存器(Shift Buffer Register,IICBUF):
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
IICBUF | 0xF004 | 读/写 | 移位缓冲寄存器 | 未定义 |
IIC总线的移位缓冲寄存器描述如表6-2-11。
表6-2-11 IICBUF寄存器描述
位 | 位名 | 功能描述 |
[7:0] | 数据 | 该数据区域用作串行移位寄存器和IIC总线的读缓冲接口。所有对总线的读/写操作均要通过该寄存器。IICBUF寄存器由移位寄存器和数据缓冲两部分构成。 发送数据时,8位的并行数据首先写入移位寄存器。 接收数据时,从数据缓冲区读取。 |
[31:8] | 保留 | 无 |
预分频寄存器(Prescaler Register,IICPS):
寄存器 | 偏移地址 | 操作 | 功能描述 | 复位值 |
IICPS | 0xF008 | 读/写 | 预分频寄存器 | 0x0000,0000 |
IIC总线的预分频寄存器描述如表6-2-12。
表6-2-12 IICPS寄存器描述
位 | 位名 | 功能描述 |
[15:0] | 预分频值 | 该预分频值用于产生IIC总线的串行时钟。系统时钟除以(16×(预分频值+1)+3)作为IIC总线的串行时钟。 若预分频值为0,则将系统时钟除以19作为IIC总线的串行时钟。 |
[31:16] | 保留 | 无 |