M0系列ARM芯片的启动程序分解

M0系列ARM芯片的启动程序分解
M0系列ARM芯片的启动程序分解

周立功NXP LPC21xx/22xx 系列ARM 芯片的启动程序分解

作者:钟常慰

关于LPC2200 启动程序分散加载描述文件的叙述

在ADS LPC2200 的启动模板中有一个scf 文件夹,其中有mem_a.scf、mem_b.scf、mem_c.scf 这3 个文件,这3 个文件是ADS 的

分散加载机制,其目的是将代码段和数据段分别定位到指定地址上。可以在Arm Linker 中选择加载路径。分散装载技术概述:

分散装载技术可以把用户的应用程序分割成多个RO(只读)运行域和RW(可读写)运行域(一个存储区域块),并且给它们制定不同的

地址。一个嵌入式系统中,Flash、16 位RAM、32 位RAM 都可以存在于系统中,所以,将不同功能的代码定位在特定的位置会大大地提

高系统的运行效率。下面是最为常用的2 种情况:

1、32 位的RAM 运行速度很快,因此就把中断服务程序作为一个单独的运行域,放在32 位的RAM,使它的响应时间达到最快。

2、程序在RAM 中运行,其效率要远远高于在ROM 中运行,所以将启动代码(Boot loader)以外的所有代码都复制在RAM 中运行,

可以提高运行效率。

分散装载技术主要完成了2 个基本的功能:

如何分散。就是如何将输入段组成输出段和域。

如何装载。就是确定装载域和运行域在存储空间里的地址是多少。

域可以分为装载域和运行域

装载域描述运行前输出段和域在ROM/RAM 里的分布状态,运行域描述了运行时输出段和域在ROM/RAM 里的分布状态。大多数情况下,

映像文件在执行前把它装载到ROM 里,而当运行时,域里的有些输出段(比如RW 类型的输出段)必须复制到RAM 里,程序才能正常运行,

所以,在装载和运行时,RW 类的输出段处在不同的位置(地址空间)。

Scatterfile 分散加载文件:

在scatterfile 中可以为每一个代码或数据区在装载和执行时指定不同的存储区域地址,Scatlertoading 的存储区块可以分成二种类

型:

装载区:当系统启动或加载时应用程序的存放区。

执行区:系统启动后,应用程序进行执行和数据访问的存储器区域,系统在实时运行时可以有一个或多个执行块。

映像中所有的代码和数据都有一个装载地址和运行地址(二者可能相同也可能不同,视具体情况而定)。scatter 文件语法

scatter 文件是一个简单的文本文件,包含一些简单的语法。

My Region 0x0000 0x1000 ;我的名字My Region 起始地址0x0000 属性0x1000

{

;the context of region 这个域的范围

}

标题

每个块由一个头标题开始定义,头中至少包含块的名字和起始地址,如(0x0000),另外还有最大长度等其他一些属性选项(注:这些属性

是可选的,如0x1000)。

内容

块定义的内容包括在紧接的一对花括号内,依赖于具体的系统情况。

1、一个加载块必须至少含有一个执行块;实践中通常有多个执行块。

2、一个执行块必须至少含有一个代码或数据段;这些通常来自源文件或库函数等的目标文件;

通配符号*可以匹配指定属性项中所有没有在文件中定义的余下部分。

有以下几种属性:

RO:只读的代码段和常量

RW:可以读写的全局变量和静态变量

ZI:RW 段中要被初始化为零的变量。

Scatterfile 中的定义要按照系统冲定向后的存储器分布情况进行,在引导程序完成初始化任务后,应该把主程序转移到RAM 中运行以

加快系统的运行速度。

2008.11.25

zhongcw1002@https://www.360docs.net/doc/2c8839940.html,

分(消)散

LPC2200 的分散加载文件分析:

ROM_LOAD 0x80000000 (1)

{

ROM_EXEC 0x80000000 (2)

{ Startup.o (vectors, +First) (3)

* (+RO) } (4)

IRAM 0x40000000 (5)

{ Startup.o (MyStacks) } (6)

STACKS_BOTTOM +0 UNINIT (7)

{ Startup.o (StackBottom) } (8)

STACKS 0x40004000 UNINIT (9)

{ Startup.o (Stacks) } (10)

ERAM 0x80040000 (11)

{ * (+RW,+ZI) } (12)

HEAP +0 UNINIT (13)

{ Startup.o (Heap) } (14)

HEAP_BOTTOM 0x80080000 UNINIT (15)

{ Startup.o (HeapTop) } (16)

}

FLASH_LOAD 0x81000000 0x1000 (17)

{ FLASH_EXEC 0x81000000 (18)

{ main.o (+RO) } (19)

}

(1) 加载时域描述,名称位ROM_LODA 它的地址为0x80000000;

0x80000000 为LPC 片外RAM 地址,即将以下的加载的段和域都在RAM 中。

(2) 第一个运行时域描述。

ROM_EXEC 描述了执行区的地址,放在第一块定义,其起始地址、空间大小域加载区起始地址、空间大小要一样。

(2)-(4)从起始地址开始放置向量表。Startup.o 是Startup.s 的目标文件。Vectors 为中断向量表。模块Startup 位于该加载域的开

头(+First),vectors 作为入口点,包含全部的RO 代码。ARM 在芯片复位之后,系统进入管理模式、ARM 状态,PC(R15)寄存器的值

