本章主要以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 |
写 | |