guet的笔记 https://bbs.21ic.com/?477754 [收藏] [复制] [RSS]

日志

ARM问答2

已有 6036 次阅读2006-11-14 22:30 |个人分类:嵌入式|系统分类:ARM

第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
......

我想问一下:LDR 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中,我编译时出现错误提示如下:
ERROR:L6221E: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,我想再装回去.
A:DebugInFLASH就已经把程序下载到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问:
Q:LPC2114替换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问:
Q:LPC2104具有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:请教:LPC2114的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芯片是不是直接安装上去就可以直接下载程序工作了了吗,
还需要有什么别的设置吗.
A:LPC2000系列有片内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的管脚在输入时没有上拉,在输出时有没有上拉
好像在资料里说的都没有上拉.
A:P0.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

*功能

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)