为0x00000000,所以必须保证用户的向量表代码定位在0x00000000 处,或者映射到0x00000000 处(例如向量表代码在0x80000000

处,通过存储器映射,访问0x0000000 就是访问(0x80000000)。

(5)-(6)第二运行时域描述。将MyStacks 堆栈段装载到片内静态RAM 中。

(7)-(8)将栈底放入堆栈的后面(+0)不进行初始化(UNINIT), 栈底为Startup 中的StackBottom。

(9)-(10) 将栈放入地址为0x40004000 并且不进行初始化(UNINIT)。

(11)-(12 将所有的RW 和ZI 段放入外部存储器中以0x80040000 为开头的地址中。并且全部清零(+ZI)外部RAM 中指定的区域。

(13)-(14)在RW ZI 段后放入堆底(Startup.o(Heap))并且不进行初始化。

(15)-(16)将堆定放入外部RAM 中(0x80080000)。

(17)-(19)自己添加的加载代码,把main.c 的目标文件加载到片外Flash 中并且占用了0x1000 的大小。2008.11.25

加载时域描述

第一个运行时域描述

放置向量表

将MyStacks 堆栈段装载到片内静态RAM 中。

将栈底放入堆栈的后面(+0)不进行初始化(UNINIT),

栈底为Startup 中的StackBottom。

将栈放入地址为0x40004000 并且不进行初始化(UNINIT)。

将所有的RW 和ZI 段放入外部存储器中以0x80040000

为开头的地址中。并且全部清零(+ZI)外部RAM 中指定的区域。

在RW ZI 段后放入堆底(Startup.o(Heap))

并且不进行初始化。

自己添加的加载代码,把main.c 的目标文件加载到

片外Flash 中并且占用了0x1000 的大小。

将堆定放入外部RAM 中(0x80080000)。

;******************************************************************************************* *************/

;** File Name: men_a.scf

ROM_LOAD 0x80000000 // ROM加载

{

ROM_EXEC 0x80000000 // ROM执行(起始地址)程序0x80000000 外部存储区

{ Startup.o (vectors, +First) // Startup.o文件(向量,程序入口)

* (+RO)} // 只读

IRAM 0x40000000 // Indexed Random Access Method,索引随机存取方法0x40000000

{ Startup.o (MyStacks)} // Startup(堆栈)装载到片内SRAM中

STACKS_BOTTOM +0 UNINIT // 堆栈栈底,将栈底放入堆栈的后面(+0),不初始化

{ Startup.o (StackBottom)} // 将栈放入地址为0x40004000 并且不进行初始化(UNINIT)

STACKS 0x40004000 UNINIT // 堆栈0x40004000 16kb的SRAM片内存储区

{ Startup.o (Stacks)} // Startup.o文件(堆栈)

ERAM 0x81000000 // 将所有的RW和ZI段放入外部存储器中0x81000000为开头的地址中

{ * (+RW,+ZI)} // 并且全部清零(+ZI)外部RAM中指定的区域读写(无输入ZI)

HEAP +0 UNINIT // 在RW ZI段后放入堆底(Startup.o(Heap))并且不进行初始化

{ Startup.o (Heap)} // Startup.o文件(堆栈)

HEAP_BOTTOM 0x81080000 UNINIT // 将堆定放入外部RAM中0x81080000

{ Startup.o (HeapTop)} // Startup.o文件(堆栈栈顶)

}

;******************************************************************************************* *************/

;** File Name: men_b.scf

ROM_LOAD 0x80000000

{

ROM_EXEC 0x80000000

{ Startup.o (vectors, +First)

* (+RO)}

IRAM 0x40000000

{ Startup.o (MyStacks)}

STACKS_BOTTOM +0 UNINIT

{ Startup.o (StackBottom)}

STACKS 0x40004000 UNINIT

{ Startup.o (Stacks)}

ERAM 0x80040000

{ * (+RW,+ZI)}

HEAP +0 UNINIT

{ Startup.o (Heap)}

HEAP_BOTTOM 0x80080000 UNINIT

{ Startup.o (HeapTop)}

}

;******************************************************************************************* *************/

;** File Name: men_c.scf

ROM_LOAD 0x0

{

ROM_EXEC 0x00000000

{ Startup.o (vectors, +First)

* (+RO)}

IRAM 0x40000000

{ Startup.o (MyStacks)}

STACKS_BOTTOM +0 UNINIT

{ Startup.o (StackBottom)}

STACKS 0x40004000 UNINIT

{ Startup.o (Stacks)}

ERAM 0x80000000

{ * (+RW,+ZI)}

HEAP +0 UNINIT

{ Startup.o (Heap)}

HEAP_BOTTOM 0x80080000 UNINIT

{ Startup.o (HeapTop)}

}

;/****************************************************************************************** **************

2008.11.25

zhongcw1002@https://www.360docs.net/doc/2c8839940.html,

加载文件的更多分解说明,网上了解资料。只作参考

有如下分散加载文件:

ROM_LOAD0x00000000 // 程序起始点(程序在Flash中) Origination Point of Code (Code in Flash) {

ROM_EXEC 0x00000000 // 起始程序执行 Origination Point of Executing

{ Startup.o (vectors, +First)

* (+RO) }

IRAM 0x40000040 // 内部SRAM起始点 Origination Point of Internal SRAM

{ Startup.o (MyStacks) } // 0x40000000 ~0x4000003F for Vector

STACKS_BOTTOM +0 UNINIT

{ Startup.o (StackBottom) }

STACKS 0x40004000 UNINIT // End Point of Internal SRAM

{ Startup.o (Stacks) }

ERAM 0x81000000 // 外部RAM起始点 Origination Point of External SRAM

{ * (+RW,+ZI) }

HEAP +0 UNINIT

{ Startup.o (Heap) }

HEAP_BOTTOM 0x81800000 UNINIT // 外部RAM结束点 End Point of External SRAM

{ Startup.o (HeapTop) }

}

其中, ROM_LOAD为加载区的名称,其后面的0x00000000表示加载区的起始地址(存放程序代码的起始地址),也可以在后面添加

其空间大小,如“ROM_LOAD 0x00000000 0x20000”表示加载区起始地址为0x00000000,大小为128K字节;ROM_EXEC描述了执行区的地

址,放在第一块位置定义,其起始地址、空间大小与加载区起始地址、空间大小要一致。从起始地址开始放置向量表(即Startup.o

(vectors,+First),其中Startup.o为Startup.s的目标文件),接着放置其他代码(即映像文件)(即*(RO));变量区IRAM的起始地

址为0x4000000040,放置Startup.o(MyStacks);变量区ERAM的起始地址为0x80000000,放置出Startup.o 文件之外的其他文件的变量

(即*(+RW,+ZI));紧靠ERAM变量区之后的是系统堆空间(HEAP),放置描述为Startup.o(Heap);堆栈区STACKS使用片内RAM,由于

ARM的堆栈一般采用满递减堆栈,所以堆栈区的起始地址设置为0x40004000,放置描述为Startup.o(Stacks)2.使用地址不连续的内存(LPC2368)

Lpc2368一共有56K的RAM,其中通用Ram32K,地址为0x40000000~0x40007fff;8KB的USB专用RAM,地址

0x7fd00000~0x7fd01ffff;

16KB Ethernet专用RAM,地址为0x7fe00000~0x7fe03fff;以上的USB和Ethernet专用RAM也可用做通用RAM,需要做如下设置:(1)

target.c中将USB和Ethernet功能打开,需要设置PCONP寄存器,详见Datasheet。(2)设置分散加载文件,分配这两段内存。

在DebugInRam模式下,有如下分散加载文件:

ROM_LOAD 0x40000000

{

ROM_EXEC 0x40000000 //加载映像文件(通用RAM首地址)

{ Startup.o (vectors, +First)

* (+RO) }

IRAM 0x40007000 //用户堆栈

{ Startup.o (MyStacks) }

STACKS 0x40008000 UNINIT //系统堆栈

{ Startup.o (Stacks) }

ERAM 0x7fe00000 /*变量,放置与Ethernet专用RAM首地址*/

{ * (+RW,+ZI) }

HEAP +0 UNINIT

{ Startup.o (Heap) }

}

3.分散使用Flash地址(LPC2368)

项目中,要求将片内Flash起始几个扇区空出来留作他用,或者当用到的Flash地址不连续的时候,都可用以下方法来编写分散加

载文件:

ROM_LOAD 0x00000000

{

ROM_EXEC0x00000000 /*中断向量表*/

{ Startup.o (vectors,+First) }

……

ROM_LOAD1 0x00004000 //加载映像文件,从第四个扇区开始

{ ROM_EXEC10x00004000

{

* (+RO)

}

}

值得注意的是,中断向量表必须放在flash起始地址处,否则无法启动。根据以上分散加载文件编译生成的Hex文件会有两个,分

别如下:

Hex1:

:020*********FA

:1000000018F09FE518F09FE518F09FE518F09FE5C0

……

Hex2:

:020*********FA

:1040000090808FE20F0098E8080080E0081081E0BF

。。。

可以看出,生成的两段Hex文件的起始地址是不同的,其中一段为中断向量表;另一段为用户映像文件。4.固定变量内存地址

嵌入式开发中,有时会需要在同一片内的不同段程序(比如Bootloader和主程序间)间传递数据,这时候往往需要固定变量地址。

一般来言,C语言编写的程序,变量地址是由C编译器来分配内存的,程序员无法实现知道变量地址。而ADS 中的分散加载文件可以告知

编译器,固定某些变量的地址,如下:

ROM_LOAD 0x00000000

{

ROM_EXEC 0x00000000

{ Startup.o (vectors, +First)

* (+RO) }

RAM 0x40000000 UNINIT //Mfile.c中的所有变量地址从0x40000000开始

{ Mfile.O(+RW,+ZI) }

IRAM 0x40000010

{ Startup.o (MyStacks)

* (+RW,+ZI) }

HEAP +0 UNINIT

{ Startup.o (Heap) }

STACKS 0x40004000 UNINIT

{ Startup.o (Stacks) }

}

上述分散加载文件固定了Mfile.c中变量的起始地址,以这种方法,可以固定任何全局变量的地址,以便其被其他系统访问。

;/****************************************************************************************** **************

;** File name: Startup.s // 起始文件

;定义堆栈的大小

SVC_STACK_LEGTH EQU 0 // 管理堆栈长度

FIQ_STACK_LEGTH EQU 0 // 快速中断堆栈长度

IRQ_STACK_LEGTH EQU 256 // 通用中断堆栈长度

ABT_STACK_LEGTH EQU 0 // 中止堆栈长度

UND_STACK_LEGTH EQU 0 // 未定义堆栈长度

NoInt EQU 0x80

USR32Mode EQU 0x10 // 用户模式

SVC32Mode EQU 0x13 // 管理模式

SYS32Mode EQU 0x1f // 系统模式

IRQ32Mode EQU 0x12 // 通用中断模式

FIQ32Mode EQU 0x11 // 快速中断模式

// 以下几个定义是确定寄存器所在地址(保证前期初始化作业)书本191-193页

PINSEL2 EQU 0xE002C014 // 定义引脚功能选择寄存器2在芯片中所在的地址(0xE002C014)(不管内容)BCFG0 EQU 0xFFE00000 // 存储器组0所在芯片位置(0xFFE00000)设定与外设的读写及间隔速度设定BCFG1 EQU 0xFFE00004 // 存储器组1所在芯片位置(0xFFE00004)设定与外设的读写及间隔速度设定BCFG2 EQU 0xFFE00008 // 存储器组2所在芯片位置(0xFFE00008)设定与外设的读写及间隔速度设定BCFG3 EQU 0xFFE0000C // 存储器组3所在芯片位置(0xFFE0000C)设定与外设的读写及间隔速度设定IMPORT __use_no_semihosting_swi

IMPORT __use_two_region_memory

;引入的外部标号在这声明

IMPORT FIQ_Exception // 快速中断异常处理程序

IMPORT __main // C语言主程序入口

IMPORT TargetResetInit // 目标板基本初始化

;给外部使用的标号在这声明 // 这些标号都是代表一段字节的首地址,可参见后面的部分设定

EXPORT bottom_of_heap // heap的底部

EXPORT bottom_of_Stacks // stack的底部

EXPORT top_of_heap // heap的顶部

EXPORT StackUsr

EXPORT Reset // 复位

EXPORT __user_initial_stackheap // 库函数初始化堆和栈

CODE32 // 32位ARM代码

AREA vectors,CODE,READONLY // 只读程序入口

ENTRY // 进入

;中断向量表

Reset

LDR PC, ResetAddr // 复位起始地址

LDR PC, UndefinedAddr // 未定义异常向量地址

LDR PC, SWI_Addr // 软件复位向量地址

LDR PC, PrefetchAddr // 预指令中止

LDR PC, DataAbortAddr // 数据异常向量地址

DCD 0xb9205f80 // 将所有向量表合计为0的一个指定数据

LDR PC, [PC, #-0xff0] // IRQ ( 该指令会读取VICVectAddr寄存器的值,然后放入PC指针)

LDR PC, FIQ_Addr // 快速中断地址

;给每一个向量分配连续的字存储单元

ResetAddr DCD ResetInit // 将ResetInit入口地址赋予ResetAddr 复位初始化

UndefinedAddr DCD Undefined // 将Undefined入口地址赋予UndefinedAddr 未定义

SWI_Addr DCD SoftwareInterrupt // 将SoftwareInterrupt入口地址赋予SWI_Addr 软件复位PrefetchAddr DCD PrefetchAbort // 将PrefetchAbort入口地址赋予PrefetchAddr 预指令中止DataAbortAddr DCD DataAbort // 将DataAbort入口地址赋予DataAbortAddr 数据异常

Nouse DCD 0 // 将Nouse赋予0

IRQ_Addr DCD 0 // 将IRQ_Addr赋予0 通用中断

FIQ_Addr DCD FIQ_Handler // 将FIQ_Handler入口地址赋予FIQ_Addr 快速中断

;未定义指令

Undefined

B Undefined // 原地循环

SoftwareInterrupt

B SoftwareInterrupt // 原地循环

;取指令中止

PrefetchAbort

B PrefetchAbort // 原地循环

; 取数据中止

DataAbort

B DataAbort // 原地循环

;快速中断

FIQ_Handler

STMFD SP!, {R0-R3, LR} // 入栈

BL FIQ_Exception // 调快速中断程序

LDMFD SP!, {R0-R3, LR} // 出栈

SUBS PC, LR, #4 // 返回当初的地址

;/****************************************************************************************** ***************

;** unction name 函数名称: InitStack

;** Descriptions 功能描述: Initialize the stacks 初始化堆栈

InitStack

MOV R0, LR // 暂存链接地址

;设置管理模式堆栈

MSR CPSR_c, #0xd3 // 设为管理状态(1101 0011),IRQ、FIQ为允许状态

LDR SP, StackSvc // 装入管理模式的堆栈

;设置中断模式堆栈

MSR CPSR_c, #0xd2 // 设为中断状态(1101 0011),IRQ、FIQ为允许状态

LDR SP, StackIrq // 装入管理模式的堆栈

;设置快速中断模式堆栈

MSR CPSR_c, #0xd1 // 设为快速中断状态(1101 0011),IRQ、FIQ为允许状态

LDR SP, StackFiq // 装入快速中断模式的堆栈

;设置中止模式堆栈

MSR CPSR_c, #0xd7 // 设为中止状态(1101 0011),IRQ、FIQ为允许状态

LDR SP, StackAbt // 装入中止模式的堆栈

;设置未定义模式堆栈

MSR CPSR_c, #0xdb // 设为未定义状态(1101 1100),IRQ、FIQ为允许状态

LDR SP, StackUnd // 装入未定义模式的堆栈

;设置系统模式堆栈

MSR CPSR_c, #0xdf // 设为系统状态(1101 1111),IRQ、FIQ为允许状态

LDR SP, =StackUsr // 装入系统模式的堆栈

MOV PC, R0 // 返回链接地址

;/****************************************************************************************** ***************

;** unction name 函数名称: ResetInit

;** Descriptions 功能描述: RESET 复位入口

;初始化外部总线控制器,根据目标板决定配置

LDR R0, =PINSEL2

IF :DEF: EN_CRP // 判断是否已经定义了EN_CRP

LDR R1, =0x0f814910 // 是的,已经定义了,第三位使用为P1.31:26用着GPIO

ELSE

LDR R1, =0x0f814914 // 否则,第三位告诉P1.31:26用作为调试端口

ENDIF

STR R1, [R0] // 设定好管脚选择寄存器2(PINSEL2)

LDR R0, =BCFG0 // 设定好读写外设的延时,课本187页

LDR R1, =0x1000ffef

STR R1, [R0]

// 简单说明:BANK0:8000 0000 –80FF FFFF 配置寄存器BCFG0

LDR R0, =BCFG1 // :BANK1:8100 0000 –81FF FFFF 配置寄存器BCFG1

LDR R1, =0x1000ffef // :BANK2:8200 0000 –82FF FFFF 配置寄存器BCFG2

STR R1, [R0] // :BANK3:8300 0000 –83FF FFFF 配置寄存器BCFG3

// 根据自己的配置的BANK0和BANK1来确定,在本板块中只是有了BANK0和BANK1

; LDR R0, =BCFG2 // BANK2在本例中没有使用,如果配置了也需要设定外设读写速度

; LDR R1, =0x2000ffef

; STR R1, [R0]

; LDR R0, =BCFG3 // BANK3在本例中没有使用,如果配置了也需要设定外设读写速度

; LDR R1, =0x2000ffef

; STR R1, [R0]

BL InitStack // 初始化堆栈

BL TargetResetInit // 目标板基本初始化

// 跳转到c语言入口

B __main

;/****************************************************************************************** ***************

;** unction name 函数名称: __user_initial_stackheap

;** Descriptions 功能描述: 库函数初始化堆和栈,不能删除

;** input parameters 输入: reference by function library 参考库函数手册

;** Returned value 输出: reference by function library 参考库函数手册

__user_initial_stackheap

LDR r0,=bottom_of_heap // 将bottom_of_heap空间对应的地址赋予r0

; LDR r1,=StackUsr // 将StackUsr空间对应的地址赋予r1

LDR r2,=top_of_heap // 将top_of_heap空间对应的地址赋予r2

LDR r3,=bottom_of_Stacks // 将bottom_of_Stacks空间对应的地址赋予r3

MOV pc,lr // 返回链接地址

StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4 // StackSvc赋值

StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4 // StackIrq赋值

StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4 // StackFiq赋值

StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4 // StackAbt赋值

StackUnd DCD UndtStackSpace + (UND_STACK_LEGTH - 1)* 4 // StackUnd赋值

;/****************************************************************************************** ***************

;** unction name 函数名称: CrpData

;** Descriptions 功能描述: encrypt the chip 加密芯片

局部解释:

"."表示当前代码地址; INFO是个伪指令,用于输出出错信息。

整个程序做的事情用一句话来概括,就是保证内部FLASH的0x1fc处为0x87654321。这样,芯片在下次复位时就会加密。

IF :DEF: EN_CRP //声明一个ASM编译条件

IF . >= 0x1fc

INFO 1,"\nThe data at 0x000001fc must be 0x87654321.\nPlease delete some source before this line." ENDIF”

用于检查当前地址是不是已经过了0x1fc.

"CrpData

WHILE . < 0x1fc

NOP

WEND

CrpData1

DCD 0x87654321 ; 当此数为0x87654321时,用户程序被保护 */就是将0x87654321赋值到0x1fc地址处ENDIF"

是在用NOP指令填充0x1fc之前的地址,等填到0x1fc时,就填入0x87654321

IF :DEF: EN_CRP // 判断是否已经定义了EN_CRP

IF . >= 0x1fc // 判断当前地址是否超过了0x0000 001FC

INFO 1,"\nThe data at 0x000001fc must be 0x87654321.\nPlease delete some source before this line." ENDIF

CrpData

WHILE . < 0x1fc //判断还没有超过0x0000 001FC

NOP // 用NOP指令填充,直到0x0000 001FC为止

WEND // 是0x0000 001FC跳出

CrpData1

DCD 0x87654321 // 当到达0x0000 001FC时,将x87654321保存进去时,用户程序被(加密)保护

ENDIF

;/* 分配堆栈空间*/

AREA MyStacks, DATA, NOINIT, ALIGN=2 // 分配一个名为MyStacks的数据空间,无需初始化,地址对齐为半字

SvcStackSpace SPACE SVC_STACK_LEGTH * 4 // 管理模式堆栈空间 = 管理堆栈长度*4(字节)IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 // 中断模式堆栈空间 = 中断堆栈长度*4(字节)FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 // 快速中断模式堆栈空间 = 快速中断堆栈长度*4(字节)AbtStackSpace SPACE ABT_STACK_LEGTH * 4 // 中止模式堆栈空间 = 中止堆栈长度*4(字节)UndtStackSpace SPACE UND_STACK_LEGTH * 4 // 未定义模式堆栈空间 = 未定义堆栈长度*4(字节)AREA Heap, DATA, NOINIT // 分配一个名为Heap的数据堆栈,无需初始化

bottom_of_heap SPACE 1 // 设定一个名字为bottom_of_heap的空间,占用一个字

AREA StackBottom, DATA, NOINIT // 分配一个名为StackBottom的数据堆栈,无需初始化

bottom_of_Stacks SPACE 1 // 设定一个名字为bottom_of_Stacks的空间,占用一个字

AREA HeapTop, DATA, NOINIT // 分配一个名为HeapTop的数据堆栈,无需初始化

top_of_heap // 分配一段名为top_of_heap的未知长度的空间

AREA Stacks, DATA, NOINIT // 分配一个名为HeapTop的数据堆栈,无需初始化

StackUsr // 分配一段名为StackUsr的未知长度的空间

END

;/****************************************************************************************** ***************

;/****************************************************************************************** ***************

;** File Name: IRQ.s

NoInt EQU 0x80

USR32Mode EQU 0x10 // 用户模式

SVC32Mode EQU 0x13 // 管理模式

SYS32Mode EQU 0x1f // 系统模式

IRQ32Mode EQU 0x12 // 通用中断模式

FIQ32Mode EQU 0x11 // 快速中断模式

CODE32 // 32位ARM程序

AREA IRQ,CODE,READONLY

MACRO

$IRQ_Label HANDLER $IRQ_Exception_Function // 用IRQ_Label来替代IRQ_Exception_Function,汇编调用C函数??

EXPORT $IRQ_Label // 输出的标号

IMPORT $IRQ_Exception_Function // 引用的外部标号

$IRQ_Label

SUB LR, LR, #4 // 计算返回地址

STMFD SP!, {R0-R3, R12, LR} // 保存任务环境

MRS R3, SPSR // 保存状态

STMFD SP, {R3,LR}^ // 保存SPSR和用户状态的SP,注意不能回写

// 如果回写的是用户的SP,所以后面要调整SP

NOP

SUB SP, SP, #4*2

MSR CPSR_c, #(NoInt | SYS32Mode) // 切换到系统模式

BL $IRQ_Exception_Function // 调用c语言的中断处理程序

MSR CPSR_c, #(NoInt | IRQ32Mode) // 切换回irq模式

LDMFD SP, {R3,LR}^ // 恢复SPSR和用户状态的SP,注意不能回写

// 如果回写的是用户的SP,所以后面要调整SP

MSR SPSR_cxsf, R3

ADD SP, SP, #4*2 //

LDMFD SP!, {R0-R3, R12, PC}^ // 全部入栈

MEND

;/* 以下添加中断句柄,用户根据实际情况改变*/

;Timer0_Handler HANDLER Timer0

END

;/******************************************************************************************

***************

来资一段网上解释:

$IRQ_Label HANDLER $IRQ_Exception_Function

HANDLER是宏名,有个参数IRQ_Exception_Function,$代表参数会被替换,IRQ_Label是标号。。。

例:$SPI_Exception HANDLER $IRQ_Spi

SPI_Exception 替代 IRQ_Label

IRQ_Label 替代 IRQ_Exception_Function

变为:

SPI_Exception

SUB LR, LR, #4 ; 计算返回地址

STMFD SP!, {R0-R3, R12, LR} ; 保存任务环境

MRS R3, SPSR ; 保存状态

STMFD SP, {R3, SP, LR}^ ; 保存用户状态的R3,SP,LR,注意不能回写

; 如果回写的是用户的SP,所以后面要调整SP

BL IRQ_Spi ; 调用c语言的中断处理程序

(来自网上的一段解释)详细内容请参见清远见嵌入式培训专家《ARM系列处理器应用技术完全手册》第13章 15页

获取映像符号

1 获得连接器预定义符号

连接器定义了一些包含$$的符号。这些符号及其他所有包含$$的名称都是ARM 的保留字。这些符号被用于指定域的基地址,输出段的

基地址和输入段的基地址及其大小。

你可以在你的汇编语言程序中引用这些符号地址,把它们用作可重定位的地址,也可能在C 或C++代码中使用exern 关键字来引用它们。

1.1 与域相关的符号

当armlink 生成映像时产生与域相关的符号。对每个包含一个(被0 初始化)ZI 输出段执行域来说,armlink 都产生包含了$$ZI$$的附加

符号。

Load$$region_name$$Base 域的装载地址

Image$$region_name$$Base 域的执行地址

Image$$region_name$$Length 执行域的长度(4*字节)

Image$$region_name$$Limit 超出执行域结尾的字节地址

Image$$region_name$$ZI$$Base 在此域中ZI 输出段的执行地址

Image$$region_name$$ZI$$Length ZI 输出段的长度(4*字节)

Image$$region_name$$ZI$$Limit 超出执行域中ZI 输出段结尾的字节地址

在ZI 域以上放置堆栈:stack 和heap

通常使用与域相关的符号来在ZI 域以上直接设置堆栈。请参考ADS Development Giude 中有关ROM 的章节。1.2 段相关的符号

一个简单的映像有三个输出段(RO,RW 和ZI),这三个段产生三个执行域。对每个映像中的输入段,armlink 都产生如下的输入符号:

Image$$RO$$Base RO 输出段的起始地址

Image$$RO$$Limit 超出RO 输出段结尾的第一个字节地址

Image$$RW$$Base RW 输出段的起始地址

Image$$RW$$Limt 超出RW 输出段结尾的第一个字节地址

Image$$ZI$$Base ZI 输出段的起始地址

ARM连接器生成的符号

又发现一个不明白的地方:

|Image$$RO$$Limit|

|Image$$RW$$Base|

|Image$$ZI$$Base|

|Image$$ZI$$Limit|

这四个变量表示意思倒是能在注释中看到,但是找来找去,还愣是没有在一大堆文件中找到什么时候定义过这几个变量,最后不得不

找Baidu了,结果如下:

ARM 连接器定义了一些包含$$的符号。这些符号及其他所有包含$$的名称都是ARM 的保留字。这些符号被用于指定域的基地址,输出段

的基地址和输入段的基地址及其大小。

我们可以自己的汇编语言程序中引用这些符号地址,把它们用作可重定位的地址,也可能在C 或C++代码中使用exern 关键字来引用它

们。

因为$在ARM 汇编中有特殊的含义,所以在使用Image$$RO$$Base 这样的符号时需要在两个竖线“|”之间来告诉汇编器这里的$$不用

处理

ARM汇编器的内置变量

内置变量的设置不能用SETA,SETL 或SETS 等指示符来设置,只能用表达式或条件来设置.

例如:

IF {ARCHITECTURE} = "4T"

内置变量变量含义

{PC}或. 当前指令的地址

{VAR}或@ 存储区位置计数器的当前值

{TRUE} 逻辑常量真

{FALSE} 逻辑常量假

{OPT} 当前设置列表选项值,OPT 用来保存当前列表选项,改变选项值,恢复它的原始值

{CONFIG} 如果汇编器汇编ARM 代码,则值为32;如果汇编器汇编Thumb 代码,则值为16

{ENDIAN} 如果汇编器在大端模式下,则值为big;如果汇编器在小端模式下,则值为little {CODESIZE} 如果汇编器汇编ARM 代码,则值为32;如果汇编器汇编Thumb 代码,则值为16,与{CONFIG}同义{CPU} 选定的CPU名,缺省时为ARM7TDMI

{FPU} 选定的FPU名,缺省时为SoftVFP

{ARCHITECTURE} 选定的ARM体系结构的值;3,3M,4,4T和4TxM

{PCSTOREOFFSET} STR pc,[…]或STMRb,[…PC]指令的地址和PC 存储值之间的偏移量

{ARMASM_VERSION}或| ads $ version | ARM 汇编器的版本号,为整数

关于ARM 汇编里的特殊符号

先前企图全部靠自己写一个bootloader,结果尝试了下,花了4 天时间查各种技术资料,写了个startup.s 文件出来,写的过程

中才发现,原来还有很多问题是我基本上不知道的,比如说如何进行ARM 的位操作、如何将堆栈设置到RAM 中、UART 的波特率计算方

法等问题。

在边写边查资料的过程中,我又发现了别人的一些程序我看不懂……因为除了EQU、DCD 等我基本不用伪指

令……

所以我开始看44B0 BootLoader 的范例程序,可能是人家水平实在比较高,也可能是俺的水平确实有限,总之是有些地方看不怎么懂,

特别是一些个特殊符号,现特将那些个麻烦的符号总结下:

符号对应指令含义示例

^ MAP 定义结构化内存表 MAP 4096;内存表首地址为4096

# FIELD 定义内存表中的数据,结合MAP指使用 STACKSVC FIELD 256; 定义从4096开始的256字节为SVC的堆栈空间

% SPACE 分配一块内存,并用“0”初始化 DataStruc SPACE 280分配280字节内存并初始化

来自一个网站的解释:

对于刚学习ARM 的人来说,如果分析它的启动代码,往往不明白下面几个变量的含义:

|Image$$RO$$Limit|

|Image$$RW$$Base|

|Image$$ZI$$Base|。

首先申明我使用的调试软件为ADS1.2,当我们把程序编写好以后,就要进行编译和链接了,在ADS1.2 中选择MAKE 按钮,会出现

一个Errors and Warnings 的对话框,在该栏中显示编译和链接的结果,如果没有错误,在文件的最后应该能看到Image component

sizes,后面紧跟的依次是Code,RO Data ,RW Data ,ZI Data ,Debug 各个项目的字节数,最后会有他们的一个统计数据:

Code 163632 ,RO Data 20939 ,RW Data 53 ,ZI Data 17028

Tatal RO size (Code+ RO Data) 184571 (180.25kB)

Tatal RW size(RW Data+ ZI Data) 17081(16.68 kB)

Tatal ROM size(Code+ RO Data+ RW Data) 184624(180.30 kB)

后面的字节数是根据用户不同的程序而来的,下面就以上面的数据为例来介绍那几个变量的计算。

在ADS 的Debug Settings 中有一栏是Linker/ARM Linker,在output 选项中有一个 RO base 选项,下面应该有一个地址,我这

里是0x0c100000,后面的RW base 地址是0x0c200000,然后在Options 选项中有Image entry point ,是一个初始程序的入口地址,

我这里是0x0c100000 。

有了上面这些信息我们就可以完全知道这几个变量是怎么来的了:

|Image$$RO$$Base| = Image entry point = 0x0c100000 ;表示程序代码存放的起始地址

|Image$$RO$$Limit| = 程序代码起始地址+代码长度+1 = 0x0c100000+Tatal RO size+1

= 0x0c100000 + 184571 + 1 = 0x0c100000 +0x2D0FB + 1

= 0x0c12d0fc

|Image$$RW$$Base| = 0x0c200000 ;由RW base 地址指定

|Image$$RW$$Limit| =|Image$$RW$$Base| + RW Data 53

= 0x0c200000 + 0x37(4 的倍数,0 到55,共56 个单元)

= 0x0c200037

|Image$$ZI$$Base| = |Image$$RW$$Limit| + 1 = 0x0c200038

|Image$$ZI$$Limit| = |Image$$ZI$$Base| + ZI Data 17028

=0x0c200038 + 0x4284

=0x0c2042bc

也可以由此计算:

|Image$$ZI$$Limit| = |Image$$RW$$Base| +TatalRWsize(RWData+ZIData) 17081(17028 + 53)

=0x0c200000+0x42b9+3(要满足4 的倍数)

=0x0c2042bc

/****************************************Copyright

(c)**************************************************

** File name: target.h

#ifndef __TARGET_H

#define __TARGET_H

#ifdef __cplusplus //如果这是一段cpp的代码,那么加入extern "C"{和}处理其中的代码

extern "C" {

#endif

#ifndef IN_TARGET

extern void Reset(void); //复位

extern void TargetInit(void); //目标板初始化

#endif

#ifdef __cplusplus

}

#endif

#endif

******************************************************************************************** ***********/

时常在cpp 的代码之中看到这样的代码:(摘自网上)

1 #ifdef __cplusplus

2 extern "C" { // 为什么括号中先有个#endif,最后又有#ifdef __cplusplus???

3 #endif // 第1 行和第3 行对应,第5 行和第7 行对应

4 //一段代码// {}表示这个括号范围内的都和c 的函数兼容,没有括号的话,extern c 只修饰后面的一个句子

5 #ifdef __cplusplus

6 }

7 #endif

这样的代码到底是什么意思呢?首先,__cplusplus 是cpp 中的自定义宏,那么定义了这个宏的话表示这是一段cpp 的代码,也就

是说,上面的代码的含义是:如果这是一段cpp 的代码,那么加入extern "C"{和}处理其中的代码。

要明白为何使用extern "C",还得从cpp 中对函数的重载处理开始说起。在c++中,为了支持重载机制,在编译生成的汇编码中,

要对函数的名字进行一些处理,加入比如函数的返回类型等等.而在C中,只是简单的函数名字而已,不会加入其他的信息.也就是说:C++

和C 对产生的函数名字的处理是不一样的.

比如下面的一段简单的函数,我们看看加入和不加入extern "C"产生的汇编代码都有哪些变化:

int f(void)

{

return 1;

}

在加入extern "C"的时候产生的汇编代码是:

.file "test.cxx"

.text

.align 2

.globl _f

.def _f; .scl 2; .type 32; .endef

_f:

pushl %ebp

movl %esp,%ebp

movl $1,%eax

popl %ebp

ret

但是不加入了extern "C"之后

.file "test.cxx"

.text

.align 2

.globl __Z1fv

.def __Z1fv; .scl 2; .type 32; .endef

__Z1fv:

pushl %ebp

movl %esp,%ebp

movl $1,%eax

popl %ebp

ret

两段汇编代码同样都是使用gcc -S 命令产生的,所有的地方都是一样的,唯独是产生的函数名,一个是_f,一个是__Z1fv。

明白了加入与不加入extern "C"之后对函数名称产生的影响,我们继续我们的讨论:为什么需要使用extern "C"呢?C++之父在设计

C++之时,考虑到当时已经存在了大量的C 代码,为了支持原来的C 代码和已经写好C 库,需要在C++

中尽可能的支持C,而extern

"C"就是其中的一个策略。

试想这样的情况:一个库文件已经用C 写好了而且运行得很良好,这个时候我们需要使用这个库文件,但是我们需要使用C++来写

这个新的代码。如果这个代码使用的是C++的方式链接这个C 库文件的话,那么就会出现链接错误.我们来看一段代码:首先,我们使

用C 的处理方式来写一个函数,也就是说假设这个函数当时是用C 写成的:

//f1.c

extern "C"

{

void f1()

{

return;

}

}

编译命令是:gcc -c f1.c -o f1.o 产生了一个叫f1.o 的库文件。再写一段代码调用这个f1 函数:

// test.cxx

//这个extern 表示f1 函数在别的地方定义,这样可以通过

//编译,但是链接的时候还是需要

//链接上原来的库文件.

extern void f1();

int main()

{

f1();

return 0;

}

通过gcc -c test.cxx -o test.o 产生一个叫test.o 的文件。然后,我们使用gcc test.o f1.o 来链接两个文件,可是出错了,错误的提

示是:

test.o(.text + 0x1f):test.cxx: undefine reference to 'f1()'

也就是说,在编译test.cxx 的时候编译器是使用C++的方式来处理f1()函数的,但是实际上链接的库文件却是用C 的方式来处理

函数的,所以就会出现链接过不去的错误:因为链接器找不到函数。

因此,为了在C++代码中调用用C 写成的库文件,就需要用extern "C"来告诉编译器:这是一个用C 写成的库文件,请用C 的方

式来链接它们。

比如,现在我们有了一个C 库文件,它的头文件是f.h,产生的lib(库)文件是f.lib,那么我们如果要在C++中使用这个库文件,

我们需要这样写:

extern "C"

{

#i nclude "f.h"

}

回到上面的问题,如果要改正链接错误,我们需要这样子改写test.cxx:

extern "C"

{

extern void f1();

}

int main()

{

f1();

return 0;

}

重新编译并且链接就可以过去了.

总结

C 和C++对函数的处理方式是不同的.extern "C"是使C++能够调用C 写作的库文件的一个手段,如果要对编译器提示使用C 的方

式来处理函数的话,那么就要使用extern "C"来说明。

/****************************************Copyright

(c)*****************************************************

** File name: target.c 目标设定

#define IN_TARGET

#include "config.h"

/******************************************************************************************* **************

** Function name: IRQ_Exception

void __irq IRQ_Exception(void) // IRQ中断异常事件,本例死循环

{

while(1); //这一句替换为自己的代码

}

/******************************************************************************************* **************

** Function name: FIQ_Exception

void FIQ_Exception(void) // FIQ中断异常事件,本例死循环

{

while(1); //这一句替换为自己的代码

}

/******************************************************************************************* **************

** Function name: TargetInit

void TargetInit(void)

{

/* 添加自己的代码*/

}

void TargetResetInit(void) // 目标复位初始化

{

#ifdef __DEBUG // 采用调试方式进行编译,书本166页说明

MEMMAP = 0x3; // MEMMAP的MAP[1:0] = 3 ,采用外包存储器进行重新映射

#endif

#ifdef __OUT_CHIP // 采用外部芯片存储器

MEMMAP = 0x3; // MEMMAP的MAP[1:0] = 3 ,采用外包存储器进行重新映射

#endif

#ifdef __IN_CHIP // 采用芯片内部存储器

MEMMAP = 0x1; // MEMMAP的MAP[1:0] = 1 ,采用用户FLASH进行重新映射

#endif

/* 设置系统各部分时钟*/

// 设置系统各部分时钟,由系统硬件决定

// 设置外设时钟(VPB时钟pclk)与系统时钟(cclk)的分频比

// pclk与cclk具体值得大小在config.h中定义

PLLCON = 1; // 设置激活但未连接PLL

#if (Fpclk / (Fcclk / 4)) == 1 // 此值由系统硬件决定

VPBDIV = 0; // VPB时钟频率Fpclk只能为系统时钟频率Fcclk的1、2、4倍

#endif

#if (Fpclk / (Fcclk / 4)) == 2

VPBDIV = 2;

#endif

#if (Fpclk / (Fcclk / 4)) == 4

VPBDIV = 1;

#endif

//设定PLL的乘因子M和除因子P的值,Fcclk / Fosc = M, Fcco / Fcclk = 2 * P

#if (Fcco / Fcclk) == 2 // CCO频率,必须为Fcclk的2、4、8、16倍,范围156~320MHz

PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5);

#endif

#if (Fcco / Fcclk) == 4

PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5);

#endif

#if (Fcco / Fcclk) == 8

PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5);

#endif

#if (Fcco / Fcclk) == 16

PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5);

#endif

PLLFEED = 0xaa; // 发送PLL馈送序列,执行设定PLL的动作

PLLFEED = 0x55;

while((PLLSTAT & (1 << 10)) == 0); // 等待PLL锁定

PLLCON = 3; // 设置激活并连接PLL

PLLFEED = 0xaa; // 发送PLL馈送序列,执行激活和连接动作

PLLFEED = 0x55;

/* 设置存储器加速模块*/

MAMCR = 0; // 关闭存储加速器MAM(00禁止/01部分使能/10完全使能)

#if Fcclk < 20000000 // 系统时钟是否低于20MHz,建议置1

MAMTIM = 1;

#else

#if Fcclk < 40000000 // 系统时钟是否在20~40MHz之间,建议置2

MAMTIM = 2;

#else

MAMTIM = 3; // 系统时钟是否高于40MHz,建议置3

#endif

#endif

MAMCR = 2; // 完全使能存储加速器MAM

/* 初始化VIC */

VICIntEnClr = 0xffffffff; // 中断使能清零寄存器

VICVectAddr = 0; // 向量地址寄存器

VICIntSelect = 0; // 设置所有中断分配为IRQ中断(中断选择寄存器)

/* 添加自己的代码*/

}

/******************************************************************************************* **************

嵌入式课程设计报告

嵌入式课程设计报告设计题目:电子密码锁

、 摘要 随着科技和人们的生活水平的提高,实现防盗的问题也变得尤为突出,传统机械锁构造简单,电子锁的保密性高,使用灵活性好。根据需要设计运用W90P170开发板,制作一款电子密码锁,密码锁通过键盘输入密码,通过在LCD的文字和图片显示当前密码锁的状态。实现设置密码,密码验证,错误密码自锁、图片显示的功能。 目录

一、选题意义及系统功能 (3) 二、硬件设计及描述 (4) 三、软件设计及描述 (5) 四、程序代码 (6) 五、课程设计体会 (11) 六、运行结果 (12) 七、心得体会 (12) 八、参考文献 (13) 九、附录 (13) 一、选题意义及功能描述 1、选题意义 电子密码锁是通过密码输入来控制电路或是芯片工作,从而控制机械的开关闭合、开锁的电子产品。随着科技提高和人们生活水平的提高,对电子密码锁的需求增加。电子密码做较传统的机械锁安全性能更高。 特点如下: (1)保密性好,编程量大,随机开锁的成功率几乎为零。

(2)密码可变,用户可以随时改变密码,防止密码被盗,同时也可以避免人员的更替而使锁的密级下降。 (3)误码输入保护,输入密码多次错误是,系统进行自锁。 (4)无活动零件,不会磨损,寿命长。 (5)使用灵活性好,无需佩戴钥匙,操作简单。 2、功能描述 基本功能: (1)从键盘输入任意6位数字作为密码,将这六位数字经过USI总线存储到Flash芯片中,设置密码完成。 (2)从键盘输入密码,比较键盘输入的密码与Flash中存储的密码是否相同。 (3)如果密码正确,则LED灯点亮;如果密码不正确,则LED灯闪烁,而且如果连续三次输入密码错误则系统锁定,不允许再次输入密码。 扩展功能: (1)首先显示“请输入密码:”,显示密码锁背景图片1。 (2)如果密码正确则显示“密码正确”,显示成功进入系统的背景图片2。 (3)如果密码不正确则显示“密码不正确,请重新输入:” (4)如果连续三次输入密码错误则显示“对不起,您已经连续三次输入密码错误,系统锁定”,显示图片1。

嵌入式实验心得体会

嵌入式实验心得体会 嵌入式实验心得体会是计算机专业应该具备的常用知识,以下这篇范文整理个人对嵌入式系统的认识,和进行操作之后的个人体会,对操作的疑难的反思。下面是这篇嵌入式实验心得体会 嵌入式实验心得体会 学期开始,我们开始学习《嵌入式系统及应用》,由于初次接触嵌入式系统,感觉蛮难的,所以收获不是很大,很多的概念都比较模糊,等到学期结束开始做嵌入式课程设计时,真是茫然无从下手,自,从拿到设计主题后,我就从像热锅像上的蚂蚁,一个字“急”。最后实在没有办“法,逼着自己去学法 习,查资料,总算对嵌入式有了资浅层理解。浅 嵌入式系统本本身是一个相对模糊的定义义,一个手持的mp3和一个一pc104的微型工业业控制计算机都可以认为是嵌入是式系统。总体来说,嵌入式系统是“用于控,制,监视或者辅制 助操作机器器和设备的装备”。一个典典型的桌面linux系统统包括3个主要的软件层---linux-内核、cc库和应用程序代码。内核核是唯一可以完全控制硬件的层,内核驱动程序代件表应用程表序与硬件之间进行行会话。内核之上是c 库,,负责把posixapii转换为内核可以识别的形形式,然后调用内核,从应应用程序向内核传递参数。应用程序依靠驱动内核。来完成特定的任务。来在了解了基础知识之后,我了开始进行上机操作,当然开,,其中遇到很多的难题,很多东西都是第一次接触很,又没有别,人在旁边指导操作,完全凭借自己去摸操索索练习。其中的困难可想而知。然而坚持就是胜利而,,牙一咬眼一闭坚持做下去去,而通过本次实验,我感觉收获还是蛮多的。可感能我对于嵌入能式的知识学习的还是不太多,但是这习之外的东西收获颇丰。之

arm嵌入式linux安装课程设计心得

arm嵌入式linux安装课程设计心得 篇一:116709047陈俊松嵌入式Linux课程设计 福建农林大学金山学院电子信息类课程设计 课程名称:设计题目:姓名: 系: 专业:年级:学号:指导教师:职称: 嵌入式linux应用开发课程设计嵌入式linux Web服务器的设计 陈俊松信息与机电工程系电子信息工程2011级116709047 朱仕浪讲师 2014年11 月24 日 福建农林大学金山学院电子信息类 课程设计结果评定 目录 设计的目的

-------------------------------------------------------- 1 设计要求---------------------------------------------------------- 1 主要仪器设备(软硬件环境)---------------------------------------- 1 设计内容---------------------------------------------------------- 1 设计原理---------------------------------------------------- 1 总体方案设计------------------------------------------------- 3 程序设计---------------------------------------------------- 3 程序的调试和运行结果---------------------------------------- 7 总结-------------------------------------------------------------- 8 参考文献---------------------------------------------------------- 9 嵌入式linux Web服务器的设计 1. 设计的目的

嵌入式系统课程设计

《嵌入式系统设计与应用》课程设计 题目嵌入式系统的实践教学探讨 1.嵌入式系统设计与应用课程的内容概述 1.1 内容概述 本课程适用于计算机类专业,是一门重要的专业课程。它的任务是掌握嵌入式系统的基本概念;掌握嵌入式处理器 ARM 体系结构,包括ARM总体结构、存储器组织、系统控制模块和I/O外围控制模块;掌握ARM指令集和Thumb指令集;掌握ARM汇编语言和C语言编程方法;了解基于ARM 的开发调试方法。它的目的是了解和掌握嵌入式处理器的原理及其应用方法。 1)介绍嵌入式系统开发的基础知识,从嵌入式计算机的历史由来、嵌入式系统的定义、嵌入式系统的基本特点、嵌入式系统的分类及应 用、嵌入式系统软硬件各部分组成、嵌入式系统的开发流程、嵌入 式技术的发展趋势等方面进行了介绍,涉及到嵌入式系统开发的基 本内容,使学生系统地建立起的嵌入式系统整体概念。 2)对ARM技术进行全面论述,使学生对ARM技术有个全面的了解和掌握,建立起以ARM技术为基础的嵌入式系统应用和以ARM核为基础 的嵌入式芯片设计的技术基础。 3)ARM指令系统特点,ARM 指令系统,Thumb 指令系统,ARM 宏汇编,ARM 汇编语言程序设计,嵌入式 C 语言程序设计。 1.2实践教学探讨 在IEEE 计算机协会2004年6月发布的Computing Curricula Computer Engineering Report, Ironman Draf t 报告中把嵌入式系统课程列为计算机工程学科的领域之一,把软硬件协同设计列为高层次的选修课程。美国科罗拉多州立大学“嵌入式系统认证”课程目录包括实时嵌入式系统导论、嵌入式系统设计和嵌入式系统工程训练课程。美国华盛顿大学嵌入式系统课程名称是嵌入式系统

嵌入式操作系统课程设计报告

嵌入式系统设计报告 系(院):计算机科学学院 专业班级:计科11201 姓名:微尘 学号: 201203300 指导教师:王剑 设计时间:2015.6.22 - 2015.7.3 设计地点:4教硬件实验室

目录 一、课程设计的目的 (2) 1.1设计目的 (2) 1.2任务介绍 (2) 二、实验及开发环境 (3) 2.1 实验室环境 (3) 2.2 个人计算机课后开发环境 (3) 三、总体设计 (3) 四、详细设计 (4) 4.1 Windows CE系统编译与安装 (4) 4.2 编程驱动LED和数码管显示正确的信息 (7) 4.3 编程驱动电机运转 (8) 4.4 个人设计小程序 (10) 五、课程设计小结 (17) 5.1 设计小结 (17)

一、课程设计的目的 1.1设计目的 本次课程设计的目的是了解嵌入式系统、嵌入式操作系统,掌握基于嵌入式系统的应用开发基本知识。了解嵌入式操作系统Windows CE的特点,Windows CE的主要模块及各自的功能。掌握嵌入式操作系统Windows CE 的配置、编译、移植方法。了解Visual Studio .NET开发环境,掌握基于Windows CE平台的应用程序设计方法。 1.2任务介绍 以下任务需基于实验室的XSBase270开发平台完成 1.嵌入式操作系统Windows CE平台的搭建 使用Platform Builder编译出自己的Windows CE 5.0操作系统,然后根据实验提供的EBOOT引导程序将编译出的Windows CE 5.0系统安装(刷入)到实验平台。 2.IO接口控制-七段数码管的LED显示控制程序 了解Windows CE下I/O访问机制的原理。了解LED和七段数码管的显示和控制原理。掌握Windows CE下访问硬件I/O寄存器的方法。 3.IO接口控制-点击控制设计 了解Window CE下I/O访问机制和原理。掌握Windows CE下访问硬件I/O寄存器的方法,以及使用Visual Studio .NET对硬件设备编程的一般方法。 4.编写实用小程序并在指定的Windows CE平台上运行调试(选做) 这一部分我选择的是在Windows CE平台上使用Visual Studio 2005基于.NET利用C#语言编写一个简易计算器小程序。从而体验对嵌入式设备编程与普通PC编程的区别。

嵌入式系统课程设计报告

嵌入式系统课程设计报告 课程名称:嵌入式系统课程设计 项目名称:基于ARM实现MP3音乐盒 专业:电子科学与技术

一、设计内容 基本功能:预存四首歌曲,实现循环播放; 每个按键对应一首歌曲。 拓展功能:通过按键简单演奏音乐,类似钢琴; 实现两个模式的切换,切歌模式和音量加减模式。 二、设计思路 基础功能: 将音频数据存储在SD卡中,使用FATFS文件系统进行数据的读写,通过SPI2总线将数据传到内核。内核再将数据通过SPI1总线传送到音频解码模块VS1053,输入的数据(即比特流数据)被解码后送到DAC发出声音。 将音乐存储在SD卡内,通过文件的地址来判别将要播放哪一首音乐,通过地址的递增和循环来实现音乐的自动循环播放。按键对曲目的控制,可通过键盘扫描函数,判断哪一个键被按下,使键盘扫描函数返回不同的返回值,实现对文件地址的控制。将此返回值设置为全局变量,可实现在音乐播放中曲目的切换。 另外,我们还利用解码模块实现对音量的控制,使用按键控制音量的提高或降低。使用SPI1总线将TFT显示屏连接到内核,显示按键功能、当前曲目、当前模式等信息。 由于开发板只有5个按键,按键数量有限,需要对按键实现曲目切换和音量功能的复用。我们小组设置了两种模式,切歌模式和音量模式,并定义左键为模式切换键,实现不同模式的选择和按键的复用。 拓展功能: 基本思路是通过定时器中断来产生一定频率的50% 空占比的脉宽调制波,用此脉宽调制波激励扬声器,从而使扬声器发出一定频率的声音。 所以只要将不同按键的中断子程序设置为对定时器进行不同数据的配置,即可实现不同按键与不同扬声器发生频率的对应。 然后使一个按键的按下与松开均进入中断,且分别实现开启(扬声器发声)与关闭(扬声器不发声)定时器的功能,从而使课题的附加功能表现地更自然。 三、硬件配置 基础功能: (1)SD卡:存储音频数据

嵌入式课程设计心得体会【精选】

本学期为期一周的嵌入式课程设计在不知不觉中结束了,虽说这次课程设计时间不是很长,但是感觉自己收获颇丰,不仅学习到了一些新知识,回顾了以前的一些快要遗忘的知识点,而且使自己的学习目标更加明确,学习方法更加完善,也体会到软件开发的趣味,更加清楚地认识到了自己在软件开发及学习上的一些不足之处。下面就来详细写一下我关于此次课程设计的心得体会: 此次课程设计的实训的是由上海杰普公司的楚老师带我们完成的。楚老师看上去比较年轻,给我们很有亲和力,技术上也很强,而且讲解的比较详细,操作上相当娴熟。让我们感觉到了计算机科学技术学习的趣味性,计算机技术的实用性。此次课程设计给老师选择项目是在下用C语言开发一个摄像头驱动程序。项目的实施方式是团队分组合作,共同完成,让我们体验了一下公司开发项目的氛围。我们一人一机,老师边讲边练,还有企业项目经理的全程指导。虽说一些些技术我们在课堂上也曾学习过,但是大多停留在理论学习上,实际开发很少,而这次课程设计给了我们一个很好的边学习边实践的机会,对我们深入学习这些技术有很大帮助,深刻体会到了这些技术的实用性。每当自己成功调试一段代码或者通过自己的努力克服一个技术困难,都颇有收获感。这次实训让我们体验了软件开发的全过程,发现自己的不足,了解了当前流行技术的软件开发,增加了一定的项目开发经验,增强了一定的就业竞争力。简短的回顾一下这几天我们所学习的: 实训的前一天下午,我们先明确了一下下周课程设计的要求和目的,跟上海杰普公司的楚老师相互认识了一下。然后楚老师给我们详细的讲解了这一周我们要做什么,并演示了一个他自己开发的摄像头驱动程序。同学们看了,都很感兴趣,如果自己能开发出这样的一个小程序,着实让人高兴。接下来的这几天我们就跟着范老师一起学习摄像头驱动的开发,同时我们也分了小组,模拟体验一下公司的团队开发,同学们都积极策划自己团队的名字、团队的口号、队歌……我们首先从基本的命令学起,以及底下的C语言的一些基本知识。虽说这学期我们也学过开发技术,有一定的基础,但这几天的学习,还是感觉到我们学的太浅,很多的东西需要去深入的学习才能有所收获。而且深刻的体会到“熟能生巧”这句良训,光学不练还是白搭。后两天我们学习了底下一些开发工具的使用,如,感觉这些工具功能确实够强大。当通过自己写的代码能够控制摄像头拍照时,别提有多高兴了。当然在调试的过程中也遇到不少错误,每当通过自己的努力把问题解决(一般自己思考一下,查查资料都没问题),也是一种很好的收获。还有一个比较深刻的体会就是A 及一些文档的查阅,这对开发人员来说是一个必须具备的能力。 一周的课程设计,一周的实训,在计算机这个博大深奥的领域我感觉自己还有好多东西要学,还有好多的东西不懂(这也再次坚定了我考研深造的决心)!嵌入式软件开发应用广泛而且前景很好,目前正处于人才紧缺的关口,嵌入式技术在未来能够得到更加广泛的应用。学好嵌入式,C语言很重要,所以感觉自己有必要在学习、积累一下这方面的知识。很多东西的学习不死一帆风顺也是比较耗时的,嵌入式也不例外,要想学好还必须下大力气,还必须坚持。这次的课程设计让我明确了一点:嵌入式开发对于提升我们的系统知识有很大的帮助,尤其是操作系统的知识。嵌入式系统开发对于我们的知识面要求非常的广,且要有一定的深度。这次的课程设计因为是一个有针对性的训练,所以记的会非常牢固。跟平时上课不太一样,平时上完理论课很少有时间上机进行时间或者隔几天才上机练习,等到上机时一些东西可能遗忘了,比较耗费时间。在课上,有老师在前面演示我们感觉看得懂或感觉没问题,可轮到我们独立完成的时候,因为实际操作的少,跟中问题就来了!我很感谢学校特别是学院老师有实训这样的安排,把我们这一学期学的东西系统的集中的进行训练,让我们深刻明确的

课程设计心得和体会

第六章课程设计总结 经过近二周的单片机课程设计,终于完成了我的频率计的设计,基本达到设计要求。 对于此次课程设计,有许多的感触与体会,遇到的难题多,学习到的知识也就更多。 第一,硬件电路首先遇到了对试验箱内部硬件电路不了解,经过试验箱上面本身所带的几个与频率计有关的实验(计数器实验、8279显示实验)最终了解试验箱内部电路连接。 第二,则是解决程序设计的问题,而程序设计是一个很灵活的东西,它反映了你解决问题的逻辑思维和创新能力。由于以前都是使用C语言编写程序,对汇编语言的编程能力还不够,所以在经过了解硬件电路后只编写了C语言程序并调试成功。 第三,在一个课题中,要设计一个完整的电路,必须要有耐心,要有坚持的毅力。在整个电路的设计过程中,重要的是各个单元电路的连接及电路的细节设计上,如程序地址的正确,不然就会与原程序对应不上。这就要求我们对硬件系统中各组件部分有充分透彻的理解和研究,并能对之灵活应用。完成这次设计后,我在书本理论知识的基础上又有了更深层次的理解。 第四,在本次设计的过程中,我还学会了高效率的查阅资料、运用工具书、利用网络查找资料。我发现,在我们所使用的书籍上有一些知识在实际应用中其实并不是十分理想,各种参数都需要自己去调整,这就要求我们应更加注重实践环节。 最后,还要在此感谢课程设计的指导老师,他们在整个过程中都给予了我充分的帮助与支持。 参考文献 [1]赵全利、肖兴达.《单片机原理及应用教程》(第二版).机械工业出版社,2007 [2]蔡美琴等.《MCS-51系列单片机系统及其应用》.高等教育出版社. [3]吴国经.《单片机应用技术》.北京:中国电力出版社,2003. [4]徐爱钧.《智能化测量控制仪表原理与设计》(第二版)[M].北京:北京航空航天大学 出版社,2004. 8 总结与体会 经过几个星期的努力,在本组同学的齐心合作下使得本设计顺利完成,通过这次课程设计,使自己的知识水平有了显著的提高,并学会了如何将自己所学的运用于实践之中,本系统所涉及的东西几乎涵盖了大学所学的各个方面的知识,如电子技术、电路原理、程序设计基础、检测与转换、单片机等,可以说,没有大学前三年的系统学习本设计几乎是不可能完成的,尽管下半年就将毕业,但是学习却是终身受益的事情,只有不断学习才能不断进步,只有不断的将所学运用

嵌入式课程设计报告

嵌入式课程设计报告 设计题目:电子密码锁 、

摘要 随着科技和人们的生活水平的提高,实现防盗的问题也变得尤为突出,传统机械锁构造简单,电子锁的保密性高,使用灵活性好。根据需要设计运用W90P170开发板,制作一款电子密码锁,密码锁通过键盘输入密码,通过在LCD的文字和图片显示当前密码锁的状态。实现设置密码,密码验证,错误密码自锁、图片显示的功能。 目录 一、选题意义及系统功能 (3) 二、硬件设计及描述 (4) 三、软件设计及描述 (5) 四、程序代码 (6) 五、课程设计体会 (11) 六、运行结果 (12) 七、心得体会 (12) 八、参考文献 (13) 九、附录 (13) 一、选题意义及功能描述

1、选题意义 电子密码锁是通过密码输入来控制电路或是芯片工作,从而控制机械的开关闭合、开锁的电子产品。随着科技提高和人们生活水平的提高,对电子密码锁的需求增加。电子密码做较传统的机械锁安全性能更高。 特点如下: (1)保密性好,编程量大,随机开锁的成功率几乎为零。 (2)密码可变,用户可以随时改变密码,防止密码被盗,同时也可以避免人员的更替而使锁的密级下降。 (3)误码输入保护,输入密码多次错误是,系统进行自锁。 (4)无活动零件,不会磨损,寿命长。 (5)使用灵活性好,无需佩戴钥匙,操作简单。 2、功能描述 基本功能: (1)从键盘输入任意6位数字作为密码,将这六位数字经过USI总线存储到Flash芯片中,设置密码完成。 (2)从键盘输入密码,比较键盘输入的密码与Flash中存储的密码是否相同。 (3)如果密码正确,则LED灯点亮;如果密码不正确,则LED灯闪烁,而且如果连续三次输入密码错误则系统锁定,不允许再次输入密码。 扩展功能: (1)首先显示“请输入密码:”,显示密码锁背景图片1。 (2)如果密码正确则显示“密码正确”,显示成功进入系统的背景图片2。 (3)如果密码不正确则显示“密码不正确,请重新输入:” (4)如果连续三次输入密码错误则显示“对不起,您已经连续三次输入密码错误,系统锁定”,显示图片1。 3、个人开发流程 (1)了解开发板的硬件结构编写适应其硬件结构的程序。 (2)掌握并编写LCD显示文本和图片程序。 (3)通过EBI对外部LED灯进行控制。 (4)键盘键值读取,及密码锁密码比对,密码锁状态转换的程序编写。 二、硬件设计及描述

嵌入式学习心得体会例文

嵌入式学习心得体会例文 篇一 1、熟悉CPU。x86中存在实模式和保护模式,CPU一上电后进入的是实模式,要进入保护模式则需要做一定的设置,最后做一个长跳转,就能进入保护模式。对于这一处理器的熟悉和了解,使得我对于处理器有一个很好的认识。此外,还得明白什么是芯片组、PCI的原理和配置方法、SDRAM如何配置、IDE 的PIO模式如何工作。 2、熟悉uC/OSRTOS并对其进行扩展。理解任务是如何实现的、任务是如何被调度的、Mutex和Semaphore是如何实现的、对处理器进行开关中断的目的是什么且要注意什么,等等。对于RTOS的扩展则包括实现了一个采用malloc/free进行内存分配的堆管理模块,这一管理模块是参照XINU操作系统来实现的;对任务调度部分进行修改以方便中断服务程序的管理。 3、MINUX操作系统的文件系统移植到我们的DVR上。MINUX 中采用的就是UNIX中的i-node的方式来管理文件的,这种方式在现在的Linux中也能看到。由于MINUX的文件系统是针对小型存储设备的,所以对其代码要进行修改,以适应当时所采用的上G的硬盘。 4、XINU中的TCP协议栈移植到DVR上。 以上的工作内容让嵌入式技术人员对于操作系统的原理和

实现得到了很好的实操。不过在嵌入式系统开发领域中这也只 是入门级别。后续还有处理器操作、RTEMS操作系统、编译器 和C语言的使用等都需要嵌入式开发人员慢慢精通。 篇二 学期开始,我们开始学习《嵌入式系统及应用》,由于初次接触嵌入式系统,感觉蛮难的,所以收获不是很大,很多的概 念都比较模糊,等到学期结束开始做嵌入式课程设计时,真是 茫然无从下手,自从拿到设计主题后,我就像热锅上的蚂蚁, 一个字急。最后实在没有办法,逼着自己去学习,查资料,总 算对嵌入式有了浅层理解。 嵌入式系统本身是一个相对模糊的定义,一个手持的mp3 和一个pc104的微型工业控制计算机都可以认为是嵌入式系统。总体来说,嵌入式系统是用于控制,监视或者辅助操作机器和 设备的装备。一个典型的桌面linux系统包括3个主要的软件层---linux内核、c库和应用程序代码。内核是可以完全控制硬 件的层,内核驱动程序代表应用程序与硬件之间进行会话。内 核之上是c库,负责把posixapi转换为内核可以识别的形式,然后调用内核,从应用程序向内核传递参数。应用程序依靠驱 动内核来完成特定的任务。 在了解了基础知识之后,我开始进行上机操作,当然,其 中遇到很多的难题,很多东西都是第一次接触,又没有别人在 旁边指导操作,完全凭借自己去摸索练习。其中的困难可想而

课程设计心得体会及感受

课程设计心得体会及感受 本学期为期一周的嵌入式课程设计在不知不觉中结束了,虽 说这次课程设计时光不是很长,但是感觉自我收获颇丰,不仅仅 学习到了一些新知识,回顾了以前的一些快要遗忘的知识点,而 且使自我的学习目标更加明确,学习方法更加完善,也体会到软 件开发的趣味,更加清楚地认识到了自我在软件开发及学习上的 一些不足之处。下方就来详细写一下我关于此次课程设计的心得 体会: 此次课程设计的实训的是由上海杰普公司的楚老师带我们完 成的。楚老师看上去比较年轻,给我们很有亲和力,技术上也很强,而且讲解的比较详细,操作上相当娴熟。让我们感觉到了计 算机科学技术学习的趣味性,计算机技术的实用性。此次课程设 计给老师选取项目是在Linux下用c语言开发一个摄像头驱动程序。项目的实施方式是团队分组合作,共同完成,让我们体验了一下 公司开发项目的氛围。我们一人一机,老师边讲边练,还有企业 项目经理的全程指导。虽说一些些技术我们在课堂上也曾学习过,但是大多停留在理论学习上,实际开发很少,而这次课程设计给 了我们一个很好的边学习边实践的机会,对我们深入学习这些技 术有很大帮忙,深刻体会到了这些技术的实用性。每当自我成功 调试一段代码或者透过自我的努力克服一个技术困难,都颇有收 获感。这次实训让我们体验了软件开发的全过程,发现自我的不

足,了解了当前流行技术的软件开发,增加了必须的项目开发经验,增强了必须的就业竞争力。简短的回顾一下这几天我们所学 习的: 实训的前一天下午,我们先明确了一下下周课程设计的要求 和目的,跟上海杰普公司的楚老师相互认识了一下。然后楚老师 给我们详细的讲解了这一周我们要做什么,并演示了一个他自我 开发的摄像头驱动程序。同学们看了,都很感兴趣,如果自我能 开发出这样的一个小程序,着实让人高兴。接下来的这几天我们 就跟着范老师一齐学习摄像头驱动的开发,同时我们也分了小组,模拟体验一下公司的团队开发,同学们都用心策划自我团队的名字、团队的口号、队歌……我们首先从基本的Linux命令学起, 以及linux底下的c语言的一些基本知识。虽说这学期我们也学过Linux开发技术,有必须的基础,但这几天的学习,还是感觉到我们学的太浅,很多的东西需要去深入的学习才能有所收获。而且 深刻的体会到“熟能生巧”这句良训,光学不练还是白搭。后两 天我们学习了Linux底下一些开发工具的使用,如Qt,感觉这些 工具功能确实够强大。当透过自我写的代码能够控制摄像头拍照时,别提有多高兴了。当然在调试的过程中也遇到不少错误,每 当透过自我的努力把问题解决(一般自我思考一下,查查资料都没 问题),也是一种很好的收获。还有一个比较深刻的体会就是API 及一些文档的查阅,这对开发人员来说是一个务必具备的潜力。 此次实训最大的收获不是我学习到了多少知识而是这几天实

嵌入式课程设计报告

嵌入式课程设计报告 一、课程设计目的 1.1 掌握linux开发环境的搭建; 1.2巩固嵌入式交叉编译的开发思想; 1.3掌握嵌入式GUI软件设计技。,. 二、课程设计要求 输入信号为 1 路AV 视频信号,要求系统能对 1 路输入信号进行实时采集,数字化处理,压缩,存储,要保证一定的录像质量. 根据设计题目的要求,选择确定ARM 芯片型号,视频采集芯片型号,完成系统硬件设计和程序设计. 三、课程设计内容 设计原理ARM10 系列微处理器为低功耗的32 位RISC 处理器,最适合用于对价位和功耗要求较高的消费类应用. ARM10 系列微处理器的主要应用领域为:工业控制,Internet 设备,调制解调器设备,移动电话等多种多媒体和嵌入式应用. 视频监控系统总体设计首先需要对系统进行总体规划,将系统划分成几个功能模块,确定各个模块的实现方法.整个视频监控系统采用C/S 结构,从主体上分为两部分:服务器端和客户端.服务器端主要包括S3C4510 平台上运行的采集,压缩,传输程序,客户端是PC 机上运行的接收,解压,回放程序.视频监控终端从摄像头捕获实时的视频信息,压缩之后通过以太网传输到视频监控服务器上. 视频图像采集和打包发送在服务器端完成,图像的接收解包和回放将在客

户端完成. 采集图像数据压缩打包发送接收 系统的硬件设计系统采用模块化设计方案,主要包括以下几个模块:主控制器模块,储存电路模块, 外围接口电路模块,电源和复位电路, S3C4510 主控器模块 主控器模块是整个系统的核心,采用的S3C4510B 处理器.Samsung 公司的S3C45 10B 是基于以太网应用系统的高性价比16/32 位RISC 微控制器,内含一个由ARM 公司设计的16/32 位ARM7TDMI RISC 处理器核,ARM7TDMI 为低功耗,高性能的16/32 核, 系统存储电路模块 主控器还需一些外围存储单元如Nand Flash,和SDRAM.Nand Flash 中包含Lin ux 的Bootloader,系统内核,文件系统,应用程序以及环境变量和系统配置文件等;S DRAM 读写速度快,系统运行时把它作为内存单元使用. 外围电路模块 外围电路主要是以下几个电路,复位电路图,电源电路图以及JTAG 电路, 三、课程设计设备及工具 硬件:UP-NETARM2410-S嵌入式实验仪、PC机、ov511摄像头; 软件:PC机操作系统REDHAT LINUX 9.0、MINICOM、AMR-LINUX开发环境。 四、设计方案 本次课程设计采用arm10开发平台。该平台采用Samsung公司的处理器S3C2410。该处理器内部集成了ARM公司 ARM920T处理器核的32位微控制器,资源丰富,带独立的16KB的指令Cache和16KB数据Cache、LCD控制器、RAM 控制器、NAND 闪存控制器、3路UART、4路DMA、4路带PWM的Timer、并行I/O 口、8路10位ADC、Touch Screen接口、I2C接口、I2S接口、2个USB接口控制器、2路SPI,主频最高可达203MHz。在处理器丰富资源的基础上,还进行了相关的配置和扩展,平台配置了16MB 16位的Flash和64MB 32位的SDRAM。通过以太网控制器芯片DM9000E扩展了一个网口,另外引出了一个HOST USB接口。

嵌入式系统课程设计报告

课程设计 课程设计报告 题目:基于ARM的楼宇对讲系统设计 班级: 姓名: 学号: 指导教师: 成绩: 电子与信息工程学院 信息与通信工程系

目录 摘要..................................................................................................................................... II 1 引言 (1) 1.1 课程设计的目的和意义 (1) 1.2 课程设计内容及要求 (1) 2 系统的工作原理 (1) 3 系统硬件设计 (1) 3.1 ARM主控模块 (2) 3.2 以太网接口模块 (2) 3.3图像处理模块 (2) 3.4 指纹数据处理模块 (3) 3.5音频处理模块 (3) 4 系统软件设计 (3) 4.1 门禁控制程序 (4) 4.2 IP对讲机系统软件实现 (4) 4.3 网络管理 (5) 5 心得体会 (6) 6 参考文献 (6)

基于ARM的楼宇对讲系统设计 摘要 采用模块化设计方法设计出一款基于ARM微控制芯片和Linux操作系统的楼宇对讲系统,该对讲系统通过以太网与楼宇间的各室内机相连,实现了安装在楼道门口的终端机与各室内机的IP对讲,同时将访客的视频信息传输到室内机,并采用指纹身份识别技术实现了门控系统管理。 关键词:嵌入式系统设计;楼宇对讲;指纹识别

1 引言 1.1 课程设计的目的和意义 巩固所学的专业技术知识,培养学生综合运用所学知识与生产实践经验,分析和解决工程技术问题的能力,培养初步的独立设计能力;通过课程设计实践,了解并掌握一般的综合设计过程,训练并提高学生在理论计算、结构设计、工程绘图、查阅设计资料、运用标准与规范和应用计算机等方面的能力,更好地将理论与实践相结合,提高综合运用所学理论知识独立分析和解决问题的能力。再设计完成后,还要将设计的电路进行安装、调试,加强我们的动手能力。在此过程中培养从事设计工作的整体观念。 1.2 课程设计内容及要求 设计基于ARM的楼宇对讲系统。要求对系统功能分析,给出设计思路;系统总体设计,画出系统构成框架图;阐述系统工作流程;画出主要设计部分的电路图。 2 系统的工作原理 通过网络适配器和交换机与用户室内机,管理中心机等组成一个LAN网络。对讲系统安装在每个楼梯入口,可用于呼叫各室内机或管理中心机;当业主欲进入梯道铁门时,可利用对讲系统连接的指纹识别传感器感应进行身份识别,确认身份后电控门锁自动开启;来访者可通过该对讲系统呼叫住户,住户通过室内机,对访客进行对话、视频确认后,遥控开启楼道门控锁;另外管理中心机壳通过对讲系统内置的Web服务器进行系统参数查询设置,如IP信息设置,系统复位,系统时钟矫正等。 3 系统硬件设计 系统主控芯片采用三星S3C2440嵌入式处理器,S3C2440是基于ARM9T的SOC芯片,低功耗、高性能,非常适合嵌入式产品的开发,具有LCD控制器,3通道UART、4通道DMA、HC和SPI总线接口、130个通道I/O口、2个USB主机楼口和1个USB设备接口等资源。基于S3C2440的这些资源,满足整个系统对处理器的要求。 整个系统的硬件结构原理如图3-1所示

嵌入式系统课程设计报告

. 学 生 课 程 实 践 能 力 考 查 题目:温度按键设定、显示、报警系统设计 课程名称:嵌入式系统开发 专业班级: 学生学号: 学生姓名: 考查地点: 考查时长: 4小时 所属院部: 指导教师: 2017 — 2018学年 第 2 学期 金陵科技学院教务 成绩

2017-2018学年第2学期《嵌入式系统开发》实践能力考核班级姓名学号 课程名称嵌入式系统开发课程编号0806504151 授课时间2018年2月26日-- 2018年5月4日周学时 4 学分 2 简要评语 (从完成情况、是 否具备独立开发 能力、是否独立完 成、编程熟练程度 等角度评价。) 任课教师签名: 日期: 温度按键设定、显示、报警系统设计 要求: 1、读取DS18B20温度,在液晶上实时显示,并显示上、下限,初始值上限32,下限26。 2、通过按键可以设置环境温度的上限和下限, WK_UP键按下调节上限,再按下调节下限,再按下调节上限…… KEY1按下加1; KEY0按下减1, 根据上限和下限判断当前温度有没有超出范围。 3、当温度超过上限,LED1隔1秒亮一次。超过下限,LED2隔1秒亮一次。(也可自定义报警方式) 4、串口波特率一律用9600bps。 液晶显示的信息: STM32 test name: xxxxxxxxx Maximum is 32C,Minimum is 26 C The temperature is 29 C,now! (xxxxx是自己的名字拼音)

目录: 第一章.系统要求 1.1设计要求 1.2设计方案 第二章.硬件设计 2.1开发板原理图 2.2 DS18B20模块 2.3按键模块 2.4 LCD显示模块 2.5 LED 模块 第三章.软件设计 3.1程序流程图 3.2程序部分代码 3.2.1主函数、main.c 3.2.2 LED 函数led.c 3.2.3温度代码 s18b20.c 3.2.4键盘代码key.c 第四章.实物效果图 第五章.课程总结

嵌入式课程设计报告

福州大学 课程设计任务书 课程:嵌入式课程设计 题目:简易电子琴 姓名:李仁煌 学号: 011000610 系别:电机电器 专业:电气工程与自动化 年级: 2010 起讫日期: 2013.6.10-2013.7.4 指导教师:王武

目录 1、课程设计目的 (2) 2、课程设计题目和实现目标 (2) 3、设计方案 (2) 4、程序流程图 (3) 5、实物图 (4) 6、程序代码 (4) 7、设计心得体会 (4) 8、附录 (5)

1、课程设计目的 嵌入式系统设计课程设计是与嵌入式系统设计课程相配套的实践教学环节。嵌入式系统设计是一门实践性很强的专业基础课,通过课程设计,达到进一步理解单片机的硬件、软件和综合应用方面的知识,培养实践能力和综合应用能力,开拓学习积极性、主动性,学会灵活运用已经学过的知识,并能不断接受新的知识。培养大胆发明创造的设计理念,为今后就业打下良好的基础。此次单片机课设为了培养我们对单片机应用系统总体方案的设计,硬件的设计,软件程序的设计以及对单片机的调试能力的培养。 2、课程设计题目和实现目标 课程设计的题目为电子琴。实现目标是设计出来的电子琴具有14个能播放14个音调的按键。 3、设计方案 1 按键扫描模块 电子琴设有16个按键作为音符输入。14个按键分别代表14个音符,包括低 音和中音段的全部音符。通过软硬件设计,使系统不断扫描按键接入的对应的引 脚电平的高低,扫描结束时,以变量形式存放扫描结果,当变量显示为有按钮跳 转,转入不同情况的程序段中。 2 播放模块 当系统扫描到播放按钮时,如果判断为播放功能而不是停止播放功能,则启动定时器,通过计时器中断来设置输出PWM波的频率,即可改变蜂鸣器的音调,同时还在中断程序中改变定时器的计数值,从而使定时时间发生改变,在蜂鸣器上表现为发声时间长短。当扫描到的是停止播放功能时,则使定时器停止计数,PWM关闭蜂鸣器停止播放。播放模块是由蜂鸣器和PWM构成,PWM输出一定频率的方波,驱动蜂鸣器发声,蜂鸣器几乎不存在噪声,音响效果较好,而且由于所需驱动功率较小,且价格低廉,所以,被广泛应用。

嵌入式课设报告---基于U盘的LINUX操作系统

华北水利水电学院课程设计报告 课程名称: 嵌入式系统 姓名: 学号: 班级: 专业: 电子信息工程 日期: 2013/7/4

目录 前言--------------------------------------------------------------------------2 1课程设计的目的和要求------------------------------------------------------2 1.1课程设计的目的---------------------------------------------------------2 1.2课程设计的基本要求-----------------------------------------------------2 2前期准备------------------------------------------------------------------2 2.1基本工作原理-----------------------------------------------------------3 2.2 开机载入程序GRUB2-----------------------------------------------------3 2.3 Busybox简介-----------------------------------------------------------4 2.4 根文件系统简介-------------------------------------------------------- 4 2.5 实验平台--------------------------------------------------------------5 2.6 实验流程--------------------------------------------------------------5 3编译linux内核-------------------------------------------------------------6 4制作启动盘-------------------------------------------------------------6 5建立根文件系统------------------------------------------------------------8 5.1 编译Busybox-----------------------------------------------------------8 5.2 建立文件系统-----------------------------------------------------------9 6 系统整合及测试------------------------------------------------------------12 7 实验心得------------------------------------------------------------------12 7参考文献-----------------------------------------------------------------13 附录----------------------------------------------------------------------13

课程设计心得体会10篇实训心得体会

课程设计心得体会10篇实训心得体会 时光飞逝,岁月如歌,繁忙的两周课程设计转眼间就结束了。在 这两周的时光里,我们每一天在寝室―教室-食堂这三点一线的生活里,让我们回忆起了那高中时代的点点滴滴,那久违的充实的而又温馨的气息涌入心头,而这两周时光也成为我在大学两年里最为充实的学习时光。虽说每一天8节课的的安排对于我们大学生来说,有点 __,但我们还是坚持着并沉浸在这课程设计的完美时光之中。 在这两周的课程设计的学习中,前两周我们忙于铜精炼反射炉的 计算,而后一周我们则进行着铜精炼反射炉的图纸的设计。在前一周的计算过程不仅仅检验者我们对有色冶金原理及设备的课程知识的 了解及掌握程度,同时也培养了我们将所学知识同理论实际相结合的潜力。而且,在设计过程中,当我们遇到问题时,我们同学之间相互讨论,相互学习,相互监督,加强了同学之间的友谊,也让我们学会了合作,学会了宽容,学会了理解,学会了做人与处世。 年产2。2万吨铜精炼的反射炉设计使我们也进工程专业的必修功课,也是对我们有色冶金化工过程原理及设备专业知识的综合应用的实践训练,是我们巩固、学习、运用专业知识必要的过程。同时,也是我们由学校迈向社会,从事职业工作前的必不可少的过程,所谓“千里之行,始于足下”,的确是真实的体现出来。透过这次课程设计,我深深的体会到了这句真理的的内涵,我此刻认真的进行课程设计的

任务,学会理论联系实际,学会脚踏实地的迈开人生的一步就是为了明天的辉煌,为明天能稳健的在社会大潮中立足打下了坚实的基础。 透过这次课程设计,我在各方面都有了必须程度的加强,透过对 反射炉的计算及结构图的设计,加强了对铜冶炼知识的了解及掌握,同时,综合运用本专业所学知识及理论和生产实际的知识进行了一次同精炼反射炉的设计工作的实际问题从而培养基加强了我们的学习 独立自主潜力,巩固和扩从了有色冶金化工设备原理及设备等课程的,掌握了铜精炼反射炉的设计方法及步骤,掌握了铜精炼反射炉设计的基本知识,怎样确定设计方案,了解反射炉的基本结构,提高了计算潜力及绘图的潜力,熟悉了规范和标准,同时各科有关的的课程度有了全面的复习,独立思考的潜力也得到显著的提高。 在这次设计过程中,体现出自我单独设计反射炉的潜力及综合运 用知识的潜力,体现了学以致用,突出劳动成果的喜悦情绪。同时,也从这次课程设计中发现了自已平时的学习的不足与薄弱环节,而这些也将是我们今后学习与工作需加强的方面。 在这课程设计结束之际,我衷心的感谢我们的课程设计郭年祥老师,郭老师教学严谨细致,一丝不苟的作风,固然让们倍感不适应,但他的这种态度正是当今社会所需要的,是我们今后学习工作所需具

相关文档
最新文档