如何修改hosts文件kknd2的.lpc文件

NXP LPC1769开发小结
上传时间为:
我们这次使用的芯片型号是LPC1769,关于它的使用手册可以参考周立功的LPC17xx用户手册。使用的是NXP官方开发板LPCxpresso LPC1769 Rev B,关于它的详细说明可参考另一个文件LPCXpressoLPC1769revB。在我们这篇文档中,尽可能用最简洁的语言告诉大家如何进行开发。我们这篇文档中的字体有两种,宋体字是关于操作的说明,楷体字是关于原理的说明,可以根据你的需要来选择看或不看。一、关于LPCxpresso编译环境的简单说明我们在开发时使用的编译器是NXP官方提供的LPCxpresso,我们不再详细地说明它的使用方法,在这里只对我们用到的功能作一些简要描述。1. 载入例程。在下载此编译器时,同时下载了关于LPC1769所有模块的使用例程,在我们进行开发时可以对其进行适当的修改,达到事半功倍的效果。在启动LPCxpresso的开发环境时,会让你首先选择工作区(Workspace)你的所有操作只能在某一个工作区中进行,每个工作区有自己的文件夹。当然,点击File,在下拉菜单中你可以进行工作区的切换。下面我们载入项目,如图:可以进入载入项目的对话框中: &&&&& 从官方下载的例程都是zip压缩包,所以点击第一个编辑框后面的Browse把,找到LPC1769的例程库,然后选中所有例程,点击Finish完成。2. 编译,链接,下载,调试首先我们先说说菜单Project下的Open Project和Close Project。这两个选项不是载入项目或者把项目从工作区中删除,而是将已经载入工作区的项目关闭或者将已经关闭的项目重新打开,这样的目的是尽量减少打开的项目,减少内存的占用。当我们选中某已打开的项目时,左下角锤子图片的字符会变为黑色,单引号中显示的是项目的名称,点击就会进行编译与链接。编译链接结束后,我们可以点击锤子下面绿色的小虫子进行下载和调试,或者点击右上角的小虫子。如果是第一次调试,我们需要建立调试对象,即点击右上角小虫子后面的绿色三角键。其中,AImove Debug和AIScreen Debug是已经建好的调试对象,点击会进行下载和调试,而我们新建对象要点击Debug Configureations&。我们要在C/C++MCU Application下创建对象,点击新建后进入新建调试对象界面,当前的项目会默认为新建的对象。点击Debug即可进入调试。注:LPCxpresso暂时不支持仿真调试。3、新建项目我们利用官方的例程来建立我们自己的项目,下面来说明如何建立项目。得到新建项目的对话框:选中LPCXpresso C Project,点击Next&选中相应的芯片型号,并选中其目录下的C Progect选择具体型号:我们用的是LPC1769,所以选择LPC1769有时候,在我们的工作区中使用的内核不是LPCXpresso当前版本默认的,所以直接选None,不添加内核。在建立之后我们自己添加。选完None就可以按Finish了。接着我们建立我们的程序,将我们需要的源文件和对应的头文件直接放到项目的目录下,不用像Keil MDK那样添加,LPCXpresso默认在项目目录中的src文件夹下的所有文件都是项目文件。然后我们加入内核。首先,右键点击我们建立的项目,会出现下拉菜单。点击Properties,进入项目设置对话框。在Project References栏中选择内核项,我们用的内核是CMSISv2_LPC17xx。在C/C++ Build下的Settings项中,Tool Settings 页面中MCU C Compiler下Symbols栏中添加“__USE_CMSIS=CMSISv2_LPC17xx”在Includes栏中添加文件夹CMSISv2_LPC17xx中的inc目录 在C/C++ Build下的Settings项Tool Settings 页面中MCU Linker下的Libraries中添加库名称CMSISv2_LPC17xx和库的路径CMSISv2_LPC17xx/Debug,记住,内核库在Debug路径中。接下来,就可以开始在新建的项目中编程了。二、GPIO端口的使用我们已经为GPIO的使用建立了一个比较完整的函数库,因此我们的工作是建立在我们的函数库之上。1. 我们的GPIO函数库我们建立的函数库由源文件lpc_GPIO.c和它的头文件lpc_GPIO.h组成。使用时,只需要看懂lpc_GPIO.h即可。GPIO函数库共有四个函数:其中,LPC_GPIO_Init()是GPIO端口的初始化程序,LPC_GPIO_Read()是利用已经初始化好的端口实现读数据,LPC_GPIO_Write()是利用已经初始化好的端口来写数据,LPC_GPIO_SetBit()和LPC_GPIO_ClrBit()是对已经初始化好的端口的某一位或者某几位来置0或者置1,它们的具体操作与它们的变量有关。首先我们来看LPC_GPIO_TypeDef类型。此类型是在LPC17xx.h中定义的结构体,它的结构与GPIO寄存器的地址分配一致,有兴趣可以看LPC17xx.h文件。我们只需记住,如果你用0端口,这个变量写为LPC_GPIO0,用1端口些为LPC_GPIO1,以此类推,当然你要查看你的芯片中究竟有没有这个端口。如果你不大明白“*”和“结构体”的含义,建议你查询C语言的基本书籍。下面我们来说在lpc_GPIO.h中我们定义的结构体和它的使用。在lpc_GPIO.h文件中,我们定义了两个结构体,定义好这两个结构体,就能使用这个GPIO输入输出的程序库了。LPC_GPIO_Def结构体,这个结构体是用来对端口进行初始化定义,里面共有六个成员,它们的可用值在#define中都有定义。这六个成员分别是:PIN_SEL,用来设置端口的工作模式,有4个可用值,分别是GPIO_FUN_IO和GPIO_FUN_2~GPIO_FUN_4,其中GPIO_FUN_IO是一般的IO端口的输入和输出,其它的功能可参见周立功《LPC17xx用户手册》第七、八章。PIN_Mode,用来设置输入输出的电气模式,有四个可选项,分别是上拉、下拉、浮空和中继模式,在我们的#define中有定义。PIN_DO,用来设置是否此引脚需要使用漏极输入输出(如果引脚使用I2C功能必需使用),有enable和disable两种模式。PINDIR,设置此端口是输入还是输出,有Input和Output两种模式。PINMASK,定义端口是否被mask,如果定义“是(true)”则此引脚不能使用(当然MASK的意义并不在于此,关于进一步的了解可以参考周立功《LPC17xx用户手册》第九章)Pin,定义使用的引脚,是一个32位2进制数,来设置某端口引脚是否使用。下面是一个使用的实例,我们定义GPIO0端口的7、24引脚为一般引脚输入,上拉模式,不用MASK,非漏极: &&&&& LPC_GPIO_Dat结构体,用来对端口进行操作,有三个成员变量:联合体PORT(x),其中PORT是对32位端口进行操作,PORTL和PORTH分别对低、高16位端口进行操作,PORT0~3将整个32位端口分为4个8位端口进行操作。关于联合体(也叫共用体)不会的话请查看任何一本C语言的教科书。GPIO_Bit,来设置如何使用端口,是作为32位的端口,还是使用作为8位端口的某个,其设置可参考#define中的GPIO_32Bit到GPIO_8Bit_3。GPIO_Pin,来设置用整个端口中的哪几个,其定义模式与LPC_GPIO_Def中的Pin成员相同,下面是我们使用的例子:将GPIO0.17和GPIO0.18置低电平: &&&& 用LPC_GPIO_ClrBit()与LPC_GPIO_SetBit()函数是不用对成员PORT(x)进行设置的,只有用函数LPC_GPIO_Read()和LPC_GPIO_Write()时才用到PORT(x),下面是一个实例:LPC_GPIO_Read(&LPC_Key,LPC_GPIO0);将LPC_Key中成员GPIO_Pin中定义的引脚中的数据放入成员PORT(x)中。可以参考工程AImove中main.c中的子函数void ShowLEDInit(void)和void KeyControl(uint32_t PinX),在这里,我们定义GPIO0的9端口接模式指示灯,8端口为采集状态指示灯,GPIO0.25、26与GPIO1.30、31为采集数据指示灯,GPIO0.7和24端口分别为模式切换和数据采集开始/停止切换键,GPIO0.17、18来给这两个键提供低电平输入源。按住模式切换键,模式指示灯(红)开始闪烁,当它一直保持亮时松开,进入数据采集状态,这时按模式切换键,会接换采集数据的种类(采集数据指示灯会显示出这4位2进制数)。按采集切换键,会开始或停止采集(开始时采集状态指示灯(蓝)亮,结束时灭)相应的数据。采集好相应的数据后,再按住模式切换键,模式指示灯开始闪烁,当它保持熄灭时松开,推出采集模式。三、用GPIO端口来驱动液晶屏四、外部中断的使用LPC1769的外部中断端口共有4个,它们分别对应不同的中断函数,所有的中断函数名称在LPC17xx.h中列出,在这一节我们只考虑外部中断,所以只用到4个外部中断函数这4个函数已经写到我们的建立项目的函数库:lpc_EXTI.c中,它的头文件是lpc_EXTI.h。中断的原理其实很简单,当我们触发中断时,会自动调用对应的中断函数,其名字就是在中断名字后面的n改为Handler,四个中断函数名如下(这段程序在lpc_EXTI.h中):外部中断分为两种,一种是单引脚中断,一种是端口中断,在单引脚中断中,中断触发引脚与中断函数的对应关系如下:
EINT0_IRQHandler
EINT1_IRQHandler
EINT2_IRQHandler
EINT3_IRQHandler
另外还有一种是对应端口的中断,只有P0和P2端口才能触发,它们对应的中断函数都是EINT3_IRQHandler,至于具体是哪个端口引起的,在中断函数中再进行判断。下面介绍我们自己编写的中断函数库。要使用中断,必须先将中断定义好,在我们的函数库中,定义单引脚中断的是结构体:typedef struct{uint32_t EXTI_EINTx;//使用第几个单引脚外部中断,取值为0~3uint32_t EXTI_M//设置中断的触发模式,边沿触发或是电平触发,其值为EINT0_EDGE或者
EINT0_leveluint32_t EXTI_P//设置中断触发模式是上升沿还是下降沿,其值为EINT0_RISING或
EINT0_FALLINGuint32_t EXTI_P//中断优先级,其值为一正整数}EXTI_D如注释中所写,将这四个成员变量定义好,然后调用函数void LPC_EXTINT_Init(EXTI_Def* EXTI_Param);将定义的中断初始化,其中的变量就是定义结构体的地址,比如我们定义了一个结构体:EXTI_Def&& EXTI1;初始化时的语句为:LPC_EXTINT_Init(&EXTI1);然后使用函数void EXTI_Switch(bool EXTI_ON_OFF, IRQn_Type IRQn)打开或者关闭中断,例如开通0端口的语句为 :EXTI_Switch(EXTI_ON, EINT0_IRQn);接着就在文件lpc_EXTI.c中对应的中断函数里添加所要执行的语句就可以了。在我们的设计中P2.10~P2.13的端口用来控制电机,因此我们用的是端口中断,使用P0端口中的P0.7和P0.24引脚。使用端口中断,就需要用到另一个结构体:typedef struct{&&&&&& uint32_t EXTI_P//整个端口中断中,有效的引脚&&&&&& uint32_t EXTI_P//端口中断中,有效的端口,其值为EXTI_P0或者EXTI_P2&&&&&& uint32_t EXTI_P//中断触发模式,上升沿或者下降沿&&&&&& uint32_t EXTI_P//中断优先级,其值为一个整数}EXTI_Group_D这是用来端口中断的结构体。在我们的程序中:LPC_GPIO_Def LPC_GPIO_SLPC_GPIO_Dat LPC_GPIO_PEXTI_Group_Def EXTI_Key_S//定义按钮1和2的输入端口: P0.7,P0.24LPC_GPIO_Structure.PINDIR = ILPC_GPIO_Structure.PINMASK =LPC_GPIO_Structure.PIN_DO =LPC_GPIO_Structure.PIN_Mode = GPIO_MODE_PullUp;LPC_GPIO_Structure.PIN_SEL = GPIO_FUN_IO;LPC_GPIO_Structure.Pin = GPIO_Pin7 | GPIO_Pin24;LPC_GPIO_Init(&LPC_GPIO_Structure,LPC_GPIO0);//接下来设置中断EXTI_Key_Structure.EXTI_Pin = GPIO_Pin7 | GPIO_Pin24;EXTI_Key_Structure.EXTI_Port = EXTI_P0;EXTI_Key_Structure.EXTI_Polar = EINT0_FALLING;EXTI_Key_Structure.EXTI_Priority = 9;LPC_EXTIGrouP_Init(&EXTI_Key_Structure);//打开中断EXTI_Switch(EXTI_ON, EINT3_IRQn);这段程序取自Main.c中的ShowLEDInit(void),来初始化LED指示灯和两个按钮。对于IO接口的设置,上一节中已经提过了,下面我们结合我们的设计说明端口模式的外部中断的使用。首先,我们设置使用的引脚为7和24引脚(GPIO_Pin7和GPIO_Pin24的设定在lpc_GPIO.h中)然后,设置我们使用的端口为P0口接着,我们设触发模式为下降沿模式(EINT0_FALLING的设定在lpc_EXTI.h中)最后,我们用9来表示此中断的优先级。设置完成员函数后,我们进行初始化,将结构体EXTI_Key_Structure的地址写入函数LPC_EXTIGrouP_Init中,初始化后,我们打开中断,注意,外部端口中断的中断函数对应着EINT3_IRQHandler,所以在函数中我们用EINT3_IRQn。这样,每当P0.7或者P0.24有一个下降沿产生时,函数EINT3_IRQHandler()会被自动调用。至于判断是哪个引脚产生的中断,我们利用下一段程序来判断:因为我们的中断用得是下降沿驱动,所以我们用了几步逻辑运算,目的是得到一个32位2进制数,对应与引脚的那一位为1,其余为0。在lpc_EXTI.c中,我们包含了文件main.h,这样我们就可以调用main.c中的函数Keycontrol(uint32_t).五、定时器的使用由于时间的关系,从这一节开始我们直接使用例程库中的代码。我希望我们在不断的开发过程中会用我们自己编写的代码去替换例程中的代码。在例程库中,定时器的例程共有两个:RITTimer和Timer,相比较来看,RITTimer更简单些,我们将RITTimer中的RITTimer.h和RITTimer.c复制到我们的目录下,在我们使用的编译器中,加入文件的方式与Keil是不同的,只要把文件放入目录下,编译的时候就会自动包含了。我们来看RITTimer.h文件我们的目的是每隔0.1秒我们会检查小车的位置和方向,然后进行相应的操作。在我们的程序中,直接调用init_rit_timer()函数,其变量值用的是在RITTimer.h中定义的TIME_INTERVAL,这个数值为89999,它保证每10ms执行一次中断。在所有的初始化和初值设定工作完成后,我们调用函数:enable_rit_timer(); 开启定时器。我们的目的是每0.1秒检查车的位置,但是我们设的数值为0.01秒中断,因此我们在中断函数rittimer.c中作了改动:同样我们在rittimer.c里引用了main.h,可以调用在main.c中的函数adjustCar(),在我们的程序中,基本是复制了例程中的结构,没有用到reset_rit_timer();六、PWM的使用关于这一部分,主要进行下面几部分的操作:首先,在整个的库函数文件夹里找到pwm文件夹,然后打开此文件。打开里边的.cproject文件下来,我先说一下,关于LPC1769这块片子和它的硬件搭建。LPC1769本身含有6路PWM,而我们控制小车,基本上用到的,只有2路,这2路PWM通过L298N模块(接下来会讲到),来控制电机的转速。PWM是通过调节占空比,也就是控制输出脉冲占整个周期的百分比。简单的,PWM对于智能小车来说,就是用来控制速度的。当然,PWM在其他方面也有很多用处,这里只针对智能小车做简单介绍。软件部分设计:首先要做的,就是对GOIO的设定,因为PWM引脚作为功能性引脚,在没有设定之前,属于普通输入输出引脚,所以我做了以下设定:然后,你需要在pwm.c这个c文件中,修改一些参数,主要是对占空比的设定。通过更改m和n的值,从而确定占空比。(m、n是自己设的参数)接下来是对电机正反转的设定,其实也是对GPIO的设定。最后就是PWM实现其功能的时候了,开机时,先对PWM进行初始化这其中的一些函数,例如PWM_Set( CHANNEL_NUM, cycle, offset )和PWM_Start( CHANNEL_NUM ),都是LPC1769这块片子里边给出来的,需要你看明白就好了,不必修改。做完这一项工作之后,PWM这一块,算是基本完成。七、串行通信的使用串行通信的程序我们首先将例程中项目UART中的文件uart.c和uart.h复制到我们项目的文件夹中。我们来看uart.h文件在我们的程序中,直接使用了好几个例程中的文件,用到缓冲区的例程,缓冲区的长度都定义为BUFSIZE,我们稍稍地加以改动以示区分,在串行通信中,我们改为SERBUFSIZE。UAERInit()是初始化函数,portNum为端口号,Baudrate为波特率;UART0_IRQHandler()与UAER1_IRQHandler()是串口0和串口1的中断函数,UARTSend()是发送函数,portNum为使用的端口号,BufferPtr为缓冲区,Length为发送字符长度。在我们的设计中,我们同时使用了串口0和串口1,串口0用来与GSM模块通信,串口1用来和ZigBee模块通信(在main.h中):#define &&&UART_PORT_GSM&& &0 //GSM通信用串口0#define&& &UART_PORT_Zigbee &&1 //Zigbee通信用串口1&&UARTInit(UART_PORT_GSM, 9600); //与GSM通信UARTInit(UART_PORT_Zigbee, 9600);&&&& //与Zigbee通信这样,串行通信0和1就打开了。在例程中,串口0的TXD和RXD分别是P0.2和P0.3,而串口1的TXD和RXD分别是P0.15和P0.16。连接时不要连错,一定要注意的是,LPC1769的TXD要连着Zigbee或GSM的RXD,而其RXD要和Zigbee或GSM的TXD连接。例程中的串行通信是用到中断的,每当串口接到一个字符,就会调用串口中断函数,串口中断函数比较复杂,有兴趣的同学可以学习学习,学习例程是提高自己水平最有效的方法,而我们这里只告诉大家最简单使用例程的方法。因为我们使用Zigbee或者GSM,其信息发送的模式是有固定格式的,这样才能保证不会错误地接到信息。Zigbee发给我们的信息的格式为:DiRSSIn:XXXX或者DiLQIn:XXXX,其中i是从0~9的数,它表示设备的序号,n=1或2,它表示接到的数值是固定发射器1的数值还是发射器2的数值。它们都是以回车符结尾,回车符的十六进制码是0x0A,因此我们在中断函数UAER1_IRQHandler()的结尾加入(在uart.c中):if(UART1Buffer[UART1Count -1] == 0x0A){//当串口接到换行符时,开始处理读入数据GetUART(1);}当收到一个换行符(回车符)时,表示收到了一条完整的信息,调用GetUART(1);同理,我们也在UAER0_IRQHandler()的结尾加入:if(UART1Buffer[UART0Count -1] == 0x0A){//当串口接到换行符时,开始处理读入数据GetUART(0);}关于处理传输的数据,在函数GetUART()之中,GSM的传输格式还没有最后定下来,另外我们只用到串口的接收而没有用到串口的发送。八、I2C总线的使用我们主要使用I2C来读取电子罗盘的数据,关于电子罗盘的介绍,可参考文件“HMC5883L中文规格书.pdf”。我们在这里只对它进行最简单的介绍。我们用的电子罗盘一共有5个接口,VCC接3.3V,GND接地,SCL接I2C1的时钟线P0.1,SDA接P0.0,最后一个引脚可以不管。我们直接使用I2C的例程:其头文件为:其中I2C1Init()我们修改过,因为I2C1在LPC1769上有两个不同的总线接口,可以根据实际情况来选择使用,我们选择的是P0.1和P0.0,因此我们初始化时:I2C1Init( 0 );如果变量改为1,使用的就是P0.15和P0.16引脚。在I2C.c中,有4个外部数组:volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][I2CBUFSIZE];volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][I2CBUFSIZE];volatile uint32_t I2CReadLength[I2C_PORT_NUM];volatile uint32_t I2CWriteLength[I2C_PORT_NUM];其中,在I2CReadLength[I2C_PORT_NUM]中确定读的字节数,在I2CWriteLength[I2C_PORT_NUM]中确定写的字节数,而I2C_PORT_NUM为端口号。在函数void GY273_Init(void)中,我们首先对电子罗盘的寄存器进行赋值,来确定电子罗盘的工作方式:I2CWriteLength[PORT_USED] = 3;&&&&&&&&&&&&&&&&&&&&&& //写入字节长度定义为3I2CReadLength[PORT_USED] = 0;&&&&&&&&&&&&&&&&&&&&&&& //读入字节长度定义为0//在地址为HMC5883_ADDR的器件的第02寄存器中写入0x0,为连续测量模式,即不断地测量角度I2CMasterBuffer[PORT_USED][0] = HMC5883_ADDR;&& //给I2C写入三个数,第一个是电子罗盘I2CMasterBuffer[PORT_USED][1] = 0x02;&&&&&&&&&&&&&& //的地址,第二个是要操作的寄存器地址I2CMasterBuffer[PORT_USED][2] = 0x00;&&&&&&&&&&&&& //第三个是给此寄存器中放入的数值I2CEngine( PORT_USED );&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //此函数用来根据数组的数值执行操作for ( i = 0; i & 0x20000; i++ );& &&&&&&&&&&&&&&&&&&&&&&&&&& /* 延时 *///在地址为HMC5883_ADDR的器件的第01寄存器中写入0xE0,用来设定磁场的测量范围I2CMasterBuffer[PORT_USED][0] = HMC5883_ADDR;I2CMasterBuffer[PORT_USED][1] = 0x01;I2CMasterBuffer[PORT_USED][2] = 0xE0;I2CEngine( PORT_USED );for ( i = 0; i & 0x20000; i++ );& /* 延时& */从我们的程序中可以看出,对于I2C总线的操作就是设定读写字节的长度,然后执行I2CEngine( PORT_USED );即可。PORT_USED=1,表示我们使用的是I2C1。在I2C总线下,电子罗盘就相当一个存储器,我们不断地从其某个寄存器中读取方向数值,电子罗盘中寄存器的地址和对应数据意义如下: &&&&& 每个寄存器中放置一个8位2进制数据,其中MSB为高8位数据。我们的小车只需要得到X与Y的值就可以了,所以我们在函数void GY273_GetAngle(int16_t *x, int16_t *y)中读取数据的代码为://转换模式为读写,写2字节,读12字节I2CWriteLength[PORT_USED] = 2;&&&&& //写数据长度为2I2CReadLength[PORT_USED] = 12;&&&&&& //读数据长度为12---保险起见,我们读取了所有数据//写入读的器件地址和器件的寄存器地址0x0I2CMasterBuffer[PORT_USED][0] = HMC5883_ADDR;&& //向I2C总线中写入电子罗盘的地址I2CMasterBuffer[PORT_USED][1] = 0x00;&&&&&&&&&&&& //写入读取数据首地址的寄存器地址I2CMasterBuffer[PORT_USED][2] = HMC5883_ADDR | RD_BIT;//从I2C中电子罗盘地址中I2CEngine( PORT_USED );//根据上面的数组来执行&&&&&&&&&&&&&& //连续读取12个数for(i=0;i&0x2000;i++);&& /* 延时& */其中,电子罗盘的地址为0x3C,我们已经用#define和HMC5883_ADDR绑定。I2C的地址一共有7位,最后一位为零表示写命令,为一表示读命令,RD_BIT为0x01,它与地址码作或运算的结果为0x3D,意为对地址为0x3C的寄存器开始读操作。又因为HMC5883芯片中寄存器的指针是自动加1的,因此我们只需将首地址定义出来,剩下的连续读取就可以了。九、以太网模块的使用关于以太网的模块,我们完全使用例程中的结构,我们发现,如果将程序复制到我们项目的文件夹中,编译总是出错,我们只能将我们编写的程序复制到以太网项目EMAC的文件夹中,这样不会出错,可能是我们建立项目时有一些设置出了问题。
这个家伙很懒,什么都没有留下。网站已改版,请使用新地址访问:
lpc24xx_usbdriver NXP 系列芯片USB HOST驱动,包括U盘创建文件、读写 等,keil环境 SCM 单片机开发 238万源代码下载-
&文件名称: lpc24xx_usbdriver
& & & & &&]
&&所属分类:
&&开发工具: C-C++
&&文件大小: 4 KB
&&上传时间:
&&下载次数: 18
&&提 供 者:
&详细说明:NXP lpc24xx系列芯片USB HOST驱动,包括U盘创建文件、读写文件等,keil环境-NXP lpc24xx USB HOST driver chips, including the U disk to create a file, read and write files, keil environment
文件列表(点击判断是否您需要的文件,如果是垃圾请在下面评价投诉):
&&usb.c&&usb.h
&[]:文件不全&[]:纯粹是垃圾
&近期下载过的用户:
&相关搜索:
&输入关键字,在本站238万海量源码库中尽情搜索:
&[] - Free usb Stack for NXP LPC2xxx microcontrollers.
&[] - 基于NXP ARM的单片机usb开发源代码,写的还比较规范的,从老外网上找来的哦。希望对大家有所帮助。
&[] - zlg ffs支持写平衡的NAND FLASH的文件系统可移值到ARM等处理器中
&[] - 刚刚从官网下的LPC23XX,LPC24XX的UCOS
&[] - LPC2478芯片U盘操作源码,ZLG提供的代码必须用UCOS,NXP提供的DEMO只能操作FAT16系统的U盘,此源码不用系统,并且可操作FAT32文件系统的U盘。此文件缺少ARM7必须的启动代码,分散装载文件等,这部分需要大家自己根据硬件环境编写
&[] - LPC24XX系列ADC转换源码,IAR环境
&[] - LPC24xx User manual LCP24xx系列处理器用户手册
&[] - lpc24xx_usb_bootloade
usb host 程序代码
LPC24XX 用户光盘资料,提供了internet,LCD,CAN等方面的开发资料
&[] - 一个实现usb数据回环(pc机发送的数据通过usb接收和返回)的例子,程序在LPC2368处理区调试通过1080人阅读
嵌入式(15)
题目:LPC2000 启动代码Start.s文件简要分析
最近要做一个温度采集。大师兄非要上ARM7,可俺还差不多是个白板呢,只能恶补一下了,先找个启动代码看看,ARM的汇编跟x86下的就是不一样啊(再说x86下的都菜的不行,呵呵),编译器与编译器之间的差异也挺大的。本例采用的是 Keil 环境下,由Keil自动生成的启动文件。平时可能用不着去自己写,可自己总是好奇心太重了,就拿来分析一下。对以后写启动代码或Bootloader也许会有些帮助吧。
先说一下启动代码的位置,启动代码是在板子加电后首先执行的。所以非要用汇编来写才行。要完成处理器模式的初始化、设置中断向量表、设置各个模式下的堆栈、初始某些变量从而把系统带到一个合适的运行环境中开始用户程序的运行。
;-------------------------------------------------------------------------------
; 本段设置处理器的模式相关常量
;-------------------------------------------------------------------------------
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
; 定义常量,处理器的几种工作模式。
; ARM 有7种工作模式:
; User: 非特权模式,大部分任务执行在这种模式&& 正常程序执行的模式
; FIQ: 当一个高优先级(fast)中断产生时将会进入这种模式 高速数据传输和通道处理
; IRQ: 当一个低优先级(normal)中断产生时将会进入这种模式 通常的中断处理
; SVC: 用于操作系统的保护模式
; Abort: 当存取异常时将会进入这种模式&& 虚拟存储及存储保护
; Undef: 当执行未定义指令时会进入这种模式 软件仿真硬件协处理器
; System: 使用和User模式相同寄存器集的特权模式
; 这个值将被写到CPSR寄存器的第0,1,2,3,4,5位,以表示当前的状态。
Mode_USR&&&&&&& EQU&&&& 0x10
Mode_FIQ&&&&&&& EQU&&&& 0x11
Mode_IRQ&&&&&&& EQU&&&& 0x12
Mode_SVC&&&&&&& EQU&&&& 0x13
Mode_ABT&&&&&&& EQU&&&& 0x17
Mode_UND&&&&&&& EQU&&&& 0x1B
Mode_SYS&&&&&&& EQU&&&& 0x1F
; 设置IRQ和FIQ中断禁止位,这两个值将被写到CPSR寄存器的第6位(FIQ)和第7位(IRQ)。1是禁止,0是允许。
I_Bit&&&&&&&&&& EQU&&&& 0x80&&&&&&&&&&& ; when I bit is set, IRQ is disabled
F_Bit&&&&&&&&&& EQU&&&& 0x40&&&&&&&&&&& ; when F bit is set, FIQ is disabled
;---------------------------------------------------------------------------------------------------
; 本段将完成堆栈相关的常量,
;---------------------------------------------------------------------------------------------------
; 设置各个模式下的栈大小
UND_Stack_Size EQU&&&& 0x
SVC_Stack_Size EQU&&&& 0x
ABT_Stack_Size EQU&&&& 0x
FIQ_Stack_Size EQU&&&& 0x
IRQ_Stack_Size EQU&&&& 0x
USR_Stack_Size EQU&&&& 0x
ISR_Stack_Size EQU&&&& (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
&&&&&&&&&&&&&&&&&&&&&&&& FIQ_Stack_Size + IRQ_Stack_Size)
; 初始化栈空间
; 定义一个数据段,名为STACK,NOINIT - 仅仅保留内存单元,还没有写入值,可读写,ALIGN=3 - 按字节对齐。
&&&&&&&&&&&&&&& AREA&&& STACK, NOINIT, READWRITE, ALIGN=3
; 分配内存,用户模式栈名为Stack_Mem,大小为1024字节;异常模式堆栈__initial_sp 大小为128+8字节。
Stack_Mem&&&&&& SPACE&& USR_Stack_Size
__initial_sp&&& SPACE&& ISR_Stack_Size
Heap_Size&&&&&& EQU&&&& 0x
;堆空间,其中__heap_base 与__heap_limit 这两个符号是给采用了MICROLIB的程序准备的。
&&&&&&&&&&&&&& AREA&&& HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem&&&&&&& SPACE&& Heap_Size
__heap_limit
;-------------------------------------------------------------------------------------------
; 初始化 VPB总线的频率,Start的时候将分频因子设置为1,表示与CPU CLOCK相同
;-------------------------------------------------------------------------------------------
; VPBDIV 是VPB总线的分频因子
; VPBDIV definitions
VPBDIV&&&&&&&&& EQU&&&& 0xE01FC100&&&&& ; VPBDIV Address
VPBDIV_SETUP&&& EQU&&&& 1
VPBDIV_Val&&&&& EQU&&&& 0x
;-------------------------------------------------------------------------------------------
; 定义与锁相环相关的寄存器
; Phase Locked Loop (PLL) definitions
;-------------------------------------------------------------------------------------------
; 定义 PLL相关寄存器的基地址
PLL_BASE&&&&&&& EQU&&&& 0xE01FC080&&&&& ; PLL Base Address
; 用偏移量的方法定义其他寄存器
PLLCON_OFS&&&&& EQU&&&& 0x00&&&&&&&&&&& ; PLL Control O控制寄存器,写入该寄存器的值在馈送序列执行前不起作用
PLLCFG_OFS&&&&& EQU&&&& 0x04&&&&&&&&&&& ; PLL Configuration O配置寄存器,属性同上
PLLSTAT_OFS&&&& EQU&&&& 0x08&&&&&&&&&&& ; PLL Status O状态寄存器,读取状态
PLLFEED_OFS&&&& EQU&&&& 0x0C&&&&&&&&&&& ; PLL Feed O馈送寄存器,使能装载PLL控制和配置信息
PLLCON_PLLE&&&& EQU&&&& (1&&0)&&&&&&&&& ; PLL Enable&& ;PLL使能,写入到配置寄存器的第0位,
&&&&&&&& ; 初始为0,表示没有激活
PLLCON_PLLC&&&& EQU&&&& (1&&1)&&&&&&&&& ; PLL Connect&& ;PLL连接使能位 ,写入到配置寄存器的第1位,当PLLC和
&&&&&&& ; PLLE都为1,且在有效的PLLE馈送后,将PLLE作为时钟源接
&&&&&&& ; 入Core,否则Core直接使用振荡器时钟。
PLLCFG_MSEL&&&& EQU&&&& (0x1F&&0)&&&&&& ; PLL MPLL 倍频因子
PLLCFG_PSEL&&&& EQU&&&& (0x03&&5)&&&&&& ; PLL Divider&& ;PLLE 分频因子
PLLSTAT_PLOCK&& EQU&&&& (1&&10)&&&&&&&& ; PLL Lock SPLL锁定状态位,应该是从PLLSTAT寄存器的第10位读取数值
&&&&&&& ; 然后与 PLLSTAT_PLOCK 相比较,相同则为PLL锁定状态。
PLL_SETUP&&&&&& EQU&&&& 1
PLLCFG_Val&&&&& EQU&&&& 0x ;表示向CFG配置寄存器写入的值为0 01 00100,跟系统所需的频率有关。
&&&& ;LPC2119的主频最高是60MHz,振荡器的主频是10MHz
&&&& ;分频值为1,倍频值为4,所以主频为40Mhz。
;-------------------------------------------------------------------------------------
; 存储器加速模块
;-------------------------------------------------------------------------------------
; Memory Accelerator Module (MAM) definitions
MAM_BASE&&&&&&& EQU&&&& 0xE01FC000&&&&& ; MAM Base Address
MAMCR_OFS&&&&&& EQU&&&& 0x00&&&&&&&&&&& ; MAM Control Offset
MAMTIM_OFS&&&&& EQU&&&& 0x04&&&&&&&&&&& ; MAM Timing Offset
MAM_SETUP&&&&&& EQU&&&& 1
MAMCR_Val&&&&&& EQU&&&& 0x
MAMTIM_Val&&&&& EQU&&&& 0x
;---------------------------------------------------------------------------
; 外部存储器扩展
;---------------------------------------------------------------------------
; External Memory Controller (EMC) definitions
EMC_BASE&&&&&&& EQU&&&& 0xFFE00000&&&&& ; EMC Base Address
BCFG0_OFS&&&&&& EQU&&&& 0x00&&&&&&&&&&& ; BCFG0 Offset
BCFG1_OFS&&&&&& EQU&&&& 0x04&&&&&&&&&&& ; BCFG1 Offset
BCFG2_OFS&&&&&& EQU&&&& 0x08&&&&&&&&&&& ; BCFG2 Offset
BCFG3_OFS&&&&&& EQU&&&& 0x0C&&&&&&&&&&& ; BCFG3 Offset
;// &e& External Memory Controller (EMC)
EMC_SETUP&&&&&& EQU&&&& 0
BCFG0_SETUP EQU&&&&&&&& 0
BCFG0_Val&& EQU&&&&&&&& 0x0000FBEF
BCFG1_SETUP EQU&&&&&&&& 0
BCFG1_Val&& EQU&&&&&&&& 0x0000FBEF
BCFG2_SETUP EQU&&&&&&&& 0
BCFG2_Val&& EQU&&&&&&&& 0x0000FBEF
BCFG3_SETUP EQU&&&&&&&& 0
BCFG3_Val&& EQU&&&&&&&& 0x0000FBEF
;// &/e& End of EMC
; External Memory Pins definitions
PINSEL2&&&&&&&& EQU&&&& 0xE002C014&&&&& ; PINSEL2 Address
PINSEL2_Val&&&& EQU&&&& 0x0E6149E4&&&&& ; CS0..3, OE, WE, BLS0..3,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ; D0..31, A2..23, JTAG Pins
&&&&&&&&&&&&&&& PRESERVE8 ;汇编伪指令,堆栈8字节对准
&&&&&&&&&&&&&&&
;-------------------------------------------------------------------------------
; 前面都是对寄存器位置的声明,以下是具体代码。定义了一个代码段
;-------------------------------------------------------------------------------
; Area Definition and Entry Point
; Startup Code must be linked first at Address at which it expects to run.
;定义个名为RESET的代码段
&&&&&&&&&&&&&&& AREA&&& RESET, CODE, READONLY
&&&&&&&&&&&&&&& ARM
; 中断向量表的异常入口共8条语句32字节,在链接的时候保证在0地址处
Vectors&&&&&&&& LDR&&&& PC, Reset_Addr&&&&&&& ;将Reset_Addr加载到PC中,程序就跳到reset_addr所指位置。
&&&&&&&&&&&&&&& LDR&&&& PC, Undef_Addr
&&&&&&&&&&&&&&& LDR&&&& PC, SWI_Addr
&&&&&&&&&&&&&&& LDR&&&& PC, PAbt_Addr
&&&&&&&&&&&&&&& LDR&&&& PC, DAbt_Addr
&&&&&&&&&&&&&&& NOP&&&&&&&&&&&&&&&&&&&&&&&&&&& ; Reserved Vector
;&&&&&&&&&&&&&& LDR&&&& PC, IRQ_Addr
&&&&&&&&&&&&&&& LDR&&&& PC, [PC, #-0x0FF0]&&&& ; Vector from VicVectAddr
&&&&&&&&&&&&&&& LDR&&&& PC, FIQ_Addr
Reset_Addr&&&&& DCD&&&& Reset_H分配一段字内存单元给程序段Reset_Handler
Undef_Addr&&&&& DCD&&&& Undef_Handler
SWI_Addr&&&&&&& DCD&&&& SWI_Handler
PAbt_Addr&&&&&& DCD&&&& PAbt_Handler
DAbt_Addr&&&&&& DCD&&&& DAbt_Handler
&&&&&&&&&&&&&&& DCD&&&& 0&&&&&&&&&&&&&&&&&&&&& ; Reserved Address
IRQ_Addr&&&&&&& DCD&&&& IRQ_Handler
FIQ_Addr&&&&&&& DCD&&&& FIQ_Handler
Undef_Handler&& B&&&&&& Undef_Handler
SWI_Handler&&&& B&&&&&& SWI_Handler
PAbt_Handler&&& B&&&&&& PAbt_Handler
DAbt_Handler&&& B&&&&&& DAbt_Handler
IRQ_Handler&&&& B&&&&&& IRQ_Handler
FIQ_Handler&&&& B&&&&&& FIQ_Handler
;-----------------------------------------------------------------------------------
;-----------------------------------------------------------------------------------
; Reset Handler
&&&&&&&&&&&&&&& EXPORT Reset_Handler
Reset_Handler&&
;设置扩展存储的引脚
; Setup External Memory Pins
&&&&&&&&&&&&&&& IF&&&&& :DEF:EXTERNAL_MODE ;判断 EXTERNAL_MODE 是否定义,如果定义了就设置响应的管脚。见某论坛上的一个人问,外部存储器设置了但是不能工作,就是这里的 EXTERNAL_MODE 没有被定义导致扩展 存储的引脚的代码没有被编译所以没有被初始化,EXTERNAL_MODE EQU 1,应该就可以了 ,还没测试。
&&&&&&&&&&&&&&& LDR&&&& R0, =PINSEL2
&&&&&&&&&&&&&&& LDR&&&& R1, =PINSEL2_V前面 PINSEL2_Val 被初始化为0x0E6149E4,完成一系列管脚的初始化
&&&&&&&&&&&&&&& STR&&&& R1, [R0]
&&&&&&&&&&&&&&& ENDIF
;设置扩展存储器的控制寄存器,分别检测几个bank是否存在,分别进行设置
; Setup External Memory Controller
&&&&&&&&&&&&&&& IF&&&&& EMC_SETUP && 0
&&&&&&&&&&&&&&& LDR&&&& R0, =EMC_BASE
&&&&&&&&&&&&&&& IF&&&&& BCFG0_SETUP && 0
&&&&&&&&&&&&&&& LDR&&&& R1, =BCFG0_Val
&&&&&&&&&&&&&&& STR&&&& R1, [R0, #BCFG0_OFS]
&&&&&&&&&&&&&&& ENDIF
&&&&&&&&&&&&&&& IF&&&&& BCFG1_SETUP && 0
&&&&&&&&&&&&&&& LDR&&&& R1, =BCFG1_Val
&&&&&&&&&&&&&&& STR&&&& R1, [R0, #BCFG1_OFS]
&&&&&&&&&&&&&&& ENDIF
&&&&&&&&&&&&&&& IF&&&&& BCFG2_SETUP && 0
&&&&&&&&&&&&&&& LDR&&&& R1, =BCFG2_Val
&&&&&&&&&&&&&&& STR&&&& R1, [R0, #BCFG2_OFS]
&&&&&&&&&&&&&&& ENDIF
&&&&&&&&&&&&&&& IF&&&&& BCFG3_SETUP && 0
&&&&&&&&&&&&&&& LDR&&&& R1, =BCFG3_Val
&&&&&&&&&&&&&&& STR&&&& R1, [R0, #BCFG3_OFS]
&&&&&&&&&&&&&&& ENDIF
&&&&&&&&&&&&&&& ENDIF&& ; EMC_SETUP
;设置VPB总线的分频因子,这里分频因子被设置为0
; Setup VPBDIV
&&&&&&&&&&&&&&& IF&&&&& VPBDIV_SETUP && 0
&&&&&&&&&&&&&&& LDR&&&& R0, =VPBDIV
&&&&&&&&&&&&&&& LDR&&&& R1, =VPBDIV_Val
&&&&&&&&&&&&&&& STR&&&& R1, [R0]
&&&&&&&&&&&&&&& ENDIF
;设置锁相环
; Setup PLL
&&&&&&&&&&&&&&& IF&&&&& PLL_SETUP && 0
&&&&&&&&&&&&&&& LDR&&&& R0, =PLL_BASE
&&&&&&&&&&&&&&& MOV&&&& R1, #0xAA
&&&&&&&&&&&&&&& MOV&&&& R2, #0x55
; Configure and Enable PLL
&&&&&&&&&&&&&&& MOV&&&& R3, #PLLCFG_Val&&
&&&&&&&&&&&&&&& STR&&&& R3, [R0, #PLLCFG_OFS]&&& ;PLLCFG_Val = 0x
&&&&&&&&&&&&&&& MOV&&&& R3, #PLLCON_PLLE&& ;R3 = 1
&&&&&&&&&&&&&&& STR&&&& R3, [R0, #PLLCON_OFS]&& ; PLLCON = 1,PLL 使能
&&&&&&&&&&&&&&& STR&&&& R1, [R0, #PLLFEED_OFS]&& ; 写 馈送寄存器命令序列一次是一次xAA,0x55。规定的。
&&&&&&&&&&&&&&& STR&&&& R2, [R0, #PLLFEED_OFS]
;等待PLL稳定
; Wait until PLL Locked
PLL_Loop&&&&&&& LDR&&&& R3, [R0, #PLLSTAT_OFS]&& ;将状态寄存器装载到R3中
&&&&&&&&&&&&&&& ANDS&&& R3, R3, #PLLSTAT_PLOCK&& ;PLLSTAT_OFS 与1&&10 进行与且影响 CPSR 的Z位,
&&&&&&&&&&&&&&& BEQ&&&& PLL_Loop&&& ;Z位为1 跳到PLL_Loop
; Switch to PLL Clock
&&&&&&&&&&&&&&& MOV&&&& R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)
&&&&&&&&&&&&&&& STR&&&& R3, [R0, #PLLCON_OFS]
&&&&&&&&&&&&&&& STR&&&& R1, [R0, #PLLFEED_OFS]
&&&&&&&&&&&&&&& STR&&&& R2, [R0, #PLLFEED_OFS]
&&&&&&&&&&&&&&& ENDIF&& ; PLL_SETUP
;-----------------------------------------------------------------------------
; 存储器加速模块
; Setup MAM
&&&&&&&&&&&&&&& IF&&&&& MAM_SETUP && 0
&&&&&&&&&&&&&&& LDR&&&& R0, =MAM_BASE
&&&&&&&&&&&&&&& MOV&&&& R1, #MAMTIM_Val
&&&&&&&&&&&&&&& STR&&&& R1, [R0, #MAMTIM_OFS]
&&&&&&&&&&&&&&& MOV&&&& R1, #MAMCR_Val
&&&&&&&&&&&&&&& STR&&&& R1, [R0, #MAMCR_OFS]
&&&&&&&&&&&&&&& ENDIF&& ; MAM_SETUP
;--------------------------------------------------------------------------
;内存映射,结构有点复杂额,总之就是根据不同的情况去设置存储器映射控制寄存器,
; 00 Boot装载,中断向量从BootBlock重新映射
; 01 用户FLASH模式,中断向量不重新映射,就在FLASH里面
; 10 用户RAM模式,中断向量从静态RAM重新映射
; 11 用户外部存储器模式,中断向量从外部存储器重新映射。
; Memory Mapping (when Interrupt Vectors are in RAM)
;----------------------------------------------------------------------------
MEMMAP&&&&&&&&& EQU&&&& 0xE01FC040&&&&& ; Memory Mapping C
&&&&&&&&&&&&&&& IF&&&&& :DEF:REMAP
&&&&&&&&&&&&&&& LDR&&&& R0, =MEMMAP
&&&&&&&&&&&&&&& IF&&&&& :DEF:EXTMEM_MODE ;判断是不是扩展模式 是就往R1里写3
&&&&&&&&&&&&&&& MOV&&&& R1, #3
&&&&&&&&&&&&&&& ELIF&&& :DEF:RAM_MODE ;如果是RAM中,往R1里写2
&&&&&&&&&&&&&&& MOV&&&& R1, #2
&&&&&&&&&&&&&&& ELSE
&&&&&&&&&&&&&&& MOV&&&& R1, #1&& ;否则R1里写1,唉汇编的编译判断真够烦的。
&&&&&&&&&&&&&&& ENDIF
&&&&&&&&&&&&&&& STR&&&& R1, [R0] ;写到MEMMAP寄存器。
&&&&&&&&&&&&&&& ENDIF
; Initialise Interrupt System
;为处理器的每种处理模式初始化栈空间
; Setup Stack for each mode
&&&&&&&&&&&&&&& LDR&&&& R0, =Stack_Top
; Enter Undefined Instruction Mode and set its Stack Pointer
&&&&&&&&&&&&&&& MSR&&&& CPSR_c, #Mode_UND:OR:I_Bit:OR:F_BCPSR_c = 0x1B|0x80|0x40 = 意思为禁止IRQ和FIQ,ARM状态,处理
器进入了未定义模式
&&&&&&&&&&&&&&& MOV&&&& SP, R0&&&& ;栈指针指向了Stack_Top
&&&&&&&&&&&&&&& SUB&&&& R0, R0, #UND_Stack_Size&& ;Stack_Top = Stack_Top - ABT_Stack_Size
; Enter Abort Mode and set its Stack Pointer
&&&&&&&&&&&&&&& MSR&&&& CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
&&&&&&&&&&&&&&& MOV&&&& SP, R0
&&&&&&&&&&&&&&& SUB&&&& R0, R0, #ABT_Stack_Size
; Enter FIQ Mode and set its Stack Pointer
&&&&&&&&&&&&&&& MSR&&&& CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
&&&&&&&&&&&&&&& MOV&&&& SP, R0
&&&&&&&&&&&&&&& SUB&&&& R0, R0, #FIQ_Stack_Size
; Enter IRQ Mode and set its Stack Pointer
&&&&&&&&&&&&&&& MSR&&&& CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
&&&&&&&&&&&&&&& MOV&&&& SP, R0
&&&&&&&&&&&&&&& SUB&&&& R0, R0, #IRQ_Stack_Size
; Enter Supervisor Mode and set its Stack Pointer
&&&&&&&&&&&&&&& MSR&&&& CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
&&&&&&&&&&&&&&& MOV&&&& SP, R0
&&&&&&&&&&&&&&& SUB&&&& R0, R0, #SVC_Stack_Size
; 进入用户模式,并且设置栈空间指针
; Enter User Mode and set its Stack Pointer
&&&&&&&&&&&&&&& MSR&&&& CPSR_c, #Mode_USR
&&&&&&&&&&&&&&& IF&&&&& :DEF:__MICROLIB&& ;支持 MICROLIB库,如果C程序的运行库是MICROLIB 则将__initial_sp 导出
&&&&&&&&&&&&&&& EXPORT __initial_sp
&&&&&&&&&&&&&&& ELSE
&&&&&&&&&&&&&&& MOV&&&& SP, R0
&&&&&&&&&&&&&&& SUB&&&& SL, SP, #USR_Stack_Size
&&&&&&&&&&&&&&& ENDIF
;进入C代码的执行,为C代码的执行创造一个运行环境
; Enter the C code
&&&&&&&&&&&&&&& IMPORT __main&& ;导入外部符号
&&&&&&&&&&&&&&& LDR&&&& R0, =__将main的地址加载到r0中
&&&&&&&&&&&&&&& BX&&&&& R0&& ;带状态的跳到main 去执行
&&&&&&&&&&&&&&& IF&&&&& :DEF:__MICROLIB ;还是有关使用MICROLIB库的,如果使用了该库就要导出下面连个符号。
&&&&&&&&&&&&&&& EXPORT __heap_base
&&&&&&&&&&&&&&& EXPORT __heap_limit
&&&&&&&&&&&&&&& ELSE
; User Initial Stack & Heap
&&&&&&&&&&&&&&& AREA&&& |.text|, CODE, READONLY
&&&&&&&&&&&&&&& IMPORT __use_two_region_memory
&&&&&&&&&&&&&&& EXPORT __user_initial_stackheap
__user_initial_stackheap
&&&&&&&&&&&&&&& LDR&&&& R0, = Heap_Mem
&&&&&&&&&&&&&&& LDR&&&& R1, =(Stack_Mem + USR_Stack_Size)
&&&&&&&&&&&&&&& LDR&&&& R2, = (Heap_Mem +&&&&& Heap_Size)
&&&&&&&&&&&&&&& LDR&&&& R3, = Stack_Mem
&&&&&&&&&&&&&&& BX&&&&& LR
&&&&&&&&&&&&&&& ENDIF
&&&&&&&&&&&&&&& END
一直对底层的东西不太懂,总是朦朦胧胧的感觉,索性拿启动代码看一下吧,指望着能学一下汇编。周末的学习效率是在太低了,一个小小的启动文件竟然费了两天功夫。费了牛劲了看是看完了,还是有好多地方一头雾水。因为认识的深度有限,错误的地方肯定少不了,所以还请您校正。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:115038次
排名:千里之外
原创:17篇
转载:30篇
(15)(1)(1)(1)(2)(5)(14)(4)(2)(2)}

我要回帖

更多关于 如何修改hosts文件 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信