1>> ARM 的数据类型
ARM 处理器支撑6种数据类型; 8位有符号和无符号字节。 (char, unsigned char)
16位有符号和无符号半字,它们以2字节的鸿沟对准。(short int, unsigned short int)
32位有符号和无符号字,它们以4字节的鸿沟对准。(int, unsigned int)
typedef unsigned char uint8; /* 无符号8位整型变量 */
typedef signed char int8; /* 有符号8位整型变量 */
typedef unsigned short uint16; /* 无符号16位整型变量 */
typedef signed short int16; /* 有符号16位整型变量 */
typedef unsigned int uint32; /* 无符号32位整型变量 */
typedef signed int int32;
2>> 关于存储器重映射我不太了解,为什么要有重映射什么时分用得到重映射?一开始向量表到底是在boot block里仍是在0x00000000处啊。
答:CPU 一发动,总是要从0地址处取指令来履行。那么,假定我想让CPU一发动就从地址a处履行指令,怎样办?
我刚刚现已说了,无论如何,一发动,CPU 都是从0地址处履行指令的。那么,有办法了:令这个地址a处的存储器,地址为0就能够了。这就如同把门的号码牌0贴到了a号房间。服务员并不论号码牌0贴 的房是什么,而只依据房间号来进行服务就能够了。
所以,尽管CPU仍是从地址0处履行,但是地址0指着的目标改动了。所以CPU一发动,就能够从 地址a存储器里取指令了。因此,存储器重映射,便是改动了地址0指着的目标,改动了号牌贴着的房间。
3>> 假如,我在JP1接通即p0.14为低的时分按了reset键怎样办,岂不是进入isp形式了,我的JTAG仿真器就不能用了是吗?
答:在ISP 形式中依然能运用JTAG调试。
4>> 关于外部中止的INT0电平中止,《根底教程》上也有这么一段例程,PINSEL1=(PINSEL1— 0XFFFFFFFC)|0X01;EXTMODE=EXTMODE &0X0E;我不明白的是,为什么设了电平中止却不用EXTPOLAR阐明是低电平中止仍是高电平中止呢。假如不设的话是否凹凸电平都会触发中止 仍是怎样样。
答:有一个外部中止极性寄存器EXTPOLAR,里边有挑选低电平仍是高电平触发的位。这个位默认值是0,也便是挑选低电平触发。上 电复位后,还没有运转用户程序时寄存器里的值便是复位值。
5>> 《根底教程》上讲:假如存储器组装备成32位宽度,地址线A0,A1无用,16为则A0无用,8位则需求运用A0。但是《根底教程》下面配的图上32位宽 存储器组衔接32位的存储器芯片的A[a_b:0]都用了啊?这是怎样回事?其二:为什么外部存储器写拜访时的addr信号要早出一个时钟周期阿?
答: 一:配图有错。便是说:CPU的地址线A2接到存储器芯片的地址线A0。
二:您的第二个问题,只说说我的个人了解,仅供您参阅。
实践上, 在读拜访时,有用地址也比有用数据先呈现至少一个周期。假定有用地址和一呈现,有用数据一起呈现,那么这是不或许的。您应该清楚世界上没有这么快的存储 器,也不合常理。所以,有用地址必定比有用数据先呈现,必定要经过一段过渡期,才干以为呈现的数据是有用数据。再考虑到存储器读写周期核算的最小单位是 cclk,那么从设计者的视点考虑,拟定一个时序图,预期有用地址比有用数据先呈现一个或2个等整数个cclk是完全能够了解的。
6>> 关于__irq 的运用
答: __irq为一个标识,用来表明一个函数是否为中止函数。关于不同的编译器,__irq在函数名中的方位不相同,例如: ADS编译器中 : void __irq IRQ_Eint0(void); Keil编译器中 : void IRQ_Eint0(void) __irq;
但是其含义一 样,它所完结的使命是标识该函数为中止函数,在编译器编译是调用此函数时,先维护函数进口现场,然后履行中止函数,函数履行结束,康复中止现场,这整个过 程不需求用户从头编写代码来完结,由编译器主动完结。因此这也给不具备中止嵌套功用的ARM体系带来了问题,若运用 __irq 时有中止嵌套产生,这现场维护就会紊乱。在前一篇日志“LPC2000系列中止嵌套处理”中,自己编写中止进口现场维护代码,并不运用 __irq 标识符号,便是这个原因。
总结如下: 1、若不想自己编写中止进口现场维护代码,并且运用中无中止嵌套,在中止函数顶用 __irq 来标识咱们的中止函数,不然犯错; 2、若程序中要运用中止嵌套,关于无中止嵌套功用的ARM来说,一定要自己编写中止进口现场维护代码,并且不能用 __irq 标识咱们的中止函数,不然犯错。
7>> FIQ中止和IRQ中止的差异之处
答:FIQ中止和 IRQ中止都归于可屏蔽中止,他们分别受CPSR的F和I位的操控。
前者不需对VIC-VectAddrs和VIC-VectCntls进行设 置,但要想正确地
中止要做几步作业:
1. VIC-IntSelect = (1 VICIntSel_EINT0); 设置EINT0为FIQ中止
2. VIC-IntEnable = (1 VICIntSel_EINT0); 使能EINT0中止
3. 树立FIQ中止函数FIQ_EINT0().
留意要声明为外部的即extern void FIQ_EINT0 (void) __irq
4. 改写Startup.S的内容。(改写后的注解见Startup.S)
后者需对VIC-VectAddrs和 VIC-VectCntls进行设置。办法:
1. VIC-IntSelect &= ~(1 VICIntSel_EINT1); 设置EINT1为IRQ中止
2. VIC-VectCntls[0] = VICIntSel_Enable VICIntSel_EINT1;设置外部中止1分配VIC最高优先级
VIC-VectAddrs[0] = (unsigned int)IRQ_EINT1;设置中止服务程序地址
VIC-IntEnable = (1 VICIntSel_EINT1); 使能EINT1中止
3. 树立IRQ中止函数IRQ_EINT1().
留意要声明为内部的即void IRQ_EINT1 (void) __irq
4. 不用改写Startup.S的内容。(当然非典就不同了~~~)
8>> #define GetAddr(addr) (volatile uint16 *)(FLASH_ADDR|(addr<<1))这一句中volatile 是指什么意思?(volatile uint16 *)为什么要用括号括起来,是代表强制转化吗?
答:1。首要清晰带参数的宏界说的概念,如#define s(a,b) a*b,假如函数中呈现t=s(2,3),则等价于t=2*3。
2。volatile 用来界说一些没有软件干涉即可改动的值,咱们称之为易失的。例,某些I/O 设备寄存器的值会由于外部事情产生改动。C的关键字volatile可用于提示编译器留意指向这种寄存器的指针,以保证每次运用数据所读取的都是实践值。 另一个效果是防止变量被优化掉。
3。用括号括起来便是将该地址强制进行指针改换,由于直接拜访操作只能用于指针类型表达式,所以“*常数=某常数”是错的。将常数强制转化为指针,然后操 作即可对该地址赋值。#define GetAddr(addr) (volatile uint16 *)(FLASH_ADDR|(addr<<1))指将FLASH_ADDR|(addr<<1)强制转化为一个寄存16位整数 的地址,将指针润饰为volatile,是告知编译器,该指针指向的内容有或许会被改动(如被外部设备),不能优化。******可查阅《c和指针》一 书******
9>> volatile uint16 *ip;ip界说为无符号16位整形指针变量,但是赋值的时分,如ip[0]=0xaaaa怎样呈现数组元素ip[0]了?
答:ip[0]等价 于*(ip+0)。由于ip为地址,ip[0]即以ip为开始地址的榜首个数即*(ip+0)
10>> 外部存储器试验中,temp1 = *ip;temp2 = *ip;然后比较temp1,temp2是什么意思?
uint8 ChipErase(void)
{ volatile uint16 *ip;
uint16 temp1,temp2;
ip = GetAddr(0x5555);
ip[0] = 0xaaaa; // 榜首个写周期,地址0x5555,数据0xAA
……
ip = GetAddr(0x5555);
ip[0] = 0x1010; // 第六个写周期,地址0x5555,数据0x10
while (1) // 等候操作完结 (若擦除操作没有完结,每次读操作DQ6会跳变)
{ temp1 = *ip;
temp2 = *ip;
if (temp1 == temp2)
{ if (temp1 != 0xffff)
{ return(FALSE);}
else
{ return(TRUE); }
}
}
return(TRUE);}
答:查阅《SST39vf160手册》可知道,芯片在编程或擦除过程中触发位DQ6时在不断改变 的。然后当咱们用temp1 = *ip句子读取ip==GetAddr(0x5555)出的数据时,数据同过DQ0~DQ15传送给ARM处理器,由于若擦除操作没有完结,每次读操作 DQ6会跳变,所以能够用此作为判别。关于return的处理,但凡子函数履行到return处便跳出子函数并回来其值:)
11>> 根底试验教程 中的UART试验二中的设置波特率除数是下面这样设置的:
bak = (Fpclk>>4)/baud;U0DLM = bak>>8;U0DLL = bak&0xff;最终一句任何效果都起不到阿!!我觉得这儿是错的。
能够这样:U0DLL = bak;U0DLM = bak>>8;或许UODLL = bak%256;U0DLL = bak/256;是吗?
答: U0DLL = bak&0xff; // U0DLL放bak的低8位数值。没错。由于U0DLL = bak&0xff跟U0DLL = bak是相同的,只不过更谨慎一些。
注:U0DLM = bak>>8;这一句在前在后都无所谓,由于这种移位赋值操作不会影响bak的值。
12>> Uart0的查询发送和查询承受的方法怎样不同?“UOTHR = DATA; WHILE(TEMT = 1);”“WHILE(RDR = 1); DATA = UORBR;”
答: U0THR用来缓冲发送字符。线状况寄存器的第5位用来判别发送坚持寄存器中是否有字节。当值为‘1’时,表明发送坚持寄存器为空,此刻,假如输出 FIFO中有数据,那么字符(不止一个)能够被写入发送坚持寄存器。别的,假如发送FIFO已满,则发送坚持寄存器中还能够再写入一个字符。注:写THR 由人完结,发送功用有机器完结;所以能够先向THR中写入数据,然后查询是否发送结束。
RBR寄存接纳FIFO中将要被读的字节,对应FIFO的最高字节。每次读取RBR的动作完结后,fifo的数据会出栈一个,一个新的数据对应 U0RBR,一起fifo的深度会减一,假如有新的数据来到,fifo深度加1。线状况寄存器中的bit0用来标明接纳FIFO中是否有数据可被传送给 RBR。之前的判别是为了防止接纳无效的数据.
12>>I2C书上说的是,经过软件置位STA后才进入I2C形式,当即发送一个 开始条件。在这个试验的主函数里仅仅发动了i2c( I2CONSET = 0x40;),但是没有将STA置1发送开始信号啊。所以,我以为这样的话,i2c的中止标志位SI是不会置一的,无法进入中止啊。
答:是我傻, 是我笨,遇事不自己先考虑,处处瞎找人问。在主函数里那是初始化I2C,所以没有置位STA。但是你细心看看I2CINT.c文件,四个分函数都是怎样写 的,都是( I2CONSET = 0x60;)