ARM经典300问(转贴)

ARM经典300问(转贴)

 

 

第1 章 体系结构
第1 问:
Q:请问在初始化CPU 堆栈的时候一开始在执行mov r0, LR 这句指令时处理器是什么模式
A:复位后的模式,即管理模式.
第2 问:
Q:请教:MOV 中的8 位图立即数,是怎么一回事 0xF0000001 是怎么来的
A:是循环右移,就是一个0—255 之间的数左移或右移偶数位的来的,也就是这个数除以4
一直除, 直到在0-255 的范围内它是整数就说明是可以的!
A:8 位数(0-255)循环左移或循环右移偶数位得到的,F0000001 既是0x1F 循环右移4 位,
符合规范,所以是正确的.这样做是因为指令长度的限制,不可能把32 位立即数放在
32 位的指令中.移位偶数也是这个原因.可以看一看ARM 体系结构(ADS 自带的英文文
档)的相关部分.
第3 问:
Q:请教:《ARM 微控制器基础与实战》2.2.1 节关于第2 个操作数的描述中有这么一段:
#inmed_8r 常数表达式.该常数必须对应8 位位图,即常熟是由一个8 位的常数循环移
位偶数位得到.
合法常量:0x3FC,0,0xF0000000,200,0xF0000001.
非法常量:0x1FE,511,0xFFFF,0x1010,0xF0000010.
常数表达式应用举例:
...
...
LDR R0,[R1],#-4 ;读取 R1 地址上的存储器单元内容,且 R1 = R1-4
针对这一段,我的疑问:
1. 即常数是由一个8 位的常数循环移位偶数位得到,这句话如何理解
2. 该常数必须对应8 位位图,既然是8 位位图,那么取值为0-255,怎么0x3FC 这种超
出255 的数是合法常量呢
3. 所举例子中,合法常量和非法常量是怎么区分的 如0x3FC 合法,而0x1FE 却非法
0xF0000000,0xF0000001 都合法,而0xF0000010 又变成了非法
4. 对于汇编语句 LDR R0,[R1],#-4,是先将R1 的值减4 结果存入R1,然后读取R1 所
指单元的 值到R0,还是先读取R1 到R0,然后再将R1 减4 结果存入R1
A:提示,任何常数都可用底数*2 的n 次幂 来表示.
1. ARM 结构中,只有8bits 用来表示底数,因此底数必须是8 位位图.
2. 8 位位图循环之后得到常数,并非只能是8 位.
3. 0xF0000010 底数是9 位,不能表示.
4. LDR R0, [R1], #-4 是后索引,即先读,再减.
可以看一看ARM 体系结构对相关寻址方式的说明.
3
第4 问:
Q:在程序移植的过程中,什么代码段处于什么样的模式,这可真是一个困扰人的大难题,
有没有一种标志或办法能够识别"代码段处于什么样的模式"
A:读取 CPSR ,任何时候都是可以读.
第5 问:
Q:为什么保护现场时,总是保护 R0-R3,R12,为什么不保护R4-R11
A:请看一看"ARM-thumb 过程调用标准"这个文档.
第6 问:
Q:请问 mov R1,#0x00003DD0 错误ut of the range of operation 是怎么回事情
我就是想IODIR=0x00003dd0,汇编就是
LDR R0,=IODIR
MOV R1,#0x00003dd0
STR R1,[R0]
编译时候说是超出操作范围
A:使用ldr,mov 的操作数为8 位位图数.
第7 问:
Q:"在ARM7TDMI(-S)处理器内部有37 个用户可见的寄存器:"
问题:"用户可见"应该怎样理解 这37 个寄存器是否是37 个不同的物理寄存器,
例如R8 与R8_fiq 应该是两个不同的物理寄存器吧
A:用户可见是指用户可以通过程序操作的.R8 与R8_fiq 是两个不同的寄存器.
第8 问:
Q:USR 模式,SVC 模式,IRQ 模式分别有哪些限制
A:对于外设操作限制与芯片设计有关.USR 模式不能设置CPSR 寄存器.
用户模式下无SPSR 寄存器,代码可以为ARM,Thumb.
第9 问:
Q:请问"在初始化堆栈时就决定了工作模式"是什么意思 如何决定工作模式的
A:设置CPSR 寄存器.
第10 问:
Q:请问:ARM 汇编程序设计中所谓的"文字池"作何理解
A:可以理解为常量数组,文字池中保存的是常量,这些常量可以是正常的常量,也可以是
地址.
4
第11 问:
Q:为什么在中断向量表中不直接LDR PC,"异常地址".而是使用一个标号,然有再在后面
使用DCD 定义这个标号
A:因为LDR 指令只能跳到当前PC 4kB 范围内,而B 指令能跳转到32MB 范围,而现在这样
在LDR PC, "xxxx"这条指令不远处用"xxxx"DCD 定义一个字,而这个字里面存放最终异
常服务程序的地址,这样可以实现4GB 全范围跳转.
QDR 不是可以全空间跳转的吗 《ARM 微控制器基础与实战》程序清单5.3.
ADR 伪指令通过设置指令缓冲池才能实现全范围跳转,而LDR 指令则只能实现4KB 范围
跳转.
第12 问:
Q:ARM7TDMI-S 和ARM7TDMI 有何区别
A:ARM7TDMI-S 是ARM7TDMI 的可综合(synthesizable)版本(软核).
对应用工程师来说,除非芯片生产厂商对ARM7TDMI-S 进行了裁减,
否则ARM7TDMI-S 与ARM7TDMI 没有太大的区别,其编程模型与ARM7TDMI 一致.
第13 问:
QCD 伪指令的疑惑.
"StackUsr DCD UsrStackSpace + (USR_STACK_LEGTH - 1) * 4"
这句话是什么意思 DCD 后面的程序标号或数字表达式是何意
A:它的内容是初始化递减堆栈的最高地址,看《ARM 微控制器基础与实战》2.3.2 节.
5
第2 章 编译器与语言
第14 问:
Q:00254: Unimplemented RDI message 是什么错误提示 我的设置连接都正常,是不是
芯片烧了
A:是JTAG 的问题.可以先使用ISP 操作试试就知道了,如果能ISP,说明LPC2104 没有损
坏,还能正常运行程序.
第15 问:
Q:请教:我在调试程序的时候在AXD 中出现这样的提示信息:
RDI Warning 00159:could not open specified device port.
我是根据配套教程的步骤设置的.
A:请按照光盘/easyarm_drive/readme.txt 安装驱动程序.
第16 问:
Q:我用实验程序运行经常出现下列信息! 程序不能下载到目标板.
Warnning! interrupt vectors data is not correct!
Program you downloaded can not run freely!
A:1.仿真器配置一定要正确,即"EasyARM Configuration"设置窗口中的"FLASH"项中选择
"Erase Flash when need";
2.向量表累加和要为0;
3.可以先在RAM 调试一个程序(运行),然后STOP,再使用File->Load Image...加载要
下载到FLASH 的调试文件.
第17 问:
Q:在ADS 中是否可以进行软件调试基于UCOS-II 的程序
A:ADS 软件调试只能调试ARM 的内核,不能调试外设.但是取消 PLL 锁定检测后,
可以调试任务切换,最终到空闲任务上.开始移植时软件仿真是最好的工具.
第18 问:
Q:ARMulate 软件是干什么的 2104 不是用EasyJTAG.dll 来仿真吗
A:软件仿真只能仿真 ARM 核.
第19 问:
Q:有关LPC2106.INC 的问题.我无法在project 引用lpc2106.inc 文件,只能引用lpc2106.h
文件, 这是什么原因 且当我的主程序用汇编编写时,不能引用lpc2106.h,用
lpc2106.inc 则无法加入project,请问汇编器应如何设置
A:不用加2106.inc 只要该文件在你的工程文件夹中,就可以直接在汇编程序的开始处加
6
"include 2106.inc".
注意:该文件是汇编文件定义的头文件,定义内部寄存器.
第20 问:
Q:入口点是什么意思 我在使用LPC2106 上移植UCOS-II,每次MAKE 时总是提示我
Image does not have an entry point,可是我是把光盘的vetctors.s 复制过来的,
而且仔细看了看,已经声明了ENTERY,这是怎么回事
A:需要在ADS 中设置入口.
第21 问:
Q:请教:如何定义不被初始化变量
A:让编译器不知道有这个内存地址即可.
A:如用分散加载文件分配RAM 故意预留一部分RAM 不分配,用它来存您不需要初始化的东
西.或者不调用编译器提供的启动代码,不过这样可能编程会麻烦一些.
第22 问:
Q:我直接通过JTAG 口下载EasyArm 板带的Ext1_test 程序到ARM 中,出现中断向量的告警:
interrupt vector is not correct arm is not running freely.
果然复位后芯片不能运行.但是我用串口下载后芯片能正常工作,中断也行的.
并且我用JTAG 仿真的话,芯片能正常工作,中断也行的,唯独JTAG 口下载不行.
不知道是什么原因
A:仿真器配置中要设置Erase Flash when need.也可以这样试试:
1.可以先打开一个工程在RAM 中调试运行;
2.stop 程序;
3.使用File->Load Image…重新加载Ext1_test 生成的*.axf 文件.
Q:仿真器配置中我是设置了Erase Flash when need,但照你说的话,那不是在RAM 下调
试吗
在RAM 下调试我是可以的,但是下载后出现interrupt vector data is not correct.
我又看了几篇文章,是不是跟中断向量表的累加和不为零有关系啊
A:是的,是向量表的累加和不为零.
因为如果用ISP 下载能运行,说明向量表的累加和已为零,而用JTAG 下载不能运行的情
况可能是 没有正常下载代码.先在RAM 中调试,目的是为了后面正确下载程序到
FLASH.
第23 问:
Q:用Scatter 怎样将某个函数或文件定位在Flash 的某个位置
A:参考
http://www.zlgmcu.com/download/downs.asp
ID="1009"
7
第24 问:
Q:我在仿真时遇到这样的提示:
Error, Flash is protected by user configation!
怎么写到flash 里面呢
A:看配套《ARM 微控制器基础与实战》附录一.
第25 问:
Q:我在移植实验中想到了两个问题,如下:
1.Debug 和Release 以及DebugRel 有什么不同,为什么在作2104 移植实验时,要用
Release
2.在Release 中为什么要将RW Base 设置为0x40000040 我将其设置为0x40003000,
为什么不能工作
A:都只是一个问题,内存空间的使用,因为跑OS 要比较大的内存空间,所以要腾出点地方.
第26 问:
Q:请问没有MMU 的ARM 芯片是否支持使用malloc()函数动态分配内存
A:是否支持malloc()函数与芯片没有多大关系,主要与编译器有关.
Q:再问:如果没有操作系统支持呢
A:也支持.
第27 问:
Q:在I2C 实验程序中,我想查看数据缓冲区DataBuf 的值,怎么查看
A:watch 窗口或鼠标停留在要查看的变量名上.
Q:我查询的是写入DataBuf 缓冲区的值,鼠标在上面根本就不会出现他的值,即使在watch
中加入,
结果也是"name not found".
A:变量被优化,调试时可以把该变量定义为全局变量查看.
第28 问:
Q:仿真软件和2104 开发板连接不上
DBE Warning 00041:
!An unspecified Debug Toolbox call failed
电源和开发板都连好,错误和没接开发板一样,驱动也安装了,安装时按确定键时,软
件很长时间才有如上反应,请帮忙
A:1.并口是否正常
2.在其它操作系统(如98)下或其它台式PC 下试试.
第29 问:
Q:如何生成32 位hex 文件
8
我在Release Setting->ARM fromELF->Output Format 中设置为Intel 32bit HEX,可
是好像没有生成hex 文件
A:试试这种方法:
Target-->Target Setting-->ost Link 中选择"ARM fromELF"加上你上面设的应该不
成问题.
第30 问:
Q:请问关于settings 中r0 base rw base 的意思
A:ro:read only,rw:read and write.
第31 问:
Q:编译成功后的信息第一行,code,R0 data,RW data,ZI data,debug 分别代表什么
A:R0 只读段,即程序代码空间;
RW 可读/写段,即数据变量空间;
ZI 清零变量段,即需要清零初始化的数据变量空间.
第32 问:
Q:如何在ADS 里面看任务执行的一些情况 比如堆栈.
A:多任务环境下的堆栈,内存等信息需要调试软件的支持才可以实现.
ucos 下有一个统计功能的模块可以间接实现部分功能.
第33 问:
Q:请问向flash 烧数据时出现:exceeds flash limitation 请予赐教!
A:要写入的flash 地址超过了范围.如果不是代码太大的问题,可以检查scf 文件是否正
确.
第34 问:
Q:在LPC2214 之类的芯片中如何实现数组的绝对地址定位,比如51 的_at_的用法.
A:*((char*)0x40000300)类似访问
Q:谢谢,但这样做就无须定义数组变量,访问也不便,还有高招吗
A:可以使用分散加载.
第35 问:
Q:请问 ADS 编译错误"L6221E:Execution region ER_RO overlays with Execution region
ER_ZI" 该如何解决
A:请用我们网站上的工程模板试一试,最大的可能是因为你的RELEASE 或者DEBUG 选项里
面没有正确设置,按照参考《ARM 微控制器基础与实战》上面的设置,是不会有这个问
题的.
9
第36 问:
Q:请教一下:将程序写入flash,再用从JTAG 方式调试写入之后再复位程序没什么反映.
看了很多以前的帖子,说memmap 寄存器要为1,我用的是一个很简单的控制led 的例子,
改动了参数之后写入flash 的.在这个程序的vectors 中找不到关于memmap 寄存器操作
的部分啊,这是怎么回事,该怎么办呢
A:《ARM 微控制器基础与实战》上附录有"常见问题",列举了几点程序写到FLASH 不能运
行的原因. memmap 操作可以在target.c 中的TargetResetInit()函数内添加.
第37 问:
Q:HEX 文件.EASY2100 配套《ARM 微控制器基础与实战》上讲:把项目编译成HEX 文件,
我不会呀,咋办
A:Target-〉target settings 设置Post-linker 并且设置Linker-〉fromELF.
Q:再问:我用的是光盘里的例子,打开工程项目里是DebugInARM.DebugInFlash.
RelInFlash.不是《ARM 微控制器基础与实战》上的DebugRel 呀,我都照《ARM 微控制
器基础与实战》上设置的,可用ISP 下载,提示无法找到HEX 文件.
A:光盘上的例子是用专用工程模板建立,已经设置好参数,与默认模板不同.
第38 问:
Q:EasyARM2100 开发板如何通过JTAG 接口下载到Flash
我在用EasyARM2100 开发板时JTAG 接口不能进行Flash 中的调试(DebugInFlash),但
是可以在RAM 中调试(DebugInRAM),且通过ISP 编程可以写入Flash.
通过JTAG 接口进行DebugInFlash 调试时,总是出现如下提示:
Flash Sector 0 write failed!
Warnning interrupt vectors data is not correct!
Program you downloaded can not run freely!
请问是什么原因 我该如何办
A:仿真器设置选项有一个允许擦除FLASH 的选项,选择它.
第39 问:
Q:我发现程序在RAM 调试时(RO=0X40000000) OK,但是JTAG 下载到FLASH(RO=0X00000000),
显示如下:
The session file 'c:/Documents and Settings/jan/default-1-2-0-0.ses'
could not be loaded.
A:这是ADS 自身的问题,请不要通过IDE 运行AXD,而是通过开始菜单运行,然后Load 调
试文件调试.
第40 问:
Q:我有几个问题想问问大家.
10
调试主机负责对ARM 源程序进行编译链接,最好用什么样的高级语言对ARM 源程序进行
编译链接 使用调试程序(如AXD)进行JTAG 调试,AXD 是什么调试程序,是否是类
似什么软件之类的 到哪能下载AXD 的调试程序呢 怎么样进行AXD 程序进行JTAG 调

