微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > LPC ARM 相关的几个问题

LPC ARM 相关的几个问题

时间:11-25 来源:互联网 点击:

6>>rtup.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;)

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top