STM32学习总结
更新时间:2024-05-03 03:22:01 阅读量: 综合文库 文档下载
- STM32报错总结推荐度:
- 相关推荐
目 录
一、 工程目录结构...................................................................................................... 1 二、 启动代码分析...................................................................................................... 1
1、启动模式的选择............................................................................................... 1 2、 启动文件分析................................................................................................. 2
1) 定义栈、堆及其初始化.......................................................................... 2 2) 定义复位向量.......................................................................................... 2 3) 其他中断向量及服务子程序.................................................................. 3 4) 拓展:_main()与main()区别 ................................................................. 3 3、 我司启动文件情况:..................................................................................... 4 三、 时钟资源分析...................................................................................................... 4
1、时钟源............................................................................................................... 4 2、 时钟源输出..................................................................................................... 6 3、 SystemInit函数分析.................................................................................... 7
1) SystemInit().......................................................................................... 7 2) SetSysClock()........................................................................................ 8 3) SetSysClockTo72()................................................................................ 8
四、 Cotex-M3异常与中断 ...................................................................................... 10
1、 异常类型....................................................................................................... 10 2、 优先级定义................................................................................................... 10 3、 NVIC概述...................................................................................................... 10 4、 InterruptVector.c文件分析 ........................................................................ 11
1) RegisterInterrupt() ............................................................................ 11 2) NVIC_Init()............................................................................................ 12
五、 项目实例............................................................................................................ 13
1、文件夹建立 .................................................................................................... 13 2、工程结构建立 ................................................................................................ 14
一、工程目录结构
结合公司工程文件格式及自身习惯,建立的常用基础工程目录结构如下:
Project子文件下用来存在工程文件。 OBJ是用来存放编译过程文件以及hex文件。 USER用来存放主函数及一些临时编写的应用函数。
FWLib中存放的是ST官方库函数源码文件,包含inc、src文件夹,inc存放的是固件库的.h文件,src存放的是对应的.c文件,每个外设对应一个.c文件及一个.h头文件。
StartUp里面是系统启动文件,我司启动文件有两个(误码仪代码):startup_stm32f10x_cl.s、startup_stm32f10x_hd.s。_cl.s文件是互联型产品的启动文件,_hd.s是大容量产品的启动文件。
CorTex-M3下的core_cm3.c和core_cm3.h是CMSIS核心文件,提供进入M3内核接口,这是
ARM
公司提供,对所有
CM3
内核的芯片都一样。
system_stm32f10x.c,system_stm32f10x.h文件的功能是设置系统以及总线时钟,这个里面有一个非常重要的SystemInit()函数,这个函数在我们系统启动的时候都会调用,用来设置系统的整个时钟系统。stm32f10x.h文件打开可以看到,里面非常多的结构体以及宏定义。这个文件里面主要是系统寄存器定义申明以及包装内存操作。
Driver里面是常用的驱动代码,进行代码移植时可直接调用。
二、启动代码分析
1、启动模式的选择
1
STM32自带的启动模式有3种:
STM32的启动选择,通过设置BOOT1、BOOT0的引脚的高低电平即可选择。其中主闪存启动是将程序下载到内置的Flash进行启动(该flash可运行程序),该程序可以掉电保存,下次开机可自动启动;系统存储器启动是将程序写入到一快特定的区域,一般由厂家直接写入,不能被随意更改或擦除。内置SRAM启动,由于SRAM掉电丢失,不能保存程序,一般只用于程序的调试。
2、启动文件分析
启动文件,总的来说主要做了3个工作:分配和初始化栈、堆;定义复位向量并初始化;中断向量表及相应的异常处理程序,以107器件cl.s文件为例。
1)定义栈、堆及其初始化 定义堆、栈:
Stack_Size EQU 0x400
Heap_Size EQU 0x400
AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack
SPACE Stack_Size
AREA HEAP, NOINIT, READWRITE, ALIGN=3 Heap
SPACE Heap_Size 堆栈初始化定义:
__user_initial_stackheap //进行栈、堆的赋值,在_main函数执行过程中调用 LDR R0, =Heap
LDR R1, =(Stack + Stack_Size) LDR R2, =(Heap + Heap_Size) LDR R3, =Stack BX LR 2)定义复位向量
Boot引脚的设置不同,复位时,起始地址的位置不同,SRAM的起始地址为0x2000000, flash的起始地址为0x8000000。Cortex-M3内核规定,起始地址必须存放堆定指针,而第二
2
个地址必须存放复位中断入口向量。在系统复位时,内核会自动从其实地址的下一个地址(即32位)空间取出复位中断入口向量,然后跳转到复位中断服务程序,该服务程序就会跳转到main()执行程序。
中断向量表(部分向量):
EXPORT __Vectors
__Vectors DCD Stack + Stack_Size ; Top of Stack DCD Reset_Handler DCD NMIException
DCD HardFaultException DCD MemManageException DCD BusFaultException DCD UsageFaultException
DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved
DCD PendSV_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved
DCD OS_CPU_PendSVHandler ; PendSV Handler DCD SysTick_Handler ; SysTick Handler 复位中断服务程序:
EXPORT Reset_Handler Reset_Handler
IMPORT __main //导入符号,_main为运行时库提供的函数;完成堆、栈的初始化
LDR R0, =__main //等工作,调用定义的__user_initial_stackheap BX R0 //跳到_main,进入C的世界
3)其他中断向量及服务子程序
在启动文件中,只定义了中断向量,它们相应的服务子程序跳转到空操作,为之后扩展中断服务程序做准备。
4)拓展:_main()与main()区别
注意:_main()与main()不是相同函数。_main()是编译系统提供的一个函数,负责完成库函数的初始化和初始化应用程序执行环境,最后自动跳转到main()。所以说,前者是库函数,后者是我们自己编写的main()主函数。
对含有启动程序的系统来说,执行地址与加载地址相同不容易实现。
3
因为启动程序是要烧到非易失存储器里,用来在上电执行的,而这个程序必定会有RW段,如果RW放在非易失存储器,如FLASH,那就不好实现RW功能了,因此要给RW移动到能够实现RW功能的存储器,如SRAM等.因此,对含有启动程序来说,\执行地址与加载地址相同\就不容易实现。
程序的入口点在C库中的_main处,在该点,库代码执行以下操作: ? 把RO,RW从他们的加载域复制到他们的运行域中去 ? 初始化ZI域 ? 跳到__rt_entry
而库函数__rt_entry()会完成以下工作: ? 调用__rt_stackheap_init()设置stack和heap ? 调用__rt_lib_init()初始化相应的库函数 ? 调用main(),即是我们自己的应用程序了
3、我司启动文件情况:
因公司使用的stm32芯片规格不一,分stm32f103、stm32f107系列等等,在进行程序编程时,为保证程序的可移植性,在InterruptVector.c文件中,通过预定义的方式来切换103/107器件,同时代码在进行编译过程中,需手动选择启动文件类型,不然代码无法编译成功。
图中编译使用的是cl.s文件。
三、时钟资源分析
1、时钟源
4
C
②
⑤
D
E
①
④
B
③
A
在STM32中,有五个时钟源,为中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。从时钟频率来分可以分为高速时钟源和低速时钟源,在这5个中HIS,HSE以及PLL是高速时钟,LSI和LSE是低速时钟。从来源可分为外部时钟源和内部时钟源,外部时钟源就是从外部通过接晶振的方式获取时钟源,其中HSE和LSE是外部时钟源,其他的是内部时钟
5
源。下面我们看看STM32的五个时钟源,对应上面图中标红的序号标示。
①、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。
②、HSI是高速内部时钟,RC振荡器,频率为8MHz。
③、LSI是低速内部时钟,RC振荡器,频率为40kHz。独立看门狗的时钟源只能是LSI,同时LSI还可以作为RTC的时钟源。
④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。这个主要是RTC的时钟源。
⑤、PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。
2、时钟源输出
再看一下时钟源的输出,如何为外设及系统提供时钟,对应上方图中字母标示。 A、MCO是STM32的一个时钟输出IO(PA8),它可以选择一个时钟信号输出,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。这个时钟可以用来给外部其他系统提供时钟源。
B、这里是RTC时钟源,从图上可以看出,RTC的时钟源可以选择LSI,LSE,以及HSE的128分频。
C、USB的时钟是来自PLL时钟源。STM32中有一个全速功能的USB模块,其串行接口引擎需要一个频率为48MHz的时钟源。该时钟源只能从PLL输出端获取,可以选择为1.5分频或者1分频,也就是,当需要使用USB模块时,PLL必须使能,并且时钟频率配置为48MHz或72MHz。
D、是STM32的系统时钟SYSCLK,它是供STM32中绝大部分部件工作的时钟源。系统时钟可选择为PLL输出、HSI或者HSE。系统时钟最大频率为72MHz。
E、指其他所有外设了。从时钟图上可以看出,其他所有外设的时钟最终来源都是SYSCLK。SYSCLK通过AHB分频器分频后送给各模块使用。
1)AHB总线、内核、内存和DMA使用的HCLK时钟。
2)通过8分频后送给Cortex的系统定时器时钟,也就是systick了。 3)直接送给Cortex的空闲运行时钟FCLK。
4)送给APB1分频器。APB1分频器输出一路供APB1外设使用(PCLK1,最大频
6
率36MHz),另一路送给定时器(Timer)2、3、4倍频器使用。
5)送给APB2分频器。APB2分频器分频输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给定时器(Timer)1倍频器使用。
注意:APB1上面的是低速外设,包括电源接口、备份接口、CAN、USB、I2C1、
I2C2、UART2、UART3等等,APB2上面连接的是高速外设包括UART1、SPI1、Timer1、ADC1、ADC2、所有普通IO口(PA~PE)、第二功能IO口等。
3、SystemInit函数分析
首先,要芯片工作进行时钟配置时函数的调用关系:startup_stm32f10x_cl.s(启动文件)→main()→SystemInit()→SetSysClock()→SetSysClockTo72()。(系统默认使用72MHz)
1)SystemInit()
在进行时钟配置之前,对RCC寄存器CR、CIR、CFGR、CFGR2进行重置。然后调用函数SetSysClock()。
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001; //内部8MHz时钟开启 /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ #ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000; //清零 #else
RCC->CFGR &= (uint32_t)0xF0FF0000; //清零 #endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF; //清零 /* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF; //清零
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ RCC->CFGR &= (uint32_t)0xFF80FFFF; //清零
#ifdef STM32F10X_CL //互联型产品 /* Reset PLL2ON and PLL3ON bits */ RCC->CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */ RCC->CIR = 0x00FF0000; //中断使能关闭 /* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
7
/* Disable all interrupts and clear pending bits */ RCC->CIR = 0x009F0000; /* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; #else
/* Disable all interrupts and clear pending bits */ RCC->CIR = 0x009F0000; #endif /* STM32F10X_CL */ SetSysClock();
2) SetSysClock()
#ifdef SYSCLK_FREQ_HSE SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz //定义为72MHz SetSysClockTo72(); #endif
定义为72MHz,便接着调用函数SetSysClockTo72()。 3)SetSysClockTo72()
先计算系统时钟SYSCLK频率(外部晶振为25MHz)。 代码中:
RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 其中RCC_CFGR2_PREDIV2_DIV5:PREDIV2=5 //5分频
也就是PREDIV2对输入的外部时钟5分频,那么PLL2和PLL3没有倍频前均为25/5=5MHz。
RCC_CFGR2_PLL2MUL8:PLL2MUL=8 //8倍频
8倍频后PLL2时钟=5*8=40MHz,因此PLL2CLK=40MHz。
RCC_CFGR2_PREDIV1SRC_PLL2:RCC_CFGR2的第16位为1,选择PLL2CLK作为PREDIV1的时钟源。
RCC_CFGR2_PREDIV1_DIV5:PREDIV1=5 //5分频
8
PREDIV1CLK=PLL2CLK/5=8MHz。 (以上是对RCC_CFGR2进行的配置)
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9);
RCC_CFGR_PLLXTPRE_PREDIV1:操作的是RCC_CFGR的第17位PLLXTPRE,操作这一位和操作RCC_CFGR2寄存器的位[3:0]中的最低位是相同的效果。
RCC_CFGR_PLLSRC_PREDIV1:选择PREDIV1输出作为PLL输入时钟;PREDIV1CLK=8MHZ,所以输入给PLL倍频的时钟源是8MHz。
RCC_CFGR_PLLMULL9:PLLMULL=9;//9倍频 也就是对PLLCLK=PREDIV1CLK*9=72MHz。 (以上是对RCC_CFGR进行的配置)
/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; //选择PLLCLK作为系统时钟源 故系统时钟SYSCLK=72MHz。 代码中:
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 故HCLK(AHB总线时钟)=PLLCLK=SYSCLK=72MHz。 PLCK2(APB2时钟)=HCLK=SYSCLK=PLLCLK=72MHz。 PLCK1(APB1时钟)=HCLK/2=36MHz。
总结一下SystemInit()函数中设置的系统时钟大小: SYSCLK(系统时钟)= 72MHZ AHB总线时钟= 72MHZ APB1总线时钟= 36MHZ APB2总线时钟= 72MHZ
9
PLL时钟= 72MHZ PLL2时钟= 40MHZ
四、Cotex-M3异常与中断
1、异常类型
Cortex-M3在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其中,编号为1-15的对应系统异常,大于等于16的则全是外部中断。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。 Cortex-M3内部总的有255个异常,因为芯片设计者可以修改CM3的硬件描述源代码,所以做成芯片后,支持的中断源数目常常不到240个,并且优先级的位数也由芯片厂商最终决定。
所有能打断正常执行流的事件都称为异常。 异常与中断区别?
240个中断对CM3核来说都是“意外突发事件”也就是说,该请求信号来自CM3内核的外面,来自各种片上外设和外扩的外设,对CM3来说是“异步”的;而异常则是因CM3内核的活动产生的在执行指令或访问存储器时产生,因此对CM3来说是“同步”的。
2、优先级定义
在CM3中,优先级对于异常来说很关键的,它会决定一个异常是否能被掩蔽,以及在未掩蔽的情况下何时可以响应。优先级的数值越小,则优先级越高。CM3支持中断嵌套,使得高优先级异常会抢占(preempt)低优先级异常。有3个系统异常:复位,NMI以及硬fault,它们有固定的优先级,并且它们的优先级号是负数,从而高于所有其它异常。所有其它异常的优先级则都是可编程的(但不能被编程为负数)。
原则上,CM3支持3个固定的高优先级和多达256级的可编程优先级,并且支持128级抢占。但是,绝大多数CM3芯片都会精简设计,以致实际上支持的优先级数会更少,如8级,16级,32级等。它们在设计时会裁掉表达优先级的几个低端有效位,以减少优先级的级数(可见,不管使用多少位来表达优先级,都是以MSB对齐的)。
3、NVIC概述
向量中断控制器,简称NVIC,是Cortex-M3不可分离的一部分,它与CM3内核的逻辑紧密耦合,有一部分甚至水乳交融在一起。NVIC与CM3内核同声相应,同气相求,相辅相成,里应外合,共同完成对中断的响应。NVIC的寄存器以存储器映射的方式来访问,除了
10
包含控制寄存器和中断处理的控制逻辑之外,NVIC还包含了MPU、SysTick定时器以及调试控制相关的寄存器。
NVIC共支持1至240个外部中断输入(通常外部中断写作IRQs)。具体的数值由芯片厂商在设计芯片时决定。此外,NVIC还支持一个“永垂不朽”的不可屏蔽中断(NMI)输入。NMI的实际功能亦由芯片制造商决定。在某些情况下,NMI无法由外部中断源控制。
NVIC的访问地址是0xE000_E000。所有NVIC的中断控制/状态寄存器都只能在特权级下访问。不过有一个例外软件触发中断寄存器可以在用户级下访问以产生软件中断。所有的中断控制/状态寄存器均可按字/半字/字节的方式访问。
STM32F10xxx系列有68个可屏蔽中断通道(不包含16个Cortex?M3的中断线),16个可编程的优先等级(使用了4位中断优先级)。
4、InterruptVector.c文件分析
首先通过预定义来进行103与107器件的切换,在两种情况下均定义系统中断NVIC向量表const IRQn_Type g_IVNCTalble[INTERRUPT_NUM],之后定义中断函数指针组void (*g_InterruptProcessVector[INTERRUPT_NUM])(void),运用函数指针数组调用中断向量。
1)RegisterInterrupt() 该函数为注册中断函数。
void RegisterInterrupt(uint8 InterruptNum,uint8 SetPreemptionPriority, SetSubPriority,void (*InterruptProcess)(void))
{ NVIC_InitTypeDef NVIC_InitStructure; //结构体变量定义 MC_ASSERT(InterruptNum NVIC_InitStructure.NVIC_IRQChannelSubPriority = SetSubPriority; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); 11 uint8 } 中断配置过程: NVIC_IRQChannel参数是用使能或者失能指定的IRQ(中断)通道。 NVIC_IRQChannelPreemptionPriority参数设置了NVIC_IRQChannel中的先占优先级。 NVIC_IRQChannelSubPriority参数设置了NVIC_IRQChannel中的从优先级。 NVIC_IRQChannelCmd 指定了在成员NVIC_IRQChannel中定义的IRQ通道是使能还是失能。 最后进入NVIC_Init()函数初始化。 2)NVIC_Init() void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) { uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); //检测变量是否合法 if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) //使能开启 { /* Compute the Corresponding IRQ Priority --------------------------------*/ tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;//算出来得到的就是占先优先级的位数占四位中的几位 tmppre = (0x4 - tmppriority); //算出来得到的就是响应优先级的位数占四位中的几位 tmpsub = tmpsub >> tmppriority; //然后将四位掩码通过抢占优先级位数得到响应优先级的掩码 tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; //与上相应优先级掩码得到单纯的相应优先级 tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub; //然后 或上(|) 响应优先级得到了该中断通道8位的优先级数 tmppriority = tmppriority << 0x04; //将这个优先级数左移四位放置到相应通道优先级寄存器8位的高四位(优先级8位从左边算起的) NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; //输入到包含该通道中断响应优先级寄存器中,可以看出,本质上也是一个读--修改--写的过程 /* Enable the Selected IRQ Channels --------------------------------------*/ NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); //使能中断,完成外设中断的初始化。 12 五、项目实例 以下是基于STM32新版插卡式误码仪代码设计的不带操作系统工程实例。 1、文件夹建立 Studys由Project、Source两个文件夹构成。 Project根目录下存放工程文件,OBJ文件夹存放编译后输出的文件。通过“Select Folder for Objects...”选项选择存储位置。 Source包含6个文件夹。 Cortex_M3中包含以下文件 core_cm3.c和core_cm3.h是CMSIS核心文件,提供进入M3内核接口,system_stm32f10x.c,system_stm32f10x.h文件的功能是设置系统以及总线时钟,这个里面有一个非常重要的SystemInit()函数,这个函数在我们系统启动的时候都会调用,用来设置系统的整个时钟系统。stm32f10x.h文件打开可以看到,里面非常多的结构体以及宏定义。这个文件里面主要是系统寄存器定义申明以及包装内存操作。 Driver文件夹中包含我公司常用的驱动函数。 13 一般都会先全部拷贝到文件夹中,不需要的驱动在keil中不进行添加。 Lib文件夹包含FWLib、MCLib。 FWLib中为ST官方库函数。 MCLib为我公司定义库函数。 Middle文件夹用来存放中间件函数,我公司常用中间件函数有6个(不包含头文件)。 StartUp文件夹存放系统启动代码。 USER文件夹中包含主函数main及其他应用函数。 2、工程结构建立 打开keil文件,新建工程,找到之前新建的文件夹“Project”根目录下,输入工程名,保存工程。 14 击c/c++选项.然后点击Include Paths右边的按钮。弹出一个添加path的对话框,然后我们将工程中函数需要的头文件添加进去。(注意:记住,keil只会在一级目录查找,所以如果你的目录下面还有子目录,记得path一定要定位到最后一级子目录。然后点击OK。) 接着我们还需要来配置一个全局的宏定义变量,这是因为库函数在配置和选择外设的时候是通过宏定义来选择的,也是在C/C++选项中。如果系统带OS,还需添加OS的宏定义。 最后,选择编译中间文件编译后存放的目录,点击魔术棒,然后选择“Output”选项下面的“Select folder for objects…”,然后选择目录中我们新建的Project-OBJ目录。 20 到目前为止,工程结构及设置部分均创建完成,接下来就是大家根据项目需求大展身手的时候了! 以上属基于个人理解编写的学习总结,由于个人表达能力及专业能力有限,难免会有遗漏及描述不清晰的地方,若有疏忽的地方请指导一下。 21
正在阅读:
STM32学习总结05-03
银行员工转正申请05-20
唐朝宗室世系表06-14
听话与说话(二)说课稿102-01
银行新员工转正申请书10-13
安全管理人员登记表(汇总)10-12
贝克曼库尔特AU5800 标准操作文件01-30
2018年入党申请书(农行员工)12-19
水文地质划分 - 图文10-13
1∶250000区域水文地质调查技术要求08-09
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 总结
- 学习
- STM32
- corejava学习总结
- 数学报十年精选题解题方法
- 复习题普通生物学
- 我国中小企业应收账款管理中存在的问题及对策
- 福建省基地校(福建师大附中)2015年高三数学10月专项练习
- 个人网上银行功能介绍 - 图文
- 个人独资企业的解散和清算--中级会计师辅导《经济法》第三章讲义
- 毕业论文-快速傅里叶变换算法及其在信号处理中的应用
- 2014—2015小学语文四年级下册教学计划
- 八年级
- 2012年各地高考模拟试题中导数题大汇编
- 陶瓷厂建设项目可行性研究报告
- 2019年中考英语模拟题及答案:(六)
- 电力系统实验二
- 高考必做百例导数压轴题(共100页)
- 2016届广东省汕头市高三下学期第二次模拟(二模)考试理综生物试
- 电梯电气故障查找方法
- 浅谈如何发挥国有企业董监事会的职能作用
- 毕业设计---发酵法年产5万吨乙醇的工艺设计
- 十三五重点项目-淀粉塑料项目资金申请报告