如何通过JTAG 仿真器发送到目标机上呢
对于单片机的调试,都用到了什么软件
都个有什么作用呢
A:可以使用 ADS1.2,Keil C 也支持.AXD 是ADS 的一个组件.
您可以在本公司网站下载 EasyARM2100 开发套件快速入门看一看.
第41 问:
Q:EasyARM2100AXD 调试时出错,故障现象:
按照光盘上的方法设置好ADS1.2 后打开光盘上的expamples/gpio/c/LedDisp 的工程文
件(从光盘上拷贝到硬盘,已去处只读属性).
编译通过后,按Debug 按键运行调试,进入AXD.按Go 按键,EasyARM 没有反应.再按
Stop 按键.
AXD 弹出两个确认框窗口:
"No disassembly could be read at the requested address".
如果进入AXD 直接按Step 按键,也是会弹出同样的两个确认框.
软件是光盘上的,没有经过任何改动.光盘上的程序试过4,5 个都是这种情况.
AXD 的设置是按照光盘上的说明设置的.
EasyARM 上的JP8 是断开的.ADS 在出现这种问题后重新安装过,故障依旧.
出现这个问题前,可以调试.只是单步的时候感觉比较慢.差不多1-2 秒钟才能单步一
次.
A:原因找到了,是芯片被加密了,无法写入新的程序,用FLASH ISP 清除后解决.
加密后JTAG 完全不能控制芯片,否则可能被解密.
第42 问:
Q:我板上的lpc2214 开始可以在线编程,只搞了两三次可以把文件写进去.但我发现P0.14
未置低电平时也进入ISP 模式,烧入的文件原来可以ISP 下载到2014 开发板中运行的.
最后只能读芯片的一些ID,载文件都不能进行.以下是对整片ERASE 时,对串口的捕获,
命令返回是19.
Synchronized
Synchronized
OK
11059
OK
U 23130
0
P 0 14
0
E 0 14
11
19 configure tar... -> ARMUL , 只能仿真ARM 核外设不能仿真.
第48 问:
Q:为什么盘中的工程会出错啊
A:文件的只读属性去掉了吗
第49 问:
Q:您在2104 的《ARM 微控制器基础与实战》中提到ucos 与应用代码分开编译,在分开编
译调试成功之后,最后要将代码统一固化到芯片中.在最后一步需要注意什么 统一编
译时感觉要改动很多东西,有没有什么最简单的办法 能否详细介绍一下方法 多谢!
A:使用我们的工程模板,可在本公司网站下载.其实不分开编译也可调试.
http://www.zlgmcu.com/tools/kaifaban/EasyARM2104.asp
的EasyARM2104 开发套件快速入门和LPC210...
第50 问:
Q:请问,我的2104 板子,通过EasyJTAG 仿真时,在AXD 上没有文件,而且出现这样
"Error, Flash is protected by user configation!"
的提示,这是怎么回事啊 在AXD 应该打开什么类型的文件啊 谢谢啦!!!!
A:在仿真器的配置窗口设置仿真器允许擦除FALSH.
AXD->Options->configure target->configure->erase……
13
第51 问:
Q:关于arm 汇编语言跳转指令的特殊用法.有如下两条跳转指令:
beq lablef
beq lableb
其中lable 为某段程序的标号,beq lablef 表示向前跳转到与当前指令最接近的标号
lable 处执行,而beq lableb 表示向后跳转到与当前指令最接近的标号lable 处执行.
在arm 汇编中有定义这样的用法吗
A:没有.
第52 问:
Q:我将一段程序从flash 从复制到了RAM 中,但是因为混合编程中不能直接向PC 寄存器中
赋值来实行跳转,这样我该如何跳转到这个RAM 中的地址呢
A:用函数指针.可参考IAP 例子.
第53 问:
Q:我想详细的了解一下ADS 开发工具中的stack.s ,heap.s 和startup.s 中代码的含义,
各位高手推荐本书或给解释一下
A:开发套件用户指南的第3.1.3 节有说明.
stack.s 定义了系统模式堆栈的起始地址.
heap.s 为初始化库函数的堆,是按ADS 的编译器要求编写的.
startup.s 向量表及初始化代码,是根据CPU 来编写的.
第54 问:
Q:我不知道所选择的C 文件到底是用ARM 还是THUMB 编译的,请大侠指点!
A:看配套《ARM 微控制器基础与实战》7.1,7.2,7.3 节.
第55 问:
Q:我重新建立了一个工程,没有用模板,TEST.C 程序在编译的时候提示OS_EVENT 没有申
明,但是我看了代码,TEST.C 中包含了CONFIG_EX.H,而congif_ex.h 中又包含了
include_ex.h, include_ex.h,这两个头文件又包 含了ucos_ii.h,而OS_EVENT 是在
ucos_ii.h 中申明的,不知道为什么会出现这种错误,能不能给我一个比较合理的目录
结构
A:请参考我们光盘的目录结构.最好使用我们的工程模板.
第56 问:
Q:请问,我现在做2114 的产品开发.出现以下问题,特向您请教! 问题:
我们开发的产品要采样,采用周期固定.于是我们采用timer0 进行时钟触发,利用触发
中断程序 每隔10 毫秒采样一次并显示波形.这都能很好的进行.但是在中断程序里
面对几个全局变量赋值, 跳出中断后却不能使用该全局变量.很是头疼!请赐教!!
14
框架如下:
uint8 a; //全局变量
void __irq funtimer0()
{
...
a=0; //在中断函数里面对全局变量赋值
...
}
void fun1()
{
uint8 i;
i=0;
.......
i=a; // 出错位置,在调试过程中运行到当前位置,鼠标移动到变量a 上
// 显示数值是0,但是不能传给i,i 的值不会随该命令改变.
......
}
因此,我在中断函数中采集到的数据放到全局数组中.采集完成关中断后在用户模式下
的程序中来处理该数组,但是该数组中的数据也不能使用!全局数组变量占1000 个字节,
IRQ 堆栈长度是256.
A:全局变量用volatile 声明.
第57 问:
Q:在AXD 里打开Debuger Internals,在Variable Name 里为什么没有PINSEL2,ADDR,ADCR
等寄存器 要在哪里设置
A:有些片内外设寄存器是不能读出,《ARM 微控制器基础与实战》上的P33 页有说明及处理
方法(在Memory 窗口写入相应寄存器地址).
第58 问:
Q:请问不连easyArm 板可不可以直接软件调试程序
我是指如果想直接调软件部分,能不能在ads 或axd 里直接调试
A:这和板子没关系啊,你直接选ARMulate 不就行了,注意把等待PLL 配置完那条语句屏蔽
就可以啦!
第59 问:
Q:AXD 里面出现 "RDI Warning 00159: Could not open specified device port"
谁能告诉我这个是问题啊我一直搞不懂啊,全部是按照《ARM 微控制器基础与实战》第4
章上配的图做的啊,但是就是不能仿真啊.
A:请先按照光盘的easyarm_drive/readme.txt 安装驱动程序.
15
第60 问:
Q:1.在《ARM 微控制器基础与实战》的2.6.3 节有说到"浮点数寄存器(F0-F7...)",2104
是否具有这些寄存器
2.如果EasyArm 不支持浮点运算,而我的程序需要用到浮点运算,请问可以实现吗
A:1.没有.
2.用C 就可以用浮点运算.
第61 问:
Q:EASYARM2104 的例子程序怎么都是调用C 写的程序,汇编那个怎么没用的啊
A:按如下步骤进行处理:
1.在项目管理窗口中删除原来的所有文件;
2.在项目管理窗口中增加汇编文件*.S;
3.编译链接,调试.
第62 问:
Q:请问版主:在AXD 调试软件中,我单步运行到一定时候,我想让自己编的软件从复位处
重新运行, 在AXD 软件中,EXECUTE 栏目中有单步,连续,运行到光标处等功能,但
无复位功能,如果要实现此功能,如何操作
A:我也没有发现,目前只能用重新装载的操作实现.
第63 问:
Q:在AXD 调试中,通过从jtag 接口,连接上lpc2106,出现如下信息:
TKSimulator for ADS, V1.2, 2003/08
Software Supplied by: ZLGMCU
ARM7TDMI-S, Little Endian
在从file|load imgage...文件,出现两种情况:
1.正常,完全能调试;
2.出现问题,如下:
RDI Warning 00254: Unimplemented RDI message
请问,这是错在哪里 如何解决 谢谢!
A:可能是电源或其他接插件接触不良引起.
第64 问:
Q:请教几个问题:
1.移植中底层接口里的__swi 关键字在SDT 中能用吗
2.为什么在勘误文档中时钟节拍服务子程序里去掉了开中断及关中断的宏
3.时钟节拍中断的优先级应该设为最高吗
16
A:1.不知,请自己看一看软件自带文档.
2.因为中断服务程序中肯定是关中断的.
3.不必.
第65 问:
Q:arm 汇编中的中括号是什么意思 比如下面的例子中括号是什么作用呀
[ PLLONSTART
ldr r0,=PLLCON
ldr r1,=((0xe8启动AXD.现象:数码管能
显示不断变化的数字0--F,但是AXD 的连接失败,提示"DBE Warning 00041: ....".
重复试了几遍,现象相同.
请教原因以及对策.
A:刚才把我机器的Win2K 系统的用户属性从"owerUser"修改为"Administrator"就没
问题了.可能是ADS/AXD 安装的时候用了Administrator 权限,在"owerUser"下工作
有问题吧.
如果哪位老兄有类似问题,不妨试一下这个方法.
第67 问:
Q:在Init.s 中有这样一段:
Reset
BL InitStack ;初始化堆栈
BL TargetResetInit ;目标板基本初始化
B __main ;跳转到c 语言入口
谁知道__main()函数的具体内容
假如我不需要调用库函数的话,是否可以改为B main
A:看调试是汇编代码里有__main(),组成成分与一些链接选项有关.
可以.但是全局变量初始化不了.
17
第68 问:
Q:我在C 中嵌入这样一条语句
__asm
{
MRS R4,CPSR;
STMFD SP!,{R4};
ORR R4,R4,0x80;
MSR CPSR_cxsf,R4
}
会出新报错"illegal write to sp"版主和各位大侠有什么办法解决阿
A:嵌入汇编不能使用SP.
第69 问:
Q:请问 ADS 如下的编译错误是什么意思
L6221E:Execution region ER_RO overlays with Execution region ER_ZI
A:程序段内存分配可能有问题,RO(只读),ZI(0 初始化)
第70 问:
Q:在axd 中有没有运行程序的时间计算器 keil 中就有那样的东西.
A:有的,不过不是时间而是执行周期,可以换算成时间.在debugger internals 中,具体
可以参考帮助文档.
第71 问:
Q:我最初的init.s 中没有加入heap 的分配和__user_initial_stackheap 函数,结果程序
跳到SWI 中死循环.我把他们加入后就好了.或者不加入他们,把B __main 改为B main
也可以.请问何解 另外,就算目标板会陷入死循环,但是用软件仿真却可以正常运
行.何解
A:堆的位置没有分配到有效的RAM 中.
第72 问:
Q:在ARM 汇编语言中,对立即数的有要求,我记得原来没有这样一说了.现在反而糊涂了,
用立即数时候,很小心很忌讳,不回象51 下随心所欲的使用了,有对立即数熟悉的朋友
站出来给大家释疑.
A:如使用"非法数据可以使用lrd 送到寄存器"的方法.
首先在存储器中定义一个常量,再ldr 进去,编译器是这样弄的.可以看下面语句反汇
编的区别;
int z="0x101";
int z="0Xff";
18
第73 问:
Q:请教各位:我在AXD 中单步运行一段程序后,想回到程序的开始重新运行,除了重新加
载,
还有其他方法或按键
A:你的程序有多大 程序在Flash 运行点击Reload Current Image 也不需要1 秒吧~
或在代码窗口Set PC="0"
第74 问:
Q:在《ARM 微控制器基础与实战》程序清单6.22 的376 页的OSIntCtxSW_1 中:
LDR R4, [R6]
ADD SP, R4, #68
LDR LR, [SP, #-8]
MSR CPSR_c, #(NoInt | SVC32Mode)
MOV SP, R4
LDMFD SP!, {R4,R5}
LDR R3, =OsEnterSum
STR R4, [R3]
MSR SPSR_cxsf, R5
LDMFD SP!, {R0-R12, LR, PC }^
请问高手DMFD SP!, {R0-R12, LR, PC }^是不是恢复新任务工作寄存器和工作模式,
LR 寄存器一并得到恢复,那么ADD 指令后面的 LDR LR, [SP, #-8] 指令是不是可
以去掉
A:两者恢复的是两个不同处理器模式的LR.
第75 问:
Q:既然option 页中的Image entry Point 填入的是调试入口地址,那么在实际的程序运行
当中它是不会 覆盖代码中的ENTRY 入口声明的,对吗 仅仅是为了调试的方便.
A:Image entry Point 优先.其实代码中的ENTRY 是为了确保代码不被优化掉.
第76 问:
Q:我想使用标准C 语言的库函数,比如memset 在string.h 中有定义,可是我直接包含
#include , 但是编译没错误,运行确有错误,应当怎么设置
A:请使用最新的工程模板
第77 问:
Q:软件中断是不是必须由SWI 指令触发
A:可以直接用你定义成软中断的函数名啊.比如:
19
__SWI(0x12) void myswi(void); // 声明函数
__asm // 调用方式1
{
swi 0x12
}
myswi(); // 调用方式2
第78 问:
Q:《ARM 微控制器基础与实战》程序清单6.9 的程序是在哪里被调用的
_user_initial_stackheap
LDR r0,=bottom_of_heap
MOV pc,lr
A:__main.千万别删哟, 否则出大事的.
第79 问:
Q:"LDR R0, =PINSEL0" 中"="是什么意思 这语句是取地址还是取地址中的内容呢
A:这是LDR 伪指令,可用来加载32 位立即数或地址,LDR R0,=PINSEL0 是将PINSEL0 的地
址加载到R0 中.
第80 问:
Q:我不明白"SWI 0"和"SWI 0X123456"这两条指令中的0 和0X123456 中有何用.
有没有应用SWI 的具体例子让我看看
A:那是特定的中断入口地址,见ADS_DeveloperGuide_D.pdf 下的swi.
第81 问:
Q:SWI 的功能表吗
A:SWI 的功能表由swi 异常服务程序决定.很多时候由编程者自己决定.
第82 问:
Q:请问:我在实验您的原代码进行ucos 移植时用的是例1,但是在按照图7.17 设置处理
器的仿真器模式时enable comms channel view 和semihostin 项为不可激活状态.为
什么,能否给一点提示
A:在一些仿真器上使能了它们会影响swi 异常处理程序.
第83 问:
Q:请问"Unimplemented RDI message"这个出错提示是什么意思啊
20
还有,有的时候当我用axd load 一个.axf 文件时,常常loading 的没完没了,这是怎
么回事啊
A:Unimplemented RDI message:为命令操作失败,需要重新连接.
下载不结束为出现不正常现象,请重新连接并下载.如果每次都出现该现象请联系我们
的技术支持.
第84 问:
Q:各位高手好,我是ARM 初学者我在程序调试中"LDR PC,[PC,R2]"命令执行后PC 为什么
=0x0000000c, 在这条命令执行前PC+R2 地址上的值是0x0000000c 吗
A:要使用软件仿真.0x0000000C 是预取中止了.
Q:请问:ARM7 在初始化CPU 堆栈时,寄存器CPSR 和CPSR_c 有什么关系 CPSR_c 是在那里
定义的
A:这是MSR 指令的语法,"_"后部分指定CPSR 的域,请参考《ARM 微控制器基础与实战》
上关于这条指令的说明.
第85 问:
Q:软中断SWI 作底层接口的问题.以下函数为啥要通过软中断调用,可以直接调用吗
OS_TASK_SW(),
_OSStartHighTdy(),
OS_ENTER_CRITICAL),
OS_EXIT_CRITICAL(),
A:在用户模式或Thumb 状态不能直接调用.
第86 问:
Q:ARM 的一条指令是32bit 长, 但有时一个立即数也是32bit, 这是如何解释的
A:指令中使用的立即数需要时8 位数移位获得,并非所有数都可以.
第87 问:
Q:请教:全局变量的值在复位(不断电)后会不会自动清零 (用光盘自带的启动代码)
A:在C 语言中一般会会初始化0 或用户指定的值,但这不是硬件自动的.
第88 问:
Q:the setting files for *.mcp is locked!是什么问题
A:文件属性只读.
第89 问:
21
Q:请问,关于printf() 在ads 中怎么用不了 谢谢!
A:请用我们我们网站上下载2104 的工程模板,它解决了这个问题.
即使这样,也不能真正使用prinf.您还需要自己编写一些底层函数才能使用,详细参
考ads 自带的ADS_CompilerGuide_D.pdf.
第90 问:
Q:swi 的功能号是如何来的 它和LR 寄存器的值是何关系
如《ARM 微控制器基础与实战》程序清单6.13
LDREQ R0,[LR,#-4] ;BICEQ R0,R0,0xff000000
ADREQ R0,[LR,#-4] ;用来读SWI 的代码
BICEQ R0,R0,0xff000000 ;是ARM 方式进入,取低24bit
第91 问:
Q:请问在TargetInit()中函数开始会执行srand((INT32U)TargetInit),它是做什么用的
A:ex1 用它来产生随机数种子的.
Q:请问:我建立的工程中,所有源文件与2104 附带的光盘例子源文件相同,编译链接也一
切正常, 可就是不能到板子上跑!
提示错误是:向量中断有错误,无法自由运行!!
这是怎么回事 相同的源文件,加在你的工程里,正常;加到我的工程中就出错!
我创建的是ARM 可执行映象.
A:vector.s 你自己的吗 如果是要计算向量去的累加和了.
第92 问:
Q:请问:vectors.s 中"DCD 0xb9205f80" 的0xb9205f80 在实际运用中需要改动吗
A:不需要更改,除非改动了向量表中的指令代码.
第93 问:
Q:请问,为什么queue 数据队列,《ARM 微控制器基础与实战》上给画成了环形
A:因为头跟尾的指针指向一个地址,队列逻辑上是环状的.
第94 问:
Q:有没有人成功的把一个数据定义到程序空间里 各种方法我都试了,是不是有什么编译
开关
A:使用const 修饰,定义变量时带初始化值,要定义为全局的变量.
第95 问:
Q:ads 里没有CODE 关键词,怎样使定义的字符串数组不占用RAM 空间
22
A:const unsigned char string[]
第96 问:
Q:在例程中TIME_test 中的TIMEOUT 当写入时提示:
Warnning! interrupt vectors data is not correct!
Program you downloaded can not run freely!
我不知怎样改设置,哪位提醒一下
A:中断向量表的校验和不为0,用AXD 看0 地址的数据(32 位方式),自己加一下.注意把
高于32 位的部分去掉.
第97 问:
Q:请教各位:我做TIMEOUT 实验(2104 板),Make 通过,Debug 时出现了如下错误提示:
Warnning! interrupt vectors data is not correct!
Program you downloaded can not run freely!
设置Link:ARM Link
r0 base:0x00000000
rw base:0x40003000
image entry point:0x00000000 其它的没变!!
而我使用ISP 完全可以下载而且可以运行!这可以说是设置问题,但是我实在找不到!
怎么办
A:请看一看配套《ARM 微控制器基础与实战》附录1,ISP 软件可能对它进行了处理,而JTAG
没有特殊处理
第98 问:
Q:*(volatile unsigned int *)是什么意思 例如*(volatile unsigned int *)addr 具体
是什么意思
A:分开来看,(volatile unsigned int *)就是定义一个可变的无符号整形指针,前面的那
个*就是取起内容.
第99 问:
Q:如何理解#define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000))
A:宏定义,参考C 语言的书籍.
(volatile unsigned long *) 0xFFFFF000 将0xFFFFF000 强行转换为指针,然后 *(指
针) 即可对此地址进行访问.
第100 问:
Q:在异常处理向量表的设置中,为什么不直接将异常向量的入口地址写入PC 中呢,为什么
非要用什么DCD 这些伪指令,到底有什么用啊
A:为了保证任何时候其累加和为零,不然改一次程序就要计算一次.
23
第101 问:
Q:单步调试i2cINT.C 在ISendStr 中启动总线后,程序怎么又跑到vectors.o 中,进行初
始化了呢
A:由于VIC 的限制,程序不能在0x18 停下来,否则执行非向量中断.如果没有设置,则非
向量中断为0,将从0 地址执行.
建议:有中断时不要单步执行程序,可以手动暂时关中断或设置断点代替单步.
(编者注:下载最新的驱动可以解决这个问题)
第102 问:
Q:请教:如何修改 ADS 的启动代码,从__main 到main,按道理应该有一个文件,修改这
个小文件, 就可以修改 启动代码.
A:__main 是ADS 运行库,最好不要修改,要是不使用库就不要用main()函数,起个别的名
字.直接跳转过去就行了.
详见:《ARM 体系结构与编程》P328.
第103 问:
Q:我在JTAG 仿真时出现的对话框,提示:
Warnning! interrupt vectors data is not correct!
Program you downloaded can not run freely!
A:参见《ARM 微控制器基础与实战》附录一第一个问题的第二部分,选择源代码的启动代
码文件夹下的vectors.s,并参照《ARM 微控制器基础与实战》图7.11 设置.
第104 问:
Q:初始化代码中分配堆栈的问题
MSR CPSR_c, #0xd3 ;进入特定的处理器模式
LDR SP, StackSvc ;给当前处理器模式的堆栈指针赋值,这只是一个值而已,
;他在接下去的DCD 语句赋值
SvcStackSpace SPACE SVC_STACK_LEGTH * 4
这个语句开辟一个SVC_STACK_LEGTH * 4 大小的内存,SvcStackSpace 是这块内存的标
号,我想应该就是内存的首地址,这样应该好理解了.
StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
这个语句就是把这个首地址加上堆栈大小值.
A:计算出堆栈指针来,我想这个堆栈是向下生长的,所以SP 赋值的是堆栈地址最高的那个.
第105 问:
Q:请问启动代码中这句是什么意思
24
__user_initial_stackheap
LDR r0,=bottom_of_heap
MOV pc,lr
;/* 分配堆空间 */
AREA Myheap, DATA, NOINIT, ALIGN="2"
bottom_of_heap SPACE 256 ;库函数的堆空间
我的问题是:
1.这个函数在哪里被调用
2.赋值给r0 以后就完事了 r0 起什么作用
A:堆和栈的分配函数,由ADS 提供的初始化代码调用,具体参考配套《ARM 微控制器基础
与实战》的相关部分.
第106 问:
Q:2104 的启动代码是否适用2124 呢
网站上下载的那个easyarm2104 工程模版里面写着arm executable imag for lpc21**,
是否说也适用2124 呢 如果不行,哪些地方需要修改 希望能够指点一下!
A:您可以下载2100 的工程模板.
第107 问:
Q:我在用ARM 的IAP 功能,要把已经烧到flash 中的数据写到RAM 中,我是这么写的:
uint32 *q,data;
q = 0x00006000;
data = *q;
这是要读的flash 的起始地址,但是第二句编译出错,我想应该是C 编译器不许给指针
直接赋值, 我用汇编解决了这个简单的问题,但是怎么用C 来解决呢
A:q = (uint32 *)0x00006000;
第108 问:
Q:问一个有关汇编的基础问题.
例程: ANDS R1,R1,#0x0400
BEQ WAITOK
请问 ANDS 是如何影响标志位的,而BEQ 判断的是那两个操作数相等时执行
A:R1&0x0400 => R1,若结果为0(即R1 为0),则标志位Z=1.
当Z=1 时,BEQ WAITOK 有效执行.
第109 问:
Q:请教:在ADS 中怎么给某个变量确定固定物理地址
就是类似KEIL 中的 XDATA xxx _AT_ 0x4456 的功能.
A:使用分散加载机制,mem_c.scf 等就是例子.
25
第110 问:
Q:哪里有介绍ARM 的C 语言编程的
A:其实大多数嵌入式系统的C 语言都差不多,可找一本写嵌入式C 语言的书即可.
第111 问:
Q:请问在系统复位后首先执行的是否为Boot Block 的中断向量
然后由boot block 里面的程序决定是执行用户程序还是ISP 程序.
那么这时启动的boot block 里的中断向量表和用户程序里的中断向量表是如何在flash
里安排的
在《ARM 微控制器基础与实战》上看到的是复位后boot 扇区的最低64 字节出现在
0x00000000 区域,那用户的中断向量表应该在哪个区域
产品中一般为0x00000000,在开发板中重启后实际为boot block 的中断向量地址,对

A:看一看3.3.6 节.产品中一般为物理0 地址处.
第112 问:
Q:《ARM 微控制器基础与实战》上有一段程序:
uint32 i;
i = VICIRQStatus;
i = IOSET;
请问:为何先要读取VICIRQStatus 的值,才能读IOSET 的值
A:读出VICIRQStatus 只是为了方便观察当前VICIRQStatus 的值,没其它用途.
第113 问:
Q:请问处理器在什么情况下处于用户模式 多谢!
A:需要你去设置CPSR 寄存器.
用户程序前台程序一般在用户模式/系统模式下运行.
第114 问:
Q:在EINT1_LED.S 中的倒数第二行有一个单独的B 指令,它是什么含义 多谢!
A:是"B .",跳转到当前地址,即死循环,与以下代码等效:
HALT B HALT
第115 问:
Q:模板里到底有些什么
A:起动代码,相关编译链接设置.
起动代码是用来初始化系统的程序,如Startup.s,target.c,stack.s 等等.
26
第116 问:
Q:今天试用了工程模板.使用了ARM Executable Image for lpc21xx 建了个项目,看了下
启动文件与原来的不同了,用了个《ARM 微控制器基础与实战》上的例程来作试验,用
的是time0 定时中断来亮灯的程序,用的例程的TargetInit()和int main(void);
修改了用户堆栈和bottom_of_heap 的长度,程序能运行,但不能产生中断,time0 和VIC
初始化的是正确的,是什么原因
用工程模板建立的项目文件夹的src 中多了几个文件,其中的
mem_a.scf,mem_b.scf,mem_c.scf,怎样才能导入到项目中来 谢谢!
A:原来startup.s 默认是关了中断的!
第117 问:
Q:在easyarm 2104 的配套光盘中的IAP 例子中,定义了一个函数指针
void (*IAP_Entry)(uint32 param_tab[], uint32 result_tab[]);
我看不懂,这个函数和普通的函数定义方法不一样,尤其是(*IAP_Entry),大家教教我.
A:这是一个指向函数的指针!!
第118 问:
Q:变量定义中volatile 是什么意思 请大侠告诉我一下《ARM 微控制器基础与实战》上c
语言定义变量时出现了volatile,不知道是做什么用的.C 语言里好像没有这个语法阿!
A:告诉编译器不要优化掉,volatile 是易变的意思.
第119 问:
Q:请问ARM 中的一个编译方面碰到的问题.
在ARM 地汇编语言中,有条件编译伪指令IF..ELSE...ENDIF;
而在C 语言中,有相应的条件编译伪指令#IF...#ELSE...#ENDIF,在较大的程序设计中,
往往需要对整个程序进行条件编译.
我要问的问题是:我在CONFIG.H 中设置一个编译开关,对所有的C 文件进行条件编译是
有效的, 因为每个C 文件中都有一个语句:#include "config.h",我如何将该编译
开关的信息传递给汇编语言文件,如VECYORS.S
A:好像没有直接的方法,可以编写一个CONFIG.INC 来管理汇编程序的配置.
27
第3 章 操作系统
第120 问:
Q:在SWI_Exception 的0x40 中的_OSFunctionAddr[regs[0]]中的Regs[0]指的是堆栈中的
R0 还是其它
A:是堆栈中的R0.
第121 问:
Q:《ARM 微控制器基础与实战》中在ucos 移植中说C 语言无法保证堆栈的结构,请问这是
什么含义
A:就是不能保证有哪些寄存器入栈及寄存器入栈的顺序.
第122 问:
Q:请问斑竹OSNeedToSwapContext 在哪个文件里声明的,我找不到
A:这是要删除的,我的OS_CPU_C.C 中函数OSIntCtxSw:
/*
***************************************************************************
* 函数: OSIntCtxSw.
* 描述: 中断级任务切换,此处并不真正进行任务切换,具体切换在 IRQ 服务程序中.
***************************************************************************
*/
void OSIntCtxSw (void)
{
}
第123 问:
Q:我的情况如下:我自己制作了一个硬件模块,用的是lpc2214,现在需要将ucos-ii 移
植到上面去.我用板子做ZLG 公司提供的实验,是可以做的,如led 灯等,按道理说串
口等硬件应该没有问题,然后我就做公司提供的那三个移植实例:ex2_arm.编译等是通
过的,生成了hex 文件,下载到flash 中,运行easyarm,但是没有任何显示,不知道是
什么问题,应该是硬件上呢,还是其他的
A:这主要是RAM 的问题,请用我们的工程模板,并选择在FALSH 中调试,如果编译通过,
则一般行, 否则请减少任务堆栈的大小.
第124 问:
Q:下载了工程模板以后,将工程模板目录下的文件都拷贝到了stationary 目录下,然后建
立了一个 ARM Executable Image for UCOSII(for lpc21xx)的工程,在PROJECT 目
录下的文件结构如下:
28
test.c
inlcudes.h
src->config.h,heap.s,includes.h,irq.s,lpc2294.h,
lpc2106.h,mem_a.scf,os_cfg.s,stack.s,startup.s
target.c,target.h,ucos_ii.c,ucos_ii.h,
arm->os_cpu.h,os_cup_a.s,os_cup_c.c
uCOS->ucos 源文件
arm_pc->pc.h,pc.c
编译可以通过,但是MAKE 时提示:
ERROR:Execution region IRAM overlaps with Execution region STACKS.
如果我表述得不是很清楚的话,那么可否告诉我工程模板到底怎么操作,怎样才能把例
子在 ARM2104 上跑起来.
A:RAM 占用太大,请在flash 中调试,并减少任务堆栈的大小.
第125 问:
Q:我改了以下SCF 文件,把堆栈的值设置大了一些,但是还是出现以前的老问题,那就是
程序跑到
TargetResetInit()函数处后就跳到取数据终止的异常中断去了.
A:不能把堆栈设置到内部RAM 之外.
第126 问:
Q:新旧任务级的切换是不是必须在管理模式下切换 切换后新任务的运行是不是必须在管
理模式下
A:在配套《ARM 微控制器基础与实战》里的任务切换是通过SWI 实现的.SWI 会使CPU 进入
管理模式.同时CPU 自动将任务的CPSR 保存到管理模式的SPSR 中.
SWI 程序还保存了一些寄存器到管理模式的堆栈中.然后任务切换程序会在管理模式
和系统模式间来回切换,目的是把保存在管理模式堆栈的寄存器内容拷贝到任务的堆栈
中(注意:任务是运 行在用户模式或系统模式的,这两个模式使用同一个SP,这时的
系统模式的SP 指向的就是任务的堆栈),也会将管理模式的SPSR 拷贝到任务堆栈(注意
管理模式的SPSR 就是在执行SWI 时CPU 自动保存的任务运行时的CPSR,它记录了任务
运行的CPU 模式和其他的运行状态信息).最后把任务模式SP 保存到任务的任务控制块
中(注意此时CPU 已经是运行在系统模式下的了).以上大致就是uC/OS-II 中所说的保
存任务运行环境的工作.
任务的恢复运行就比较好理解了.
接着前面的说,CPU 还在系统模式下.程序从任务控制块中得到任务的堆栈指针.
(OSIntCtxSw_1 的第一句)将这个指针的值加上一定的偏移量保存到SP 中.为什么要
加上一定 的偏移量呢 因为这时任务的堆栈中除了保存任务运行时的数据外还保存
了任务的上下文,即任 务切换时保存的CPU 寄存器等内容.而我们恢复任务等一下是
在管理模式下进行的,用的是管理模式的堆栈指针.等恢复任务后CPU 就开始执行任务
29
代码了.我们已经没有机会再修改系统模式下的SP 值了.所以在这个时候就应该对SP
进行调整.调整的大小就应该是所保存的上下文占用的大小.从堆栈中恢复LR 的值.同
样的道理,管理模式和系统模式使用不同的LR,在切换到管理模式之前,必须先在系统
模式下恢复任务运行时的LR.(OSIntCtxSw_1 的第三句)接下来就切换到管理模式了.
(OSIntCtxSw_1 的第四句)使管理模式SP 指向任务堆栈(第五句)注意这是没调整过
的任务SP,也就是保存了上下文环境的SP.
接下来的事情就真的很简单了.从堆栈中恢复出保存的东西.先是OSEnterSum,然后是
任务的CPSR (注意任务的CPSR 就是进入SWI 时由CPU 自动保存到管理模式的SPSR
中的,所以此时也是恢复到管理模式的SPSR 中)最后一句就是典型的中断返回语句了.
恢复寄存器,恢复PC,加了一个^号意味着同时将SPSR 拷贝到CPSR 中.
现在是回答你的问题的时候了.
切换前任务是运行在什么环境下的(包括CPU 模式,所有的寄存器),任务切换后任务就
是运行在 什么环境下的.对任务来说,什么也没改变.只有PC 值指向了下一条指令,
哈哈.
第127 问:
Q:请教:在rtos51 解释的概念里的"信号量"比较难懂,"消息队列"可以理解为任务之间
互相传递的参数,但"信号量"怎样理解呢 具体一点,谢谢!
A:信号量是60 年代中期Edgser dijkstra 发明的,它实际上是一种程序间的约定机制,
这种约定决 定那个程序(任务)可以执行.在多任务内核中普遍使用信号量用于:
1.控制共享资源的使用权(满足互斥条件);
2.标志某事件的发生;
3.使两个任务的行为同步.
信号量像是通行证,且通行证的数目是有限的.任务要运行下去,要先拿到通行证.如
果信号量 已被别的任务占用,该任务只得被挂起,直到信号量被当前使用者释放掉.
信号量的值可以是0 到255 或0 到65535,或0 到4294967295,取决于信号量规约机制
使用的是8 位,16 位还是32 位.到底是几位,实际上是取决于用的那种内核.根据信
号量的值,内核跟踪那些等待信号量的任务.
一般地说,对信号量只能实施三种操作:初始化,也可称作建立;等信号也可称作挂起;
给信号或发信号.信号量初始化时要给信号量赋初值,等待信号量的任务表应清为空.
想要得到信号量的任务执行等待操作.如果该信号量有效(即信号量值大于0),则信号
量值减1,任务得以继续运行.如果信号量的值为0,等待信号量的任务就被列入等待信
号量任务表.多数内核允许用户定义等待超时,如果等待时间超过了某一设定值时,该
信号量还是无效,则等待信号量的任务进入就绪态准备运行,并返回出错代码(指出发
生了等待超时错误).任务以发信号操作释放信号量.如果没有任务在等待信号量,信号
量的值仅仅是简单地加1.如果有任务在等待该信号量,那么就会有一个任务进入就绪
态,信号量的值也就不加1.于是通行证给了等待信号量的诸任务中的一个任务.至于
给了那个任务,要看内核是如何调度的.收到信号量的任务可能是以下两者之一:
1.等待信号量任务中优先级最高的任务;
2.最早开始等待信号量的那个任务,即按先进先出的原则(FIFO).
30
有的内核有选择项,允许用户在信号量初始化时选定上述两种方法中的一种.但Small
RTOS51 只 支持优先级法.如果进入就绪态的任务比当前运行的任务优先级高(假设,
是当前任务释放的信号量激活了比自己优先级高的任务).则内核做任务切换(假设,使
用的是占先式内核),高优先级的任务开始运行.当前任务被挂起.直到又变成就绪态中
优先级最高任务.
第128 问:
Q:我用了两个串口,但当我把程序做大的时候,发现在这个任务里所建立的邮箱失败,
我只用一个串口时是没有这种事情的.
Uart0ReviceMbox = OSMboxCreate((void *)0 ); /* 建立邮箱 */
if (Uart0ReviceMbox == NULL)
{
while (1);
}
我想问一下有几种可能会造成这种分配失败 我的程序存储器用量如下:
Total R0 size 22168
Total RW size 7956
Total ROM size 22168
A:在OS_CFG.H 中定义最大事件数,太小的话,分配会失败的.
第129 问:
Q:在周立功的原例子中,系统代码事先烧到ROM 中,应用代码在RAM 中运行.我想知道,
(RAM)应用代码调用系统函数,那么2104 是如何把ROM 中的系统函数的地址传递给RAM,
也就是应用代码和系统代码是如何关联在一起的 我猜是通过swi(软中断),应用代码
通过swi 调用系统代码,但是swi 中断程序中,是如何获得烧到RAM 中的系统函数的地
址哪 百思不得其解.
A:您看一看romcode 工程中swi 的0x40 和0x41 功能,
及Os_call.c,Os_call_arm.s,Usr_call_arm.s.
第130 问:
Q:16k 的RAM,128 的FLASH ROM 跑uc/os-II 够吗 再跑点应用程序够吗
A:取决于您的应用程序对RAM 的需求,及代码量.一般程序可以.
第131 问:
Q:利用lpc2104 开发应用程序时,在Os_call_arm.s,Os_call.c 两个文件中,那几个函数
需要在汇编中实现,哪几个需要在.c 文件中实现,为什么 谢谢各位大虾 !
A:4 个以上参数用c 实现.因为通过寄存器只能传递4 个参数.
31
第132 问:
Q:如果禁止SmallRTOS51 进行中断嵌套管理(#define EN_OS_INT_ENTER 0),是否还需要
设置中断优先级寄存器IP,使得所有中断的优先级都相同(全高或全低)
A:受SmallRTOS51 管理的设置为最低优先级,不受SmallRTOS51 管理的设置其它优先级较
好.
第133 问:
Q:在OS_CPU_S.s 文件中有如下一段代码,其中有两句代码的作用不是很明白,请解说一下.
OSIntCtxSw_1
LDR R4, [R6] ;获取新任务堆栈指针
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;这两行代码有何作用呢
ADD SP, R4, #68 ;17 寄存器CPSR,OsEnterSum,R0-R12,LR,SP
LDR LR, [SP, #-8]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
MOV SP, R4 ;设置堆栈指针
LDMFD SP!,{R4, R5} ;CPSR,OsEnterSum
;恢复新任务的OsEnterSum
LDR R3, =OsEnterSum
STR R4, [R3]
MSR SPSR_cxsf, R5 ;恢复CPSR
LDMFD SP!, {R0-R12, LR, PC }^ ;运行新任务
A:这两条指令是在系统模式下恢复用户模式下的LR;可以参考配套《ARM 微控制器基础与
实战》6.4.9 节.
第134 问:
Q:我将《ARM 微控制器基础与实战》上uC/OS-II 的第一章例2 移植例在ARM2104 开发版上
实现例2 中的TEST.C 中的"#define TASK_STK_SIZE 512"改为"...256",程序编译
后,数据量低于16K,能正常运行,但运行时"Total Stack"不是256 全是1024.另
UC/OS-II 书上,第一章例2 每一个任务的堆栈都是512,为什么书上11 页"Total Stack"
是"624,1024,1024,1024,1024,1024,1024",请老师指点,万分感谢!
A:显示的是字节而定义的是字.
第135 问:
Q:可不可以把所有的任务和相关信号量(二值)在一个任务里面一起创建呢 我现在是这
样做的, 不知是不是这方面的原因 而且全部信号量是这样创建的:
XX1 = OSSemCreate(0);
32
XX2 = OSSemCreate(0);
XX3 = OSSemCreate(0);
一共创建了十个信号量,以前程序代码版本是分开写的执行起来没有问题,不知现在为
什么这样写就会出现小问题呢 这样的问题和我的任务和信号里书写位置有关系吗
A:必须在使用信号量前创建信号量.
第136 问:
Q:UCOS 在中断处理完后调用 OSIntExit(),该函数将判断是不是要进行任务切换,如果是
则调用 OSIntCtxSw()切换任务, 然后才恢复寄存器,中断返回.这样说来,在中断
返回前,已经切换到别的任务去了,在再次回到被中断的任务前,是不是一直没有中断
返回
A:如果进行任务调度,则不会执行OSIntCtxSw()后的语句,相当于中断已退出.
第137 问:
Q:最近我在学习使用SMALL RTOS 时发现一个 BUG.
任务在调用系统等待函数 OSWait(K_TMO | K_SIG,x) 后,不能在延时 x 个 ticks 后
被唤醒.
我分析了一下原因如下:
在 OS_CORE.C uint8 OSWait(uint8 typ, uint8 ticks) small 中,
case (K_TMO | K_SIG): 中执行了函数 OSTaskSuspend(OSTaskID);
( OS_CORE.C 第549 行)而此函数将延时值改为了 0!
解决办法:将此函数改用另一个函数 OS_TaskSuspend(TaskID);
并在其后加入任务切换函数 OSSched();
便能工作正常.
A:对,这是疏忽,谢谢.您的更改是对的.
第138 问:
Q:在文件Os_cpu_a.s 中的函数OSIntCtxSw 中有如下语句:
……
(1) LDR R4, [R6]
(2) ADD SP, R4, #68
;17 寄存器 CPSR,OsEnterSum,R0-R12,LR,SP
(3) LDR LR, [SP, # --8]
(4) MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
(5) MOV SP, R4
……
(6) LDMFD SP!, {R0-R12, LR, PC }^ ;运行新任务
《ARM 微控制器基础与实战》404 页中解释:只所以要(1)(2)是因为"OSTCBHighRdy
—>OSTCBStkPtr 保存的是任务栈位置,而寄存器恢复后堆栈指针并不指向这,所以要调
33
整新任务堆栈指针." 可是将堆栈指针调整到 "新任务入栈的其它数据(见《ARM 微控
制器基础与实战》图6.3)"处后,除了取出了LR 以外并没有做 什么,而当执行了(4)
后又重新将堆栈指针指向了栈顶(即第(5)句).我认为可以将(2)省去,直接将(3)改为
"LDR LR, [SP, # 60]",而当执行完(6)后,堆栈指针就自动指向了"新任务入栈的其它
数据"处.这样修改后我运行了EX1_arm 例子,正常.
请问这利用(3)进行堆栈指针调整的原因是什么 不调整可以吗 谢谢.
A:注意不同模式有不同的SP 指针.您这样做会造成内存泄漏,长时间运行会耗尽堆栈而使
程序崩溃.
第139 问:
Q:不明白在光盘上ROMCODE/SRC/下的os_call.c 做什么用.
A:是应用程序与事先固化到flash 中的ucosii 接口的一些代码.在本例中为应用程序如何
调用事先 固化到flash 中的ucosii 的OSFlagPend 等函数的接口代码.请看配套《ARM
微控制器基础与实战》的7.4.3 节的第10 点.
第140 问:
Q:请问在OS_CORE.C 中的常数数组OSUnMapTbl[]是做什么用的
A:用来计算优先级的,查表计算比较快.
第141 问:
Q:ucos 的中断嵌套层数是否受到初始化时分配的IRQ 堆栈大小的限制 我的理解是每一次
中断需入栈的寄存器有R0-R3,R12,LR,SPSR,共7 个,如果想达到8 层嵌套的话,堆栈长
度IRQ_STACK_LEGTH 应设为56,不知这样理解对不对.
A:是,但中断至少占用8 个字,因为c 语言的中断处理函数会将一些数据压入堆栈.
要达到8 级嵌套需要的堆栈长度与具体的代码有关.
(编者注:新移植代码已有改变)
第142 问:
Q:请问:核心定时器中断不进入可能因为……
我的程序在运行一段时间以后,核心定时器中断即操作系统用的Timer0 不能进入,查发
现CPSR 的I 位为1,请教这可能是哪个原因
A:估计为开关中断次数不匹配造成.
第143 问:
Q:请问:GetOSPprioCur()函数应怎样调用 它是一个内核函数吗
为什么我在内核和任务分别编译时正常,而合到一起编译时它告警为未定义呢
同时我已给您发了一个邮件,请教如何将分别编译的程序合在一起编译的方法,请指教!
A:这是我自己编写的函数,其实就是返回OSPrioCur 的值,请参考MyFunction.c.
34
第144 问:
Q:关于不受uc/os 控制的中断:在ARM 板中,非屏蔽中断可以挂起正在执行的uc/os 任务,
除了不能使用uc/os 中的函数外,它的执行工序是不是和受管理的中断一样,先挂起当
前任务,再保存CPU 寄存,然后再执行中断ISR,完成后,内核脱离,寄存器恢复,最
后任务调度.
另外,《ARM 微控制器基础与实战》中提到不受管理的中断,它的工作是否和非屏蔽中断
一样,也可以在uc/os 正执行时发生中断.如果不同,它们是怎样工作
最好是象受管理中断一样说明一下它的工作时序!
A:必须比受管理的中断的优先级高,编写方法与没有OS 时中断的编写方法一样.
第145 问:
Q:不受uc/os-ii 管理的中断和受管理的中断是否具有相同的响应方式,即不受管理的中断
在中断 uc/os 正执行的任务后,是不是也是先挂起当前的任务,保存CPU 寄存器,再
执行中断子程序,恢复CPU 寄存器,进行最优先级任务的调度.
A:不受uc/os-ii 管理,uc/os-ii 都不知道,还有什么任务调度
Q:我知道不受管理的中断不能调用uc/os 的函数,但《ARM 微控制器基础与实战》上说:
FIQ 不受uc/os 管理,但可以用来执行紧急任务,就是说在uc/os 运行时,不受uc/os
管理的中断还是可以发生的,它是把整个uc/os 操作系统中止,还是只是中止uc/os 正
在执行的任务.不受管理的中断完成后,接着执行什么
A:可以发生,中断整个RTOS.
Q:我看了您在lpc210x 上的移植代码,你在说明中说:"如果您想通过软件仿真,请将
target.c 中的第 51 行屏蔽, 这样就可以看到任务逐个切换,最后将进入空闲任务."
我照这做了,但是在单步或者设断点执行时会产生异常,原因是未定义指令
OS_ENTER_CRITICAL()引起的,经过编译的函数都会变成蓝色,但这个函数还是黑色,因
为它实际上是一个软中断,请教您如何调试才能看到任务逐个切换 谢谢!
A:1.屏蔽的那一行是死等锁相环锁定,软件仿真时是没有锁相环的.
2.黑色是正常的,因为没有定义成函数.
3.因为你的 AXD -> OPTION -> 配置处理器中的 VECTOR CATCH 中的 S 选中了,所以 AXD
将你的软件中断当成了异常给捕捉了,取消即可.
第146 问:
Q:请教ucos2 的源代码中经常碰到:return((void*)0)是什么意思
A:返回空指针.
第147 问:
Q:这是个什么错误,怎么改啊
OsMemPut 是个函数名称
Error : L6200E: Symbol OSMemPut multiply defined (by uCOS_II.o and
Os_mem.o).
A:这是重复定义错误.请不要把uCOS_II.C 添加到你的工程中.
35
第148 问:
Q:我想请教一下在配套光盘中有没有ucosII.h 文件,怎么我总是找不到的
如没有能否提供下载地方 谢谢!
A:北航出版的第2 版就带有uC/OS 2.52 源代码,
还可以到其它网站上找找.
第149 问:
Q:我想问一下一个任务中的子函数的局部变量算不算进堆栈的容量.
我发现我在用邮箱传递一个较大的值时,是在一个任务的函数中声明了uint8
byte[500],可在传递时值发送了变化,只好用的外部变量了,最后搞得邮箱只起了信号
量的作用,所以我觉得局部变量虽然是从堆栈中取得数据,最后在任务切换时,把局部
变量也保存到堆栈中,不知道我这种理解是否正确
A:算.局部变量在函数退出后(不管任务是否却换过)被释放.
第150 问:
Q:我用UCOS 在EASYARM 上的一个程序内编写了5 个任务,前4 个任务调试后工作正常,在
编译第5 个任务时,提示为:
Execution region ER_RO overlaps with Execution region ER_ZI.
编译还提示:
TOTAL ROM SIZE (CODE +RO DATA +RW DATA ) 8624
我曾经试图修改"#define TASK_STK_SIZE 64 "也不管用,请问,如何解决
A:问题已找到,代码超过16K.上面的信息会在zi 段或者rw 段与ro 段(代码段)发生重
叠时发生.
第151 问:
Q:请教uc/os 移植问题
在2104 上面能进行移植吗 如果不行的话,需要买2106
A:你要在os_cfg.h 中把不用的内部调用都裁减掉,就可以做一个很小的内核,就是不裁减
你就是14k 左右,写在FLASH 里一样也能运行.
第152 问:
Q:请教信号量的概念问题.
我准备用信号量来编写一个ARM 程序,但我没有完全理解信号量的概念.
例如:现在有4 个任务:TASK1,TASK2,TASK3 和TASK4,任务的要求是:TASK1 和TASK2
之间需有信号量传递信息;TASK3 和TASK4 之间需也有信号量传递信息.
假定TASK1 和TASK2 之中已建立了一个信号量为
RandomSem = OSSemCreate(1);
我要问的问题是:TASK3 和TASK4 之中的信号量是否需重新建立一个 例如,加一条
36
RandomSem1 = OSSemCreate(1);
换一个问法:即若TASK1 和TASK2 之间需有信号量传递信息;
TASK3 和TASK4 之间需也有信号量传递信息,我只需在运行这4 个任务之前的初始化程
序中有一条指令即可:RandomSem = OSSemCreate(1);
A:用两个信号量,你第一个说法对了.
第153 问:
Q:各位:在UCOS 多任务中有一个任务结构如下:
void TASK(*pdata)
{
uint8 i;
任务循环前的一些指令集A;
while(1)
{
任务循环;
}
}
我要问的是:与该任务有关的初始化,如串口初始化,是否不用放在整个程序的开始处,
而作为指令集A 的一部分,也可达到同样效果
A:启动和初始化代码放在一个文件里主要是为了程序的模块化,不过代码少的话倒是可以
放在一个函数里完成.
A:ucos 的事件标志使用注意点:
请在事件标志结构定义前加__packed,否则由于字节对齐的问题会产生没有反应的bug!
第154 问:
Q:移植中碰到的问题!
我把周工《ARM 微控制器基础与实战》上的范例1 移植到ARM 上,但任务没有跑起来,
请做过移植的朋友帮帮我吧!
我是把代码生成HEX 文件全部下到FLASH 中,不知道这样对不对啊 软件需要怎么设置

A:先检查ARM Linker 的设置是否正确 参照《ARM 微控制器基础与实战》P42O 设置release
的参数.
A:感觉运行ex1 还是比较容易的,毕竟斑竹都已经把代码写好调试好了,你可以不必完全
把它拷贝下来,可以自己建一个project,然后一个个文件添加,这样比较容易弄懂哪
些文件都是来干嘛的,哪些还需要自己改写.推荐在建立project 时可以把相应文件分
组,我就是把uC/OS2.52 文件放在一个组下,需要自己改写的(如OS_CPU_A.S)放在一个
组内,启动代码放在一个组内,自己的代码(如main,自己的任务)放在一个组内,这样
比较分明些,个人建议.
第155 问:
Q:看过操作系统固化之后,有点疑问:
37
把操作系统和用户代码分开真的能节约RAM 空间吗 只是在用户代码定义的起始地址在
0x40000000 的情况下(即调试时)才会节约吧 一般情况下我觉得如果要真正使用的话
都应该是把程序起始地址定义到00000000 上的,这样的话才有,不然一掉电程序就没了.
这样理解对吗
A:是的,参考合并在一起的例程
http://www.zlgmcu.com/download/downs.asp
ID="861".
第156 问:
Q:任务间的数据传输除邮箱等外是否可以建立一个全局变量在任务间传递数据!
A:可以,但要注意重入问题和代码优化问题,最好使用volatile 修饰变量,如果不能一次
读写完毕则需要加上开关中断的代码.
第157 问:
Q:请问:uc/os 任务堆栈问题.
在ucos 移植的程序EX1_arm 中:
#define TASK_STK_SIZE 128 /* Size of each task's stacks (# of WORDs) */
#define N_TASKS 10 /* Number of identical tasks */
请问,任务堆栈设为什么设这么大
A:可以变小,但要在复杂任务中应保证够用.
第158 问:
Q:在看uc/os-II 的书时,关于ucos-II 中任务切换的几种情况的问题.
1.在一个时钟周期内,至少所有的任务都要运行一遍,对吗
2.任务切换发生的三种情况:
a.任务A 主动放弃CPU 的主动权,利用 OSTimeDly() 延时,进行任务切换;
b.中断时钟周期发生时,在任务就绪表中寻找最高优先权的任务,如果当前任务不
是最高优先级,发生任务切换,否则仍执行原任务;
c.发生irq,fiq,软中断,取指错误和取数据错误五种异常模式时,直接发生任务
切换, 中断处理结束后,在任务就绪表中寻找最高优先权的任务,如果当前任
务不是最高优先级,发生任务切换,否则仍执行原任务.
A:1.不一定,如等信号时 OSPend(x, 0, &err)时.
2.只有在IRQ,FIQ 和软中断受OS 管理时才能进行任务切换,同理取指,取数异常在启
动阶段的 死循环根本谈不上任务切换.
第159 问:
Q:请问:在移植UC/OS 中的软件中断汇编接口程序中取功能号码.原程序为:
如果是在THUMB 状态,则为LDR R0,[LR,#-2]
如果是在ARM 状态, 则为LDR R0, [LR, #-4],
在清除R0 中的最高两位,R0 的值就为功能号.
为什么是从LR 中取值呢 LR 的值是进入中断时候保存的PC 值吗 迷惑!
A:执行SWI 指令后,处理器进入管理模式,LR_svc 中保存返回地址,顺藤摸瓜,根据LR_svc
38
就可以取得SWI 语句,也就取得了中断号.
第160 问:
Q:请问及各位高手:OSIntCtxSw()函数分别在includes.h 和OS_CPU_A.s 中有定义,区别
在哪
程序OSIntExit 中调用该函数的时候是不是都是去调用了includes.h 中的宏定义的那

两者各自的应用范围在哪儿 我看过一个移植实例上只有一个OSIntCtxSw 函数.请指
教!
A:includes.h 中的宏 OSIntCtxSw 在C 中被调用.
第161 问:
Q:问一个堆栈指针的问题
在OSIntCtxSw_1,获取新任务堆栈指针.
LDR R4, [R6]
ADD SP, R4, #68 ;17 寄存器
CPSR,OsEnterSum,R0-R12,LR,SP
LDR LR, [SP, #-8]
MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
MOV SP, R4 ;设置堆栈指针
LDMFD SP!, {R4,R5} ;CPSR,OsEnterSum
;恢复新任务的OsEnterSum
......
我想问一下DR LR, [SP, #-8],这一行程序中,为什么堆栈指针要减去8 个字节
的值
A:这是调整SP 的指针,使其指向栈中的LR.看一看配套《ARM 微控制器基础与实战》的图
6.3.
Q:ucos 中断丢失.
在ucos 在每秒切换200 次时正常,但在1000 次时中断丢失 可能是哪里的问题
A:问题已经找到,是随2104 中的ucos 不支持中断嵌套.在不嵌套时4000 次/秒也是正常
的.
第162 问:
Q:uC/OS-II 能在2104 上和用户程序一起编译吗 一定得分开编译吗
《ARM 微控制器基础与实战》上介绍的移植方法上是分开编译的,我想合并在一起调试,
这样就不必用软件中断去寻找系统函数的入口地址.要做到这样,是不是只需把
OS_TASK_STAT_EN 设置为1,OS_SELF_EN 为0
39
A:可以,网站上有例子
http://www.zlgmcu.com/tools/kaifaban/EasyARM2104.asp
.
第163 问:
Q:请教:我运行OSInit(); 函数,程序死在SoftwareInterrupt B SoftwareInterrupt 困
惑呀!
A:uc/osii 的启动代码与普通的启动代码不同,您使用的是普通的启动代码.
第164 问:
Q:请问:在UC/OS-II 目录中的README.TXT 下,有的例子说:"仅lpc2106 有足够的RAM
可以在RAM 中放入所用代码."那么,如果我使用LPC2104,在FLASH 中存放运行代码
是否能正常运行 谢谢!
A:主要看数据是否超出16k,如果超出,请减少任务占用的堆栈.
第165 问:
Q:请问:在UCOS-II/ex2_arm 中,我编译时出现错误提示如下:
ERROR6221E:execution region ER_R0 overlaps with Execution region ER_ZI.
如何解决 而我在UCOS-II/ex1_arm 中编译.运行都正常,谢谢!
A:定义任务堆栈小一点,如"#define TASK_STK_SIZE 128"
第166 问:
Q:uCOS-II/EX2_arm 我什么也不动,用ADS 打开,可是编译的时候出错,是很多文件找不
到.
比如ucos_ii.h 就找不到.
#include "../../source/ucos_ii.h"
可是我的光盘里没有source 这个文件夹啊,还有很多uCOS-II 文件也找不到,是不是我
的光盘少了东东 站上有得下载吗
A:要将uC/OS-II(v2.52)源代程序放到source 目录下,北航出版的uC/OS-II 书(第二版)
带有.
第167 问:
Q:OSIntNesting(嵌套层数)和OsEnterSum(关中断计数器),有什么区别吗
我个人认为这两个变量相同,不知为什么要定义两个变量
A:OsEnterSum 是关中断的计数器,目的是实现临界段嵌套.
OSIntNesting 是中断嵌套层数,目的是实现中断嵌套.
第168 问:
Q:为何我EX1_FLASH 移植的时候总出现如下错误提示,请问是哪里出错了
Error : C2933E: type disagreement for 'OSTaskStkInit'
40
Os_cpu_c.c line 70
A:是调用OSTaskStkInit 时类型不一致导致,好好看一下C 语言.
第169 问:
Q:请问:在SWI 软中断指令中,LR 中放的是异常模式下的返回地址,而这个地址的低8 位
和低24 位分别是thumb 和ARM 指令下的立即数,这种对应的关系是如何来的
还有执行THUMB 和ARM 指令,LR 中放的地址最后的位应是0 和00,那么为什么会有
swi 01
swi 03
这样的立即数呢
A:您的理解不对,可以看一看os_cpu_s.s 这个文件.
第170 问:
Q:2104,2119 中都不能用UCOSII 的flag 的问题.
在模板中ARM Executable Image for UCOSII(for lpc21xx)加入这个程序文件.实际上
程序运行到 KeyFlagGrp = OSFlagCreate(KeyFlags,KeyFlagErr); 时就进入Startup.s
的取数据终止,但在没模板的情况下是没问题的,请问哪位在模板中用过UCOSII 的
flag
A:字节对齐问题,请在事件标志结构定义前加__packed.
第171 问:
Q:我请教您一个问题,在2104 里写程序的时候用 malloc()来分配内存单元的时候,经常
出现在程序中被分配的单元数值在任务切换的过程中被改变的情况,不知道您碰到过没

是如何解决的 谢谢!用ucos 中的内存分配函数就不回出现这种问题.
A:请在网上下载最新的模板,其中启动代码有更新.
另外,如果分配太大的空间可能会造成程序跑飞.
第172 问:
Q:在uC/OS 中进入临界代码区时,只是关swi 中断,还是将所有的中断都关断.
A:要关所有调用了OS 系统服务函数的中断.一般是IRQ 中断.
41
第4 章 芯片
第173 问:
Q:2100 实验板的问题.
使用几次RelInFLASH 后不能正常工作,包括其他两种方式也不能工作在RelInFLASH 和
DeBUGinflash 时显示一个错误
Warnning! interrupt vectors data is not correct!
Program you downloaded can not run freely!
不知怎么回事 使用DebugInRAM 虽然不报错,但无法正常工作.
A:可能是启用了加密功能引起的,使用ISP 擦除FLASH.
第174 问:
Q:很有意思,自从买了2100 实验板一直在用DebugInRAM,今天想试试DebugInFLASH,后
来就选了后者进行调试,奇怪的现象发生了,以后再进行DebugInFLASH 之前确切的说是
进入AXD 在运行之前都显示着我第一次用DebugInFLASH 时下装的程序,一运行就可以显
示当前程序的结果,每次如此,只要不运行其他程序,实验板上的LED 就保持第一次下
载的程序的状态,RESET 和重新上电都不行,是不是我的这个程序把开机的DEMO 替换掉
了,哪里可以下载到那个DEMO,我想再装回去.
AebugInFLASH 就已经把程序下载到FLASH 了,原先出厂的程序已被你的程序覆盖.
第175 问:
Q:我将其按照intle 32 bit hex 编译后将hex 文件通过ISP 下载到2104 开发板上为什么
没有反映 后来再下载C 语言编写的同样功能的文件,前几次可以运行,后来又下载
了别的程序后就又不能运行了,请问这是什么问题 多谢!
A:光盘上的EINT1_LED.S 只适合于在RAM 中调试,如果要下载到FLASH 中运行,需要加入
向量表(且要求向量表累加和为0).
Reset
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC, FIQ_Addr
ResetAddr DCD MAIN
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
42
Nouse DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
MAIN ...
第176 问:
Q:手册上只有I1.8,而没有I3.3,无法计算片子功耗.
A:3.3V 与外设相关.芯片本身在3.3V 中的消耗可以忽略不计.
第177 问:
Q:通过查看数据手册LPC2119 的接地有三种,分别是Vss(0V 电压参考点),Vssa(模拟地),
Vssa_pll (pll 模拟地),三种的电压都为0V,但为了降低噪声和出错几率需要隔离,
请问如何隔离 电源方面:有两种供电电压,一种是1.8V(内核),一种3.3V(I/O 口)
分别存在隔离问题,请问如何解决 吾乃新手,还忘老手不吝赐教,谢谢!
A:与普通的多种地布线类似(它们有多少种方法就有多少种方法),最终这些地线还是要接
到一起.
第178 问:
Q:请问LPC2119 的电源芯片选哪款较为合适 有没有推荐的匹配
A:与2104 一样,可选SPX1117.
第179 问:
Q:我现在数字电路除LPC2114 使用3.3V 电压外,其余的大部分是5V 的.我想先将LPC2114
连接到 CPLD,再连接到其它电路(CPLD 的I/O 口可以输出或输入5V)不知道行不行.
谢谢.
A:我觉的简单的电路可以用LVC 芯片,必要时可以用3V 的CPLD.
第180 问:
Q:请问:你们公司的ARM 芯片相对于 象44B0X 等等一系列的ARM 处理器的优点在那里
好象LPC2104 还比较的贵啊!现在我正在考虑选择 ARM 芯片的问题,望回答.谢谢
A:我们的LPC210X 内部有FLASH 和RAM,LPC211X 为工业级适用于工控领域,并且是全球唯
一可加密 的ARM.
以整个系统成本来说,LPC ARM 内部有FLASH 和RAM,低功耗,可加密性价比更高.具有
ARM 的性 能,单片机的特点,在许多应用场合比其它的ARM 更优越.
第181 问:
43
Q:我的2214 板IO 口和中断均能正常工作,今天准备调显示器,显示器接在CS2 上,8 位
数据线,通过查资料,得cs2 的地址空间为8200 0000,于是我将命令口地址定为0x8200
0001,数据口地址定义为0x8200 0000,对啦,数据命令切换线在A0 上,在显示器初始
化前,对CS2 进行了配置,即BCFG2&=0XCFFF FFFF,即除修改成8 位数据线外,其它均
不变,对显示初始,定时送显示器,但是测量CS2 口线,根本不出现低电平,更不用说
数据线啦,即好像外部总线根本没有工作.
之后根据2214 的模板,从新设置了参数,结果写信号出不来,片选,读地址,数据均有.
PINSEL2=0x0f814910;
BCFG2&=0xcfffffff; // CS2,8 位数据线,
请问,配置外部总线还需要其它寄存器吗,由于手上没有这方面的资料,请给予帮助.
谢谢!
A:注意BCFG2 的写保护位.
第182 问:
Q:请问:关于LPC2214 的BOOT0 和BOOT1 的用法.
前提:我使用内部FLASH 作为程序存储器,利用外部总线CS0 扩展一片并口的12 位AD,
CS1 扩展并口的液晶,CS2 扩展一片RAM 芯片.
我的想法:将BOOT0 和BOOT1 上拉,系统上电启动后,检测到11,那么从内部FLASH 启
动,之后我可以设置管脚的选择寄存器,使能CS0 和CS1 和外部总线,那么我就可以随
时的利用它的地址访问我的外部扩展的设备.
请问我的想法对吗,并请指点一下我应该注意的相关的问题.
A:正确.
第183 问:
Q:请问:2214 外扩SST39VF320 在CS1 上为什么读ID 不正确 程序如下:
//设置PINSEL2 位
#define P1_26_31_Debug 4 // JTAG D2
#define P1_16_25_Track 8 // 跟踪 D3
#define P2_Data_Bus 0x10 // D0-15 IO (D5 D4=01)
#define P3_27_WE 0x100 // 写信号 D8
#define P3_26_CS1 0x800 // D11
#define P3_25_CS2 0x4000
#define P3_24_CS3 0x10000
#define P3_0_23_ADDR 0x0f800000 // 地址总线
//PINSEL0=P0_0_15_Set;
#define PIN2Set (P1_26_31_Debug+P1_16_25_Track+P2_Data_Bus+/
P3_27_WE+P3_26_CS1+P3_25_CS2+P3_24_CS3+P3_0_23_ADDR)
#define SST39VF320_Com_Add1 (*((volatile unsigned long *) 0x81005555))
#define SST39VF320_Com_Add2 (*((volatile unsigned long *) 0x81002aaa))
#define SST39VF320_ID1_Add (*((volatile unsigned long *) 0x81000000))
44
#define SST39VF320_ID2_Add (*((volatile unsigned long *) 0x81000001))
void InitGPIO()
{
PINSEL2=PIN2Set;
BCFG1=0x10000000; // 16 位
}
void Check320(void)
{
SST39VF320_Com_Add1=0xaa;
SST39VF320_Com_Add2=0x55;
SST39VF320_Com_Add1=0x90;
// Delay_150_Nano_Seconds();
// Read the product ID from 39VF320
SST_id1=SST39VF320_ID1_Add; // 读出ID 不对
SST_id2=SST39VF320_ID2_Add; // 读出ID 不对
SST39VF320_Com_Add1=0xaa;
SST39VF320_Com_Add2=0x55;
SST39VF320_Com_Add1=0xF0;
}
A:CPU 的A0 不能不能接,另外地址也要相应的变化(针对FLASH 的地址和针对CPU 的地址
不一样).
第184 问:
Q:请问1.8V 电源和3.3V 电源的跳线要同时供电吗 分别是给谁供电的
A:一个是给核心(内核)供电,一个是给I/O 口供电.
第185 问:
Q:1.ARM 的P0.1(WR),P0.4(RD)为何不直接和以太网控制芯片的IOWB,IORB 相连
NETCS 起什么作用
2.网卡控制芯片的INT0 为何要接一个反相器和ARM 的P0.7 相连
3. 我能否直接连接到ARM 的P0.16(外部中断0 输入)口呢
4.8 位数据线和5 位地址线怎么实现分时复用
A:1.使用片选选择,NETCS 就是片选信号.
2.因为8019 的中断是输出高电平,为了适应所选芯片,所以加反相器.
3.如果所选芯片支持低电平或跳变触发,就可以不用加反相器而直接与外部中断输入相
连.
4.加锁存器.
第186 问:
45
Q:目前210x 的各功能均试验完毕,现在想知道的是其IAP 功能是否可以向PSD 产品那样实
现远程的程序更新 如果可以,那么当程序代码写入FLASH 后如何让程序转到更新后的
程序 PSD 是通过寄存器来完成转换的,那么210x 如何实现呢 比如210x 的程序是从0
地址开始执行的,假如原代码长2FFFH,现在更新后的程序长3500H,那么在IAP 时只能
将代码写到非00000000~00002FFFH 区域FLASH 中,写完后该如何让当前程序停止而转到
更新后的程序呢 PSD 产品是因为有2 块存储器,在执行当前存储器中程序时可对另块
存储器写操作,写完后在将执行权交给另块存储器.期待您的回复!
A:如果,你的程序较小(64k),你就把它当作两块独立的FLASH(多个扇区).
写入其中一块,另一块空着...
程序开始执行的时候,判断哪一块是最新的,跳转过去就行了!
一旦从外界收到"更新程序"的命令,检验数据,更新另外一块,就行了!
接收完毕,烧写结束,写入最新程序标志.立即跳过去.
下一次开机,执行最新的.
这个方法,比较安全.可以防止中途通讯结束,复位等.
如果你的程序比较大,有点悬……至少,在某些干扰环境下,不要那么做.
第187 问:
Q:开发板实验中 delay_ns(uint32 dly) 在上述条件下是延时dly 秒吗 如是则执行速度
似乎并不 快 怎么估计出来的呢
A:如果程序和数据均在片内RAM 中,这样计算:
1.一般指令需1 个主时钟时.
2.每次跳转增加3 个主时钟时间(也许是2 个,需要确认).
3.从RAM 中取一个操作数多增加一个主时钟时间,以此类推.
4.保存一个结果到RAM 中多增加一个主时钟时间,以此类推.
5.访问片内外设,增加一个外设时钟时间.
注意伪指令ldr rn,=x 需要从ram 中取一个操作数.
第188 问:
Q:请问如果lpc2104 和5V 的芯片字节连接,中间不接小电阻,会怎样 对系统有没有很大
的影响
A:不安全而已.
第189 问:
Q:2104 的功耗最大在多少,(考虑外设全部工作,功率损耗)
EASY ARM 板上提供的电源最大输出电流好象只有300mA 哦.
A:芯片本身功耗最大值小于70mA(120 摄氏度,核2.1V 供电,运行于60MHz).一般情况
小于50mA.
IO 口耗电(即3.3V 耗电)与其它电路密切相关,实质是其它电路在消耗电源(ARM 本身
对3.3V 的消耗是极小的).
46
第190 问:
QPC2114 替换LPC2104 的话,我的程序还需要做哪些变动
哪些内部专用寄存器的地址是否变动
还有,我原来设计电路用的是LPC2104 的次要JTAG 口,现在换到LPC2114 上来,需要怎
么改电路
A:程序无需改动,JTAG 设计时在RTCK 接一个4.7k 的下拉电阻即可.
第191 问:
Q: 有一问题请教,在市场上买的ARM 核单片机的程序用ADS1.2 建立项目,添加初始化程
序vectors.s, init.s,target.c 和target.h 后再写自己的主程序,编译烧录到ARM
中即可投入使用了吗 而有的ARM 嵌入式系统中还有bootloader,那是不是利用ARM 开
发的产品都要bootloader,而bootloader 是通过什么软件编译的
我所买的easyarm 开发板的lpc2104 中有bootloader 吗
A:bootloader 是用来下载程序到FLASH 中的,LPC210x 具有ISP 功能,可直接使用ISP 下
载程序,不需要自己编写bootloader.
第192 问:
Q:我想用IAP 把数据存到2104 的FLASH 里,可我怎么读出来呢
A:定义一指针,指向你用IAP 写数据的那个区域,就可以读了.
第193 问:
Q:当PLLCFG 设置为0x05 时的效果和设置为0x25 时一样,但晶振是11.0592MHz 的,如果
设为0x05, Fcco 的范围不在156M-320MHz,为什么还可以用,而且和其它没有区别
A:手册说明的是保守值.实际的芯片的Fcco 可能在更大的范围可以工作.
第194 问:
Q:WDT 复位后从地址0 开始执行吗 运行程序5.40 后,WDT 复位后并不是从地址0 开始执
行,却跑去执行
[0x07806808] dcd 0x07806808,
并一直执行此语句.如何才能从地址0 开始执行
A:WDT 复位后是从0 开始执行程序.可在复位处设置一些外部现象(如LED 闪烁),然后脱
机运行.
第195 问:
Q:我运行光盘上原始的IAP 程序例子,使用它的project 是正常的,但我自己重新建一个
目录和project,参数设置按照原来工程的设置,编译出来的axf 文件就是会在运行到
第一个 SelSector(1,1)时无法继续下去,我自己的axf 文件和光盘上的一样大16kB,
究竟是怎么一回 事 有一处设置Language Settings 里的ATPCS 项有什么意义 其他
47
工程好像没有选择这一项.
A:IAP 是THUMB 指令,如果用户程序是ARM 指令,所以调用时需要使用BX 指令.则C 编译
器的ATPCS 项要设置"ARM/Thumb interwork...".
第196 问:
QPC2104 具有6 个PWM,可以应用与电机控制,可是却没有计数器进行电机转速的PID
闭环控制, 这个情况是不是lPC2106 的一个缺陷呢 如果不是,那应该怎么样才能进
行外部脉冲的计数 在不用外加计数器的情况下! 很是困惑!
A:捕获算周期.
第197 问:
Q:ISP 通讯的问题.
自己做的板子,使用ISP 下载程序,提示无法通讯.板子上使用了跳线使得44 脚和地连
通,也通过max3232 进行电平转换了.还有复位电路感觉也一切正常.不知道为什么就
是无法通讯.好晕啊,各位成功下载的大侠们指点一下吧.试了好几天了,都没法成功.
A:你确保了max3232 过来的电平正确了吗 如果正确了,还要确保通信方向是否弄反,最
后注意复位信号是否正确.
A:搞定了,原来是max3232 的问题,现在已经可以下载程序了!
第198 问:
Q:如何用ISP 软件擦除FLASH 中的内容啊
我在调试UART0 串口程序的时候出现问题,上网看到很多文章都建议要先擦除FLASH 中
已有的内容,于是用ISP 软件进行擦除.但是在使用该软件过程中,按到很多钮都说:
串口不能正常工作.
这是什么原因啊 请教高手正确使用ISP 软件的方法及注意事项.
A:看看你的跳线是不是按要求接好了!!
第199 问:
Q:EasyArm2104 开发板上的ISP 下载的时候通讯不上.请问,要跳JP6 吗
A:您可以自己试一下:
1.是不是接的UART0 口
2.系统晶振(XATL.Freq)是不是11059.2kHz
3.串口选择是否正确
4.要求你复位的时候你是否有复位
5.ISP 使能跳线使用JP1(JP6 和JP7 保持主JTAG 调试状态)!
第200 问:
Q:请教高手,lpc2104 和lpc2114 外部晶振接法
原来我用LPC2104 做的板子,外部晶振接到X1 时不可用.后来接到X2 上时好象可以用,
但这与资料上的说法好象有点出入.现在我想换LPC2114 改版,但不想再次改版了.故
在此请教外部晶振接法
48
A:使用外部无源晶振,晶振两个管脚无需连接,与51 单片机基本一致;时钟信号由X1 输
入.
第201 问:
Q:请问有没有工业级的21**系列
A:lpc2114 等芯片就是工业级的.
第202 问:
Q:读LPC2119/2129/2194/2292/2294 使用指南之迷惑.
1. 对于2292/2294,开放了外部总线,程序应该可以放到外部,外部和内部的存储空间
地址不连续,如何保证程序超过128K 后自动跳转到外部执行程序
2. VIC 部分,VIC 通道号17#和18#都是EINT2,是什么意思 难道一个中断源占2 个号
EINT3 的VIC 通道号是多少
3. 我购买的芯片是否内部已经有了Boot 装载程序
A:1.使用分散加载.
2.可能是笔误.
3.有.
第203 问:
Q:请问用LPC2104 扩展D12 有没有问题
A:可以使用模拟总线,速度比51 快几倍.
第204 问:
Q:请教PC2114 的V3 能否接2.8V
系统有多个外设,有一个使用2.8V±5%的电平接口,其它使用3.3V,那么LPC2114 的
V3 怎样接
V3 接2.8V 电压基准是否可以,口线与其它3.3V 的接口能否直接相连
A:建议不要超出手册说明的范围使用芯片.
第205 问:
Q:我自己做的板子,把2104 的44 脚(EINT1)接地,再利用LPC210XISP 软件通过串口0
往芯片里写程序,为何按了复位键以后连芯片的ID 都不能读到
A:应该检查如下几点:
1. 确保你的芯片在工作.一般可以查看芯片的几个电源是否都正确,查看晶体是否有
波形, 最好还可以看看各电源的纹波是否严重.
2. 确保电平转换芯片的正确工作,以及各输入输出的正确.这个方向最容易弄反.
3. 查看复位端的电平是否正确,复位按健正常.
4. 确保44 脚接地.
49
第206 问:
Q:请教如何通过2104 的串口1 来往芯片里写程序
A:使用ISP 功能,不能用串口1,只能用UART0.
第207 问:
Q:请教ARM2104 配套《ARM 微控制器基础与实战》上第一个实验的问题.
在ADS1.2 中编译以下程序后进入AXD 进行调试成功.
程序稍加修改,使LED1..LED4 同时闪烁,在ADS1.2 中编译以下程序进入AXD 调试成功.
问题:两个程序的软件延时部分相同,但两个程序使LED 的闪烁间隔时间不同,不知是
何原因
A:可以先使用ISP 将芯片FLASH 擦除试试,可能是FLASH 程序设置PLL 的缘故.
第208 问:
Q:1.《ARM 微控制器基础与实战》上说32 字节的向量表的累加和必须为0 才可脱机运行,
是否需要每次修改程序后修改第六个保留向量的值(因为地址有改变).
2.《ARM 微控制器基础与实战》上说用ldr pc, resetaddr 指令代替b 指令可全空间跳
转,但是我看指令说明ldr 指令的地址只能是当前地址的+-4k 呀!
A:1.不用修改.
2.请看书.
第209 问:
Q:关于2119 的can 的通讯问题,就是2119 的波特率的设置与SJA1000 有什么不同
A:基本上一致,将ARM7 的Fvpb 与SJA1000 的晶振对比:
BRP,SJW,TSEG1,TSEG2 均是同样的设置方法,需要计算,可参照SJA1000 中位定时参
数的计算方法.
第210 问:
Q:请问各位高手.新买的ARM 芯片是不是直接安装上去就可以直接下载程序工作了了吗,
还需要有什么别的设置吗.
APC2000 系列有片内FLASH 的都可以直接ISP,不过要保证硬件正常.
第211 问:
Q:2119 实时时钟电池怎么供电 所有的电源引脚都要供电吗
A:没有独立的电池供电引脚,以后会推出RTC 独立晶振和备份电源接口的型号.
不太适合电池供电,除此以外,功能还是很强的.
第212 问:
50
Q:在调试实验程序的时候,把低功耗掉电模式实验代码PDRUN 编译后下载到2104 FLASH
以后,程序正常运行了.可是再DEBUG 程序时,在AXD 下总是提示错误:
Error:flash is user configured protected
我能明白这个是因为2104 一直处于掉电模式的原因,可是如何解除这种状态,把现在
FLASH 里的这段程序擦除掉啊
A:通过ISP 软件擦除.
第213 问:
Q:请教关于"IAP 实验的问题"
《ARM 微控制器基础与实战》359 页的IAP 实验是用汇编写的,然而在光盘上IAPtest
实验的程序是用C 编写,其中提到本实验是调用IAP 服务程序.请问:
1. IAP 服务程序放在了什么地方(汇编部分)
2. 我想向其中写入10 字节数据,而不是诸如256 个字节,是否可以,如何实现
3. 在主程序中定义一个数组,如何把此数组中的数据固定在特定地址中阿,然后我好
进行RamToFlash.
A:1.在BOOT 区,入口地址为0x7ffffff0,IAP 服务程序为THUMB 指令.
2.先读取原数据到RAM 中.如果只需要保存小量数据,且经常要更改,最好使用外部
E2PROM.
3.可能不好实现,参考ADS 帮助手册吧.
第214 问:
Q:请问LPC2104 系统为什么采用11.0592Mhz 的晶振,是在定时上有优势还是其他原因.
A:选用11.0592MHz 只是为了得到精确的通信波特率,串口通信的可靠性高.
第215 问:
Q:请教:lpc2104 和RTL8019AS 的接口问题.
以前在C8051F 上做,高低地址是固定的,容易接口,RTL8019 映射地址也容易算出.现
在lpc2104 是32 位的,32 个地址线和32 个数据线,和外围器件接口时带到很困惑.不
知有没有高手看过周立功网站的提供的lpc2104+RTL8019AS 的接口电路,SA0-SA4 和
lpc2104 的哪个脚接在一起 请指点由一个573 来控制地址与数据总线复用现在有点明
白虚拟总线了,加上一个地址锁存器,和51 机的就很相似了.
A:对,为了兼容51.
第216 问:
Q:开发板上的74HC125 的U5C,U5D 起什么作用
A:去抖动.
第217 问:
Q:请教:在2100 开发板的ADC 实验(P119 面)中为什么每次AD 转换都要启动两次
51
A:切换通道后,丢弃第一次ADC 转换值.
第218 问:
Q:如果我的AD 转换需要的满量程是0V~5V,是不是把AD 部分的电源即V3A 由现在的3.3V
改为5V 供电就可以了
A:把输入的电压用电阻分压就可以了.
第219 问:
Q:疑问:2104 开发板上用了MAX708,其已有高/低电平复位输出,为什么还要用74HC125

A:为了使手动与JTAG 都可以对芯片复位.
第220 问:
Q:请教高手关于自己做板子的问题.
我自己做了一个2104 的板子,第一次上电可以通过串口顺利地把 .hex 文件从串口写入
flash, 然后再次上电,程序就不执行了,并且再次用周立功公司提供的ISP 软件却
无法访问该芯片.同样地程序我放到周立功地2104 的开放板用同样的步骤,它却能正常
运行,我的板子基本上是按《ARM 微控制器基础与实战》上的图制作的,请指点我的问
题可能的原因在哪里 请教自己做板子容易出错和注意的地方.
A:重新上电试试.
P0.14 口是否已接为低电平
测一下晶振是否起振
Q:晶振测过已经起振,运行自己的程序不是要把P0.14 口断开吗 用ISP 软件下载程序的
时候才把P0.14 接地是不是
A:需要ISP 时P0.14 口接地;
需要运行用户程序时,P0.14 口要接一个上拉电阻,因为P0.14 内部无上拉(作为输入时).
第221 问:
Q:请问2104 的复位电路我不用MAX708 和74HC125,做成象51 单片机那样的复位电路可以

A:做成这样是为了保证JTAG 接口和按钮,上电都可以复位芯片!
实现线与逻辑,如果你不需要调试只是生产的话,完全可以那样设计复位电路.
第222 问:
Q:关于REMAP
请问remap 的时候只要给MEMMAP 赋值就好了吗 具体的中断向量表的映射系统自动给你
生成
在启动代码中关于remap 我只看到赋值,而在《ARM 微控制器基础与实战》上写了一段
重映射的代码示例P280 程序清单5.2.
52
如果系统自动remap 的话,那么映射到的地址空间我们没法改动了
代码中,通过B lable1 或bl Lable2 进行跳转时,要不要进行栈的操作
如果调用的是c 语言函数,除了传递必要的参数,有没有保存寄存器呢
A:中断向量表不是系统自动生成的,是由用户编写.Remap 通过改变MEMMAP 的值实现.
请看一下"ARM-Thumb 过程调用标准"(ATPCS.pdf)这篇文档.安装ADS 后就有.
第223 问:
Q:请问:lpc2104 运行速度
ARM7TDMI(-S)能提供0.9MIPS/MHz 的指令执行速度,lpc2104 cclk 为60MHZ 时指令执行
速度应为0.9*60 = 54 MIPS,这样得到一条指令的执行速度大概为0.018us.可我用示
波器观察计算得出一条指令的执行时间远远大于这个数值,大概为0.1us-0.8us(可能由
于流水线的影响,指令执行时间的差别很大).这是怎么回事呀
A:这是一个在存储器带宽足够时的平均值.如果程序和数据均在片内RAM 中,这样计算
1. 一般指令需1 个主时钟时间
2. 每次跳转增加3 个主时钟时间(也许是2 个,需要确认)
3. 从RAM 中取一个操作数多增加一个主时钟时间,以次类推
4. 保存一个结果到RAM 中多增加一个主时钟时间,以次类推
5. 访问片内外设,增加一个外设时钟时间
注意伪指令ldr rn,=x 需要从ram 中取一个操作数.
在flash 中如果MAM 配置为最优,平均速度与在ram 中相差无几.
第224 问:
Q:请教斑竹关于211x 和22xx 系列P1.16-P1.25 这些引脚的作用
另外在开发版上除了JTAG 口外,上述引脚是否用到
在设计自己的系统时,如果将P1.16-P1.25 这些脚作为普通输入输出口用,是否会影响
系统的调试
A:ETM 跟踪端口.
一般JTAG 仿真器不使用这些引脚,所以设计自己的系统时用作I/O 即可.不会影响调试.
第225 问:
Q:请问,请问评估板上的S-1131B 哪里能订购到,或者有什么替换型号.谢谢
A:SPX1117M3_1.8 和 SPX1117M3_3.3.
http://www.zlgmcu.com/Sipex/power/SPX1117.asp
.
第226 问:
Q:关于 P2104 的驱动能力!
我正在用2104 外接LCD 其中用P0 口模拟总线 我的了LCD 电压是5V 的,而2104 是3.3V
的,能否直接相接 我没接时还有信号输出但接上之后就什么信号都没有了,请问是何
缘故 是否需要电平转换芯片或驱动芯片 上拉电阻能否满足要求
A:中间串一个小电阻试一试.我们接过多种总线器件都没有问题.
53
第227 问:
Q:问一下,lpc2104 的I/O 的驱动能力
单个I/O 可以走多大电流
全体I/O 可以走多大电流
A:数据手册上有,Ioh,Iol.
第228 问:
Q:2119 最高频率可达60MHZ,在频率比较高的时候应该使用几层的电路板,有没有确切的
规定
A:不知道什么时候有人就把PCB 的层数与频率划上了一个必然的关系.60MHz 很高吗
看看你的调频收音机,FM 波段范围是88-108MHz,内部部本振频率可达118.7MHz,1
层板!看看电视机里头的电路板,高频盒内一般最多就2 层板(还是一层的居多)它跑
多高的频率 自己查查UHF 的范围吧,记得保持冷静因为没有什么值得去惊讶的!再有
几年前拆过一个GIGA 的游戏机,音频部分的PCB 是4 层板(独立的小板),小日本的东西
元器件密密麻麻的,看看这个它又能是跑多高的频率 况且现在数字电路的电平容差相
对于模拟电路的至少有一个数量级的差别.在高频模拟电路下,多一块覆铜可能就使电
路的性能下降或工作点异常,例如它可能使电感特性器件的Q 值下降,产生涡流耗损等.
很多时候增加PCB 的层数决不是单纯因为系统速度,你所说的60Mhz 也只是芯片内部的
系统时钟, 难道你的IO 也要作为时钟源使用吗 在ARM 中采用PLL 技术使得外部时
钟可以下降到一个较低的水平,则可以抑制部分由时钟电路产生的射频干扰,有较好的
EMC,EMI 特性,一个合理的PCB layout 可能比盲目增加PCB 层数的方法提高系统的稳
定性来得更合理和有效!看你是想做精品还是想做产品或其他,这就要综合多方因素考
虑了.
无可否认,增加PCB 的层数后比较容易的处理一些由于电源寄生干扰产生的问题,适当
配合layout 可以满足一些速度(时序)要求苛刻的电路.由于现在元器件体积日渐小
型化,PCB 上元器件密度大,很多时候单面或双面的layout 实现已经非常困难,增加PCB
层数是为了更好的使设计变得合理和可靠.
第229 问:
Q:ARM 抗干扰能力怎样,是否低压器件一定比高电压器件抗干扰能力弱 谢谢!
A:我们用自己的开发板打群脉冲到最高都正常工作(程序没有任何抗干扰措施).
第230 问:
Q:我刚刚设计完了一块LPC2106 的电路板.在用EASYARM 仿真器通过JTAG 接口调试没有能
够使用,但是通过JTAG 口下载到FLASH 后上电复位却不能正常工作,手动复位也不行.
同样的程序在购买的实验板上完全可以使用.不知道是怎么回事.我初步怀疑是复位电
路问题,但不知道怎么解决.
A:问题解决了!只要将P0.14 上拉到高电平就可以了.
54
第231 问:
Q:VPB 是什么意思 英文全称是什么
A:VPB (VLSI Peripheral Bus)
第232 问:
Q:请问大侠们,2104 怎样与5V 的外设连接,多谢!!
下一个产品想用2104,可是用惯了51,不知怎样与5V 外设连接,多谢!!
A:可以考虑使用3.3V 至5V 的缓冲器件如4245,最简单的方法就串上个小电阻.
第233 问:
Q:请教大家:LPC2104 芯片中的PWM 有中断功能,请问输出置PWM 匹配通道的中断标志有
什么意义,有什么作用
A:举个例子,如果 使用PWM 滤波 生成正弦波,有中断,就方便很多!
55
第5 章 GPIO
第234 问:
Q:我是在LPC2119 与光隔相连时遇到的这个问题,以前用的片子IO 口都是5V 电压,由于
2119 是
3.3V 所以和以前系统中采用的高速光耦相连时就涉及到两个问题:
接受光耦送来的信号2119 可否承受
还有2119 输出的信号能否驱动光耦
搞CAN 的朋友可否同样遇到此问题,我觉得可以解决这个问题,但不敢肯定,我想通过
分析光耦内部结构可以解决这个问题,有经验的朋友谈谈吧
A:可以将 CAN 引脚当成普通 IO 口对待,就不会存在疑惑了.
第235 问:
Q:LPC2119 的IO 口输出电压是多少,我在数据手册上没有找到
还有它的IO 口带不带上拉电阻
A:GPIO 输出可输出高电平电压约为3.3V,手册上的Voh.
GPIO 作输入时没有内部上拉.
第236 问:
Q:请教:LPC2214 的P2,P3 作为普通IO 时,怎么设置输入输出方向 没有找到它们的IODIR!
A:与P0 一样,请下载工程模板,内有头文件.
第237 问:
Q:请问:LPC2214 的GPIO 的管脚在输入时没有上拉,在输出时有没有上拉
好像在资料里说的都没有上拉.
A0.2,P0.3 是I2C 接口,是开漏输出,所以要外接上拉电阻,其它GPIO 不用接.
第238 问:
Q:LPC2104 实验板接上JTAG 线时,P0.22 变为0 我在测试键盘时发现的,一拿下JTAG 插
头,一切正常.
A:使用主JTAG 调试时,P0.22 为ETM 跟踪调试口,不能作GPIO 用.
第239 问:
Q:请教LPC2214 的P2/P3 口做I/O 口扩展而不是EMC 怎样访问 手册上没有找到,只有P0/P1
的访问方法.
A:同P0 口一样.请下载"EasyARM2100 开发套件快速入门和L...",里面的头文件有其地
址的定义.
56
第240 问:
Q:GPIO 哪些内部有上拉,哪些没有
A:《ARM 微控制器基础与实战》中说的明白,都没有上拉电阻的,不过是推挽输出的,输入
0,1 都没问题,放心!
第241 问:
Q:因为看到LPC2114 外围电源用的是3.3V 供电,而我想用它的I2C 接口去控制后面用5V
供电的芯片,因此想问一下是否可以直接接上拉电阻和5V 相连 如果不能是不是只能加
电平转换了 谢谢!
A:可以.
第242 问:
Q:当外部有数据送到IO 口时,是不是通过读寄存器IOPIN 就可以得到其IO 的当前状态呢
A:你说的对,但是要将你要用的IO 口设为GPIO(PINSEL0/PINSEL1)方式,并将其设为输
入方式(IODIR),就可以了.不过要是你用的IO 口不连续的话,要将输入的管脚状态处
理一下才是你要的字节或是字数据.我就是用这种方式扩展外部CAN 总线器件的.
第243 问:
Q:当用用GPIO 时,输出电流是多大呢 急用!
A:数据手册上有,Ioh = 4mA.
第244 问:
Q:请教:2104 的IOPIN 这个寄存器为什么老是一个值.
我的IO 不断变化,他就是不变,不知为什么
A:我认为可能是IODIR(管脚方向寄存器)和PINSEL0,PINSEL1(管脚功能寄存器)中的
一个寄存器没设置好吧.
第245 问:
Q:可以直接把+5V RAM/FIFO 的数据线和2104 连接吗(模拟总线时)
A:我做过外接RAM 的实验,RAM 输入的直接连,输出到ARM 的串电阻.
第246 问:
Q:我用2104 的时候,怎么设置IO 口,比如例子上有一个:#define LEDCON 0x00002000.
为什么设置P0.13 的时候要定义为0x00002000,是怎么计算的.谢了
A:右移13 位(1  6)/a_mode->ubps;
U0DLM = tmp >> 8;
U0DLL = tmp & 0xff;
70
tc = a_mode->data_bit;
tc |= a_mode->stop_bit;
tc |= a_mode->parity_bit;
U0LCR = tc;
VICIntSelect = 0x00000000; // 设置所有通道为IRQ 中断
VICVectCntl0 = 0x26; // UART0 中断通道分配到IRQ slot 0,即优先级
最高
VICVectAddr0 = (int)IRQ_UART0; // 设置UART0 向量地址
VICIntEnable = 0x00000040; // 使能UART0 中断
A:要在VECTOR.S 文件中打开IRQ 中断.如"MSR CPSR_c, #0x5F"
第271 问:
Q:我用开发板自带的一个程序Debug 调试,然后AXD 提示:
Warnning! interrupt vectors data is not correct!
Program you downloaded can not run freely!
我不知道其中中断向量的地址是如何算出来的,也就是说程序中的异常向量所指向的位
置我不清楚.我买的《ARM 微控制器基础与实战》中提到这儿有一句话解释了下面的程
序:在保留的异常向量位置填数据0xb9205f80,是为了使向量表中所有的数据32 位累
加和为0.(没明白,0xb9205f80 是如何计算出来的!)
Vectors
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC, FIQ_Addr
ResetAddr DCD Reset
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Nouse DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
A:从mem 窗口看这些地址是什么数(32 位方式),然后加起来.
第272 问:
Q:我将光盘里的EINT1 中的:
71
config,init.s,
LPC2106.h
target.c
target.h
vectors.s
eint1_led.c
加入项目中,设置的编译环境为:debug, Release DebugRel 中的R0 base 为0x40000100;
Rw base 为: 0x40003000;Image entry point 为0x40000100.编译通过,调试,f5 出
现第一个默认断点,在全速执行,程序在while(1) ;循环,按k1 键led4 不闪烁,我
想是没有进入中断,但我不知道这是为什么,另外我将r0base 设为0x40000100 是认为
0x40000000 到0x40000100 之间要放置remanp 后的中断向量表,不知道这样做对否.
A:如果设置robase 设为0x40000100,那么你要把向量表的代码复制到0x40000000,然后
再REMAP 操作.另处用我们的EasyJTAG 暂时不能单步调试中断,否则会破坏VIC 的状态.
请用先设置断点,然后全速执行的方式调试.特别注意不能在0x18 处设置断点(别的仿
真器也不能在这设置断点,否则破坏VIC 的状态).
第273 问:
Q:贵公司网站上提供的可固化的中断程序中,是将中断向量表先拷贝到0X40000000,再
REMAP 到FLASH 的底部(我的理解).我认为既然是固化到FLASH 里,把完成上述功能的
程序去掉不是也可以吗
即下面的程序段:
; 实现REMAP 操作
REMAPS MOV R2,#0x40000000 ; 复制中断向量代码,设置目标地址
LDR R1,=Vectors ; 设置源地址
LDMIA R1!,{R3-R10} ; 共复制16 个字(64 字节)
STMIA R2!,{R3-R10}
LDMIA R1!,{R3-R10}
STMIA R2!,{R3-R10}
LDR R2,=MEMMAP ; REMAP 操作
MOV R1,#0x02
STR R1,[R2]
A:可以去掉,只是这样做可以动态改变向量表.
第274 问:
Q:在《ARM 微控制器基础与实践》中的157 页,在0X0000018 处加LDR PC,[PC,#-0XFF0]
指令,为什么就会将VICVectAddr 寄存器中保存的地址装入PC
A:like this:
VICVectAddr = 0xFFFFF030
0x00000018+0x08-0xFF0 = 0xFFFFF030
therefore PC = [FFFFF030]
72
A:为什么不能进入中断,init.s,target.c 都是贵公司的提供的启动代码!!!
向量的初始化为:
Vectors
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xB8A06F58
LDR PC, [PC,#-0xff0]
LDR PC, FIQ_Addr
ResetAddr DCD Reset
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Nouse DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
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
主程序如下:
void __irq IRQ_Handler(void)
{
}
73
void __irq Time1_Handler(void)
{
}
int main(void)
{
.
.
.
T0PR = 99;
T0MCR = 0x03;
T0MR0 = 110592/2;
T0TCR = 0x03;
T1PR = 99;
T1MCR = 0x03;
T1MR0 = 70000;
T1TCR = 0x03;
T0TCR = 0x01;
T1TCR = 0x01;
VICIntSelect = 0x00000000;
VICIntEnable = 0x00000030;
VICVectCntl0 = 0x00000022;
VICVectAddr0 = (int)IRQ_Handler;
VICVectCntl1 = 0x0000002f;
VICVectAddr1 = (int)Time1_Handler;
while(1);
}
A:the Problem may be the channel selection
VICVectCntl0 = 0x00000022; may be VICVectCntl0 = 0x00000024;
VICVectCntl1 = 0x0000002f; may be VICVectCntl1 = 0x00000025;
第275 问:
Q:断点如果设置在启动时钟节拍之后,在断点处停顿后在继续运行,程序运行就异常了,
这是什么原因
A:不是不中断,而是时钟走过头,还需很长时间才中断.target.c 如下修改即可避免:
T0MCR = 0x01; 改为T0MCR = 0x03;
函数 Timer0 改为
void Timer0(void)
{
T0IR = 0x01;
// T0MR0 += (Fpclk / OS_TICKS_PER_SEC); // 删除此句
74
VICVectAddr = 0; // 通知中断控制器中断结束
OSTimeTick();
}
第276 问:
Q:请教寄存器VICVectAddr 和VICVectAddr0~15 的使用区别,看文档没有明白,谢谢!
A:VICVectAddr 在发生中断时,存放有服务程序的地址(来自VICDefVectAddr 或
VICVectAddr0~15);而VICVectAddr0~15 是存放各个向量中断服务程序地址的寄存器,
当发生向量中断时,相应的地址会自动装载到VICVectAddr 中.
第277 问:
Q:在一个程序中同时编入两个中断时,不知道如何将一个中断的优先级设定高于另一个中
断.
例如:外部中断和定时器的中断.
A:VICVectCntl0~15 优先级递减,参看实验程序IRQ2_test.
第278 问:
Q:还有在AXD 环境下,单步执行怎么起不了作用,会跳到void IRQ_Exception(void)里面

A:有中断时不能单步调试,否则VIC 工作异常.
第279 问:
Q:我想问向量表累加和是如何计算的
A:前8 个字的32 位机器码相加.
第280 问:
Q:我把程序下载到FLASH 中发现MEMMAP 的值是01,可是我把程序下载到RAM 时发现MEMMAP
的值是0;不过程序都能运行.我这个程序没有中断,是不是如果我的程序中有中断而
且在RAM 中运行时就必须修改MEMMAP 同时拷贝向量表到0x40000000 呢 如果程序中没
有中断并在RAM 中运行时就可以不管MEMMAP 的值了阿
A:是的.
第281 问:
Q:为什么在EINT1 中断实验程序中,中断函数里没有VICVectAddr=0x00;是因为它是非向
量中断吗
A:因为它根本没有使用VIC 的VICVectAddr 来判断中断服务程序入口.
75
第282 问:
Q:当我作向量IRQ 中断实验时,将EINT0 设为最高优先级,EINT1 次之.我在IRQ_Eint1(void)
函数中加入一条while(1)指令,想作一下优先级差别的实验.我先让EINT1 中断,这时
进入IRQ_Eint1(void)函数中,并产生死循环,然后我按下KEY3 想产生EINT0 中断,结
果却没反应,我已经将EINT0 的优先级设成了最高,为什么不进入EINT0 中断函数
A:有没有允许中断 进入中断后处理器自动设置cpsr 中的中断允许位,禁止中断.
第283 问:
Q:执行FIQ 代码时,操作系统在做什么呢 当执行FIQ 中断代码时,需要注意什么呢 要
对相关寄存器进行入栈吗 那执行完了以后,又怎么返回到OS 里执行任务呢 FIQ 可不
可以调用OS 函数 IRQ 呢
A:1.FIQ 服务程序中断了OS 啊.
2.FIQ 中断服务不在OS 管理范围内,所以不能访问任何与OS 相关的函数及变量.
3.FIQ 其实就是普通的FIQ 中断服务函数而已,与普通的一样处理.
4.受OS 管理的IRQ 可以调用 OS 的系统功能函数.
第284 问:
Q:请问,在vectors.s 程序中中断向量操作如下:
Vectors
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC, FIQ_Addr
ResetAddr DCD Reset
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Nouse DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
;未定义指令
Undefined
B Undefined
;软中断
SoftwareInterrupt
B SoftwareInterrupt
PrefetchAbort
76
B PrefetchAbort
;取数据中止
DataAbort
B DataAbort
;快速中断
FIQ_Handler
STMFD SP!, {R0-R3, LR}
BL FIQ_Exception
LDMFD SP!, {R0-R3, LR}
SUBS PC, LR, #4
现我将它改为
Vectors
LDR PC, =Reset
LDR PC, =Undefined
LDR PC, =SoftwareInterrupt
LDR PC, =PrefetchAbort
LDR PC, =DataAbort
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC, =FIQ_Handler
;未定义指令
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
程序编译可以通过,用AXD 调试时报告不能自由运行,可以仿真运行.
按我的理解DCD 前面为地址(也就是指针),DCD 后面为4 个字节的内容(指针的值),
LDR PC,ResetAddr
LDR PC,=Reset,
都是采用间接寻址,也就是将Reset 的地址放进PC,为什么"LDR PC, ResetAddr"地
址从中间转一道就对了而"LDR PC, =Reset"就不对,既然不对为什么还可以仿真,而
77
脱机运行就不行
A:因为异常向量表累加和不为0.详细看一看5.1.3 节或6.3 节.我记得以前也有一个类
似的帖子
可以参考.
第285 问:
Q:是不是FIQ 与IRQ 的使用上没有什么区别
FIQ 自己独有的寄存器有什么用
我是否可以把INT1,UART1 等中断设为FIQ
FIQ 的中断服务程序应该定位到什么位置
A:没有本质的区别.
FIQ 拥有独立的R8_fiq~R12_fiq,FIQ 中断时,其它模式相应的寄存器就可不入栈,从
而加快FIQ 的处理.多个中断源共用还不如单独用IRQ.因为FIQ 比较适合在人命关天
的情况下用.
第286 问:
Q:这是VECTORS.s 中的一段,里面的REMAP 操作都做了些什么 好像是保护一类的操作.
REMAP 和MEMMAP 各是什么含义 如果我要同时使用两个外部中断,应当怎样写这一段
REMAPS MOV R2,#0x40000000
LDR R1,=Vectors
LDMIA R1!,{R3-R10}
STMIA R2!,{R3-R10}
LDMIA R1!,{R3-R10}
STMIA R2!,{R3-R10}
LDR R2,=MEMMAP
MOV R1,#0x02
STR R1,[R2]
MSR CPSR_c, #0x1f
MOV PC, R0
A:REMAP 是重映射的意思,MEMMAP 是存储器映射控制寄存器.
MEMMAP = 0b01,不映射,程序由FLASH 开始.
MEMMAP = 0b10,程序从RAM 开始,如果你的程序在RAM 中,必须使用这种方式.
如同时使用两个中断,这一段也不用改.
第287 问:
Q:特定的异常出现时,处理器进入相应的异常模式.如出现IRQ 就进入IRQ 模式,那出现
什么情况进入管理模式呢
A:复位或SWI 中断.
78
第288 问:
Q:请问什么时候需要通过软件中断进入管理模式
A:如果你的程序是在用户模式下运行,那就可以通过软中断进入特权模式,修改CPSR 寄存
器.如开关IRQ 中断(CPSR 的I 位).
第289 问:
Q:软件中断是用软件置位的方法产生中断请求,比如定时器0 中断请求.用软件中断的方
法可以产生IRQ, FIQ 中断,对吗
A:VIC 中的软件中断是这样,而swi 产生的异常,英文也为软件中断,它是不一样的.
第290 问:
Q:我现在在看ads 编译器文档中的swi 部分,我理解软中断就是一种预期发生的中断而一
般中断是不可预期的,对吗
A:可以这样说.
第291 问:
Q:为什么以下的程序进不了中断
/**********************************************************
*修改说明 加中断
*修改目标 我是想每发一个字符就让LED 变换一次,现在结果是
* 仍正常发送字符,但没有中断效果,为什么呢
* 哪位帮看看!先谢谢了!
**********************************************************/
#include "config.h"
#define HC595_CS 0x00000100
#define LEDCON 0x00000400 // LED1~LED4 设置为输出
void DelayNS(uint32 dly)
{
uint32 i;
for(; dly > 0; dly--)
for(i = 0; i < 50000; i++);
}
/**************************************************************************
*初始化SPI 接口
**************************************************************************/
void MSpiIni()
{
SPI_SPCCR = 0x52; // 设置SPI 时钟分频
SPI_SPCR = 0xB0; // 配置MSTR = 1 CPOL = 1 CPHA = 0 LSBF = 0
}
/***********************
79
*功能

你可能感兴趣的:(arm常识)