STMCU小助手
发布时间:2022-1-23 15:58
|
1、时钟安全系统(CSS) ! Z- j8 L& e! J! b 时钟安全系统被激活后,时钟监控器将实时监控外部高速振荡器;如果HSE时钟发生故障,外部振荡器自动被关闭,产生时钟安全中断,该中断被连接到Cortex-M3的NMI的中断;同时CSS将内部RC振荡器切换为STM32的系统时钟源(对于STM32F103,时钟失效事件还将被送到高级定时器TIM1的刹车输入端,用以实现电机保护控制)。 操作流程: : H' M8 R8 S" b! @. H6 W 1)、启动时钟安全系统CSS: RCC_ClockSecuritySystemCmd(ENABLE); (NMI中断是不可屏蔽的!) . k/ G- G- l( l 2)外部振荡器失效时,产生NMI中断,对应的中断程序:
9 ^% N0 F. s, W; H 3)、在RCC的中断处理程序中,再对HSE和PLL进行相应的处理。 6 P" f( W8 z) \5 ] 注意:一旦CSS被激活,当HSE时钟出现故障时将产生CSS中断,同时自动产生 NMI。NMI将被不断执行,直到CSS中断挂起位被清除。因此,在NMI的处理程序中 必须通过设置时钟中断寄存器(RCC_CIR)里的CSSC位来清除CSS中断。 2、SysTick工作原理 # g0 k: L5 L; c) `, p7 j Cortex-M3的内核中包含一个SysTick时钟。SysTick 为一个24位递减计数器,SysTick设定初值并使能后, 每经过1个系统时钟周期,计数值就减1。计数到0时, SysTick计数器自动重装初值并继续计数,同时内部的 COUNTFLAG标志会置位,触发中断(如果中断使能)。 3、内部时钟输出PA.8(MCO) STM32的PA.8引脚具有复用功能——时钟输出(MCO), 该功能能将STM32内部的时钟通过PA.8输出. 操作流程: 1)、设置PA.8为复用Push-Pull模式。 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; ; z7 _7 f9 o" s2 Z W9 z GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 4 {1 I' H4 U' ~9 ~8 ?$ l$ I, V GPIO_Init(GPIOA, &GPIO_InitStructure); 1 E; Q3 X2 ]; Z2 @& J2 S 2)、选择输出时钟源。 时钟的选择由时钟配置寄存器(RCC_CFGR)中的MCO[2:0]位控制。 RCC_MCOConfig(RCC_MCO); 参数RCC_MCO为要输出的内部时钟: " l" E7 P" J1 D, O RCC_MCO_NoClock --- 无时钟输出 RCC_MCO_SYSCLK --- 输出系统时钟(SysCLK) 3 Z$ K7 [/ l' R* a, f7 E RCC_MCO_HSI --- 输出内部高速8MHz的RC振荡器的时钟(HSI) * w- J. s Y @) t RCC_MCO_HSE --- 输出高速外部时钟信号(HSE) * V. \+ l+ n! z- ^1 `- }* D RCC_MCO_PLLCLK_Div2 --- 输出PLL倍频后的二分频时钟(PLLCLK/2) ( M6 q# J T3 H7 R: N ) q8 e, u: a, }7 U2 W6 @; @ f0 V 注:由于STM32 GPIO输出管脚的最大响应频率为50MHz,如果输出频率超过50MHz,则输出的波形会失真。 " w& G5 X: T4 C4 j % u7 t. R# S3 E! Q, v9 q 4、可编程电压监测器(PVD) STM32内部自带PVD功能,用于对MCU供电电压VDD进行监控。通过电源控制寄存器中的PLS[2:0]位可以用来设定监控电压的阀值,通过对外部电压进行比较来监控电源。当条件触发,需要系统进入特别保护状态,执行紧急关闭任务:对系统的一些数据保存起来,同时对外设进行相应的保护操作。 ! f5 q; O3 I! C 操作流程: 9 k" Y# o8 ^ O/ v2 A! z 1)、系统启动后启动PVD,并开启相应的中断。 PWR_PVDLevelConfig(PWR_PVDLevel_2V8); // 设定监控阀值 PWR_PVDCmd(ENABLE); // 使能PVD ; L) v; X" U' R' `& c- b EXTI_StructInit(&EXTI_InitStructure); 5 x6 m+ ]% B' Y. c% I4 N EXTI_InitStructure.EXTI_Line = EXTI_Line16; // PVD连接到中断线16上 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //使用中断模式 7 B5 N! A+ k' k0 i8 c% k4 s, y3 u EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Raising;//电压低于阀值时产生中断 EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能中断线 / @2 Y& O% ]. g; U4 h) Z. u EXTI_Init(&EXTI_InitStructure); // 初始 EXTI_InitStructure.EXTI_Trigger的赋值可选项: : m$ d0 I, W2 a. ~3 E2 W EXTI_Trigger_Rising---表示电压从高下降到低于设定阀值时产生中断; EXTI_Trigger_Falling---表示电压从低上升到高于设定阀值时产生中断; EXTI_Trigger_Rising_Falling---表示电压上升或下降越过设定阀值时都产生中断。 2 g! S% g; q1 o2 J 2)、当工作电压低于设定阀值时,将产生PVD中断,在中断程序中进行相应的处理: void PVD_IRQHandler(void) , K; ]" _4 ^ n! j: a { 4 F: s) \; Q+ R2 L, E, O EXTI_ClearITPendingBit(EXTI_Line16); …… // 用户添加紧急处理代码处 } 4 n6 V3 K% K" U2 _9 Y+ R 5、STM32上不使用外部晶振,OSC_IN和OSC_OUT的接法 : ]; e$ ~' |3 @9 ? 1)、对于100脚或144脚的产品,OSC_IN应接地,OSC_OUT应悬空。 - C$ l* M# A7 Z s# U" E 2)、对于少于100脚的产品,有2种接法: , o6 x" o3 y2 I, o/ ] H- S 2.1)、OSC_IN和OSC_OUT分别通过10K电阻接地。 此方法可提高EMC性能。 2.2)、分别重映射OSC_IN和OSC_OUT至PD0和PD1,再配置PD0和PD1为推挽输出并输出'0'。 ; k( Z4 h8 [' B 此方法可以减小功耗并(相对上面2.1),并节省2个外部电阻。 6 \1 T% g E9 R) p+ G* A 0 v2 I' f" `( J% `4 A8 p 8 g7 g5 \! S8 c3 f3 N- s ============================ Interrupt/Evens ========================= N' y# t2 L! f0 T2 Z# S4 g( z 1、NVIC的优先级概念 占先式优先级 (pre-emption priority): U3 A9 P; P! [, L6 M v2 m9 d 高占先式优先级的中断事件会打断当前的主程序/中断程序运行— —抢断式优先响应,俗称中断嵌套。 - L _. }' e9 E; a8 ] 副优先级(subpriority): 在占先式优先级相同的情况下,高副优先级的中断优先被响应; : G, S1 S0 v' Z0 `* ^# B 在占先式优先级相同的情况下,如果有低副优先级中断正在执行, 高副优先级的中断要等待已被响应的低副优先级中断执行结束后才 能得到响应——非抢断式响应(不能嵌套)。 5 K; ?0 a! S1 m+ {- b ' z1 w( B; g/ n4 x; t9 @ 2、判断中断是否会被响应的依据 首先是占先式优先级,其次是副优先级; ( X8 y H/ s4 \" S0 w% N 占先式优先级决定是否会有中断嵌套; 3 q6 h- j0 b- {9 j4 x& h/ y Reset、NMI、Hard Fault 优先级为负(高于普通中断优先级)且不可调整。 ' H K. j4 p1 |3 j 3、STM32中用到的Cortex-M3寄存器说明 在STM32中用到了Cortex-M3定义的三组寄存器,有关这三组寄存器的说明不在STM32的技术手册中,需要参考ARM公司发布的Cortex-M3 Technical Reference Manual (r2p0)。 在STM32的固件库中定义了三个结构体与这三个寄存器组相对应,这三个结构体与ARM手册中寄存器的对应关系如下: 1)、NVIC寄存器组 STM32的固件库中有如下定义: 0 t5 I7 W# V/ P8 E3 I1 J
它们对应ARM手册中的名称为 ISER = Interrupt Set-Enable Registers ICER = Interrupt Clear-Enable Registers 7 |1 L5 V5 g; H4 V$ o0 m. [! | ISPR = Interrupt Set-Pending Register . u7 z x% F& Y$ f Q* b ICPR = Interrupt Clear-Pending Register IABR = Active Bit Register IPR = Interrupt Priority Registers 2 e! ]/ N$ J/ x 每个寄存器有240位,以Interrupt Set-Enable Registers说明,ISER[0]对应中断源0~31,ISER[1]对应中断源32~63,STM32只有60个中断源,所以没有ISER[2:7]。 参考STM32技术参考手册中的中断向量表,中断源的位置为: 7 W. H4 P, D! @ @7 D9 y, B 位置0 - WWDG = Window Watchdog interrupt 位置1 - PVD = PVD through EXTI Line detection interrupt & Y$ `, T# X' E+ N 位置2 - TAMPER = Tamper interrupt ...... 位置58 - DMA2_Channel3 = DMA2 Channel3 global interrupt + K2 Q9 v4 t! ^" u) H* r+ X 位置59 - DMA2_Channel4_5 = DMA2 Channel4 and DMA2 Channel5 global interrupts 9 r. ]( S1 M+ o9 ?2 K* A- b9 y# F ( [+ F' R* n+ X0 _( O3 ~; @ 2)、系统控制寄存器组 STM32的固件库中有如下定义:
它们对应ARM手册中的名称为 7 g" B! f( ]* ?4 E7 p# T3 ^ CPUID = CPUID Base Register ICSR = Interrupt Control State Register 7 `$ r, u- h% i" G$ t VTOR = Vector Table Offset Register AIRCR = Application Interrupt/Reset Control Register # J) W5 | Q) {3 v2 r) q SCR = System Control Register $ Y+ _. M5 }. l3 ^: n- p- C CCR = Configuration Control Register 8 r* T; K" ]$ ?5 s SHPR = System Handlers Priority Register * [) s: I. D5 u2 Q2 [1 ] SHCSR = System Handler Control and State Register + Z4 r9 R9 s# S. U$ w$ | CFSR = Configurable Fault Status Registers HFSR = Hard Fault Status Register DFSR = Debug Fault Status Register ; N1 `4 i" x3 C5 \/ S" A MMFAR = Mem Manage Address Register BFAR = Bus Fault Address Register AFSR = Auxiliary Fault Status Register 3)、系统时钟寄存器组 y J* b6 B n- X9 S! \ STM32的固件库中有如下定义: 8 ]" m5 Y2 _3 \7 ?5 T
它们对应ARM手册中的名称为 CTRL = SysTick Control and Status Register LOAD = SysTick Reload Value Register + W+ C% w1 e; Y! P VAL = SysTick Current Value Register 8 t1 S& e$ R' w; c CALIB = SysTick Calibration Value Register 2 A* R, X9 C X( |, v, [: D# V: F( M ================================= DMA ================================ 1、DMA普通模式和循环模式的区别 4 P9 }' A& O( F p8 i" r 循环模式:用于处理一个环形的缓冲区,每轮传输结束时数据传输 的配置会自动地更新为初始状态,DMA传输会连续不断地进行。 * t/ N8 J, V* w6 P8 C3 Q 普通模式:在DMA传输结束时,DMA通道被自动关闭,进一步的 DMA请求将不被满足。 9 b+ z1 a ?( l, G4 h 2、DMA传输需要指定的条件: 传输源:DMA控制器从传输源读出数据; 传输目标:DMA控制器将数据传输的目标; % A) q. i8 w+ u8 e* ~ 触发信号:用于触发一次数据传输的动作,执行一个单位的传输源至传输目标的数据传输。可以用来控制传输的启动条件。 - P4 e8 R& X* f2 j" \% F 4 Z/ P# X2 E$ i! P y/ R6 e ================================= ADC ================================ 1、STM32的内部温度传感器 + r. l0 P& Q/ R( ~4 N STM32内部温度传感器与ADC的通道16相连,与ADC配 合使用实现温度测量。测量范围–40~125℃,精度 ± 1.5℃ 操作流程: 1)、设置ADC相关参数
' J6 ^* O1 V- n- } 2)、选中ADC1的通道16作为输入,设置采样时间17.1us ( Ncycle × tADC = 17.1靤 )。 " n/ [/ o. a5 n! }5 S) U i // ADC1 regular channel16 Temp Sensor configuration ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_55Cycles5); , L7 r% O5 h- |' d; } O 3)、设置寄存器ADC_CR2中的TSVREFE位激活温度传感器 ) L! i- z0 O Y9 s$ @1 i // Enable the temperature sensor and vref internal channel ADC_TempSensorVrefintCmd(ENABLE); 4)、转换采样值为温度 2 s% v* e; M4 g/ a! U" j, | ADC转换结束以后,读取ADC_DR寄存器中的结果,转换温度值计算公式如下: : N9 D& l; ?/ l V25 - VSENSE 6 ?) w) _( z2 U- A$ d6 ~- ^3 A" E T(℃) = ------------ + 25 Avg_Slope V25: 温度传感器在25℃时 的输出电压,典型值1.43 V。 ( d2 T: m: s0 C' J VSENSE:温度传感器的当前输出电压,与ADC_DR 寄存器中的结果ADC_ConvertedValue之间的转换关系为: * g: j6 j: i+ c. o8 O, } ADC_ConvertedValue * Vdd VSENSE = -------------------------- : o6 Y5 G0 [" t Vdd_convert_value(0xFFF) Avg_Slope:温度传感器输出电压和温度的关联参数,典型值4.3 mV/℃。 2 Q4 V4 F' v7 h( k8 @ //Converted Temperature Vtemp_sensor = ADC_ConvertedValue * Vdd / Vdd_convert_value; Current_Temp = (V25 - Vtemp_sensor)/Avg_Slope + 25; 2、VDDA的电压范围 4 O5 }& P2 `4 @ A' O STM32的数据手册规定,VDD与VDDA之间的压差不能大于300mV。ADC的工作电压范围在2.4V~3.6V,供电电压VDD范围在2.0V~3.6V. # [2 @2 `* k8 b ~ \- O " d2 c$ _# P2 q ================================= DAC ================================ m8 T' t! \4 A2 D' B , c! b/ J9 q U' c) y! d" A ============================= Advanced Timer ========================= " P% i. I: ]7 q" l8 d ============================== General Timer ========================= ================================ Base Timer ========================== ============================= Real-Time Clock ======================== 3 H' B7 I/ d/ o+ Y& } =========================== Independent watchdog ===================== " v3 Y5 \) `2 ~+ i% { ============================= Windows Watchdog ======================= ) `2 e& M& i: H9 u$ X- n ! W0 d" ]; c8 f2 j$ i5 x ! D" h) ^! K* [; r ================================== FSMC ============================== ( `5 }7 {7 X4 @ 4 z' I8 o# y, A ================================== SDIO ============================== 1 M+ E! u6 w! ] ================================== USB =============================== 1 Q1 W' x; v a- L& w 1、STM32的USB中断说明 STM32的USB模块可产生三种中断:USB唤醒中断、USB高优先级中断和USB低优先级中断,这三种中断对应事件如下: 1)、USB唤醒中断 - 在中断向量表中的位置是42 这个中断在USB设备从暂停模式唤醒时产生,唤醒事件由USB_ISTR寄存器的WKUP位标识。 2)、USB高优先级中断 - 在中断向量表中的位置是19 ! J) g4 g: N Z 这个中断仅由USB同步(Isochronous)模式传输或双缓冲块(Bulk)传输模式下的正确传输事件产生,正确传输事件由USB_ISTR寄存器的CTR位标识。 % y8 S. W0 n9 u. I) C 3)、USB低优先级中断 - 在中断向量表中的位置是20 这个中断由所有其它的USB事件产生,例如正确传输(不包括同步模式和双缓冲块模式)、USB复位等,事件标志位在USB_ISTR寄存器中。 , v( G: e- ?; O- r+ U 在STM提供的STM32 USB 开发包中的例程包含了上述三种中断的处理方法。例如在USB Speaker例程中,CTR_HP函数处理USB高优先级中断;在所有例子中都有USB_Istr()函数处理USB低优先级中断。 ' `% F6 C% }1 I8 q% b 4 q3 Z! T* O; O. x ================================= bxCAN ============================== . Z+ z, n7 B( B6 b8 @ v 1、CAN波特率的设定计数 ================================ Etherne ============================== ================================== SPI =============================== ' e9 g, S) i- v# S# |* T* P1 r, ~ 1、SPI外设的NSS引脚设置为通用IO口 由于SPI外设的SPI_CR1寄存器中SSM置1时,NSS引脚可被被释放用于GPIO使用,因此无论是在SPI的主模式或是从模式下均可以将NSS引脚释放,由软件或硬件进行NSS管理; 操作流程: 1)、初始化SPI外设,设置NSS由软件管理: SPI_InitStructure.SPI_NSS= SPI_NSS_Soft; 2)、如果NSS引脚用于其他外设时,需要使能NSS输出: " v, T0 ^; i3 n6 O SPI_SSOutputCmd(SPIx, ENABLE); 2、SPI 单线传输 此模式下限制:只能用作输入或者输出,或者工作在半双工模式下。 9 X( z: `3 } c; Y; O# b- \ " t$ E3 s! S% w+ w: ^; a , u; `4 O7 g+ E; d+ R9 @- J ================================== I2C =============================== & e+ ?5 u T; i 2 R4 ?5 Q P5 j/ R ================================= USART ============================== $ d, V5 @( G1 o5 T* P ============================ Device Signature ======================== 1、 STM32F10xxx系列MCU内部含有一个出厂被固化的96bit唯一识别ID,该ID可以用于芯片加密、设备识别等一类特殊应用。 读取该ID的方法: 2 J8 e2 G6 ]% m8 T: i+ r1 [ u32 DevID[3]; 5 y, F2 a2 i/ Y1 Y, V: |) L DevID[0] = *(vu32*)(0x1ffff7e8); DevID[1] = *(vu32*)(0x1ffff7ec); DevID[2] = *(vu32*)(0x1ffff7f0); / h/ G9 E% x c& P$ S* r, c 数组DevID[3]中即保存了MCU的ID。 ' B) X, {* ?. T% a/ [2 w 注:256K Flash或以上容量的STM32,仅“Z”版本才有,之前的“A”版本没有。 2、 3 R$ ~& |; b- C g3 w$ k * P7 M' ]/ m U0 b+ { ================================== I2C =============================== 0 I# r4 u# S U8 A+ y4 m6 X / `1 o6 P o; h" N 5 o4 V+ L* A8 \* K ================================= Flash ============================== 1、STM32对内部Flash的保护措施 所有STM32的芯片都提供对Flash的保护,防止对Flash的非法访问 - 写保护和读保护。 1)、读保护即大家通常说的“加密”,是作用于整个Flash存储区域。一旦设置了Flash的读保护,内置的Flash存储区只能通过程序的正常执行才能读出,而不能通过下述任何一种方式读出: 通过调试器(JTAG或SWD); 5 |. x2 @3 p$ `7 X 从RAM中启动并执行的程序; $ |1 k% x8 m5 X( b 2)、写保护是以四页(1KB/页) Flash存储区为单位提供写保护,对被保护的页实施编程或擦除操作将不被执行,同时产生操作错误标志。 $ s% ^$ ?+ K6 O/ R 读与写设置的效果见下表: 7 r: w& h* D* ` |5 Z" H0 y 读保护 写保护 对Flash的操作功能 有效 有效 CPU只能读,禁止调试和非法访问。 有效 无效 CPU可以读写,禁止调试和非法访问,页0~3为写保护。 无效 有效 CPU可读,允许调试和非法访问。 + C6 f- q4 s, ~& S 无效 无效 CPU可以读写,允许调试和非法访问。 . S& ]" G& }4 r* M 2、当Flash读保护生效时,CPU执行程序可以读受保护的Flash区,但存在两个例外情况: ! u9 [: t/ i4 E {* K1 ? 1)、调试执行程序时; 2)、从RAM启动并执行程序时 $ n, l5 ^7 [& `1 ^: Q & `" D; }3 w2 I8 n5 z! i. P5 x STM32还提供了一个特别的保护,即对Flash存储区施加读保护后,即使没有启用写保护,Flash的第 0 ~ 3 页也将处于写保护状态,这是为了防止修改复位或中断向量而跳转到RAM区执行非法程序代码。 h# r+ n N6 P$ ? 3、Flash保护相关函数 # Z# k- [% d2 C: \3 } FLASH_Unlock(); //Flash解锁 FLASH_ReadOutProtection(DISABLE); //Flash读保护禁止 FLASH_ReadOutProtection(ENABLE); //Flash读保护允许 0 c" M7 p7 Y6 K' W3 q : A& B; M3 H$ q8 b ================================== CRC =============================== : F, n1 J- [ x 1、CRC计算公式 " f4 |3 o+ i& t3 O5 l( ^. X+ @ 所有的STM32芯片都内置了一个硬件的CRC计算模块,可应用到通信程序中,这个CRC计算模块使用常见的、在以太网中使用的计算多项式: X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2 + X + 1 ! F1 ]6 K; J% Q( p" a+ w+ i* N 写成16进制就是:0x04C11DB7 , u) E% `( M5 `' W5 n- Z, w 2、使用这个内置CRC模块操作步骤: 5 c/ w+ X& L$ e7 N/ U2 U 复位CRC模块(设置CRC_CR=0x01),这个操作把CRC计算的余数初始化为0xFFFFFFFF 把要计算的数据按每32位分割为一组数据字,并逐个地把这组数据字写入CRC_DR寄存器(既下图中的绿色框) $ y( J" K% S& u* V' n$ _5 J9 g 写完所有的数据字后,就可以从CRC_DR寄存器(既下图中的兰色框)读出计算的结果。 * q6 w1 L v* S2 S( s7 @1 f 注意:虽然读写操作都是针对CRC_DR寄存器,但实际上是访问的不同物理寄存器。 4 ]6 }* ^( f' W6 H 3、C语言描述的这个计算模块算法。可放在通信的另一端,对通信的正确性进行验证: ' Z$ a. ?6 H4 [* _4 z
注意: # S# y1 W2 ~) t" S: Z) u% ?2 W- c' d 1)、上述算法中变量CRC,在每次循环结束包含了计算的余数,它始终是向左移位(既从最低位向最高位移动),溢出的数据位被丢弃。 2)、输入的数据始终是以32位为单位,如果原始数据少于32位,需要在低位补0,当然也可以高位补0。 3)、假定输入的DWORD数组中每个分量是按小端存储。 4)、输入数据是按照最高位最先计算,最低位最后计算的顺序进行。 & i1 s2 k( o/ v5 f 例如: 如果输入0x44434241,内存中按字节存放的顺序是:0x41, 0x42, 0x43, 0x44。计算的结果是:0xCF534AE1 & P2 V$ g6 ]/ V% ? 如果输入0x41424344,内存中按字节存放的顺序是:0x44, 0x43, 0x42, 0x41。计算的结果是:0xABCF9A63 2 G$ P7 _# z) |7 B8 g : C) I, \# ]! ?# U4 m, S ====================================================================== " L! k& }/ u+ ~+ q1 ] ; r' ~$ X' Y# [1 q* ^5 v7 H' u 按照使用编译器 ====================================================================== ; S K" n* h g& X ================================== IAR =============================== # n4 Y# C( Y8 C 1、IAR环境下如果链接工程文件,出现堆栈溢出错误,该如何处理? 打开链接文件lnkarm_flash.xcl或者是lnkarm_ram.xcl //************************************************************************* // Stack and heap segments. ]. U. W6 |$ h4 m, l5 V //************************************************************************* ' f0 J, N H9 E8 r. ]0 v -D_CSTACK_SIZE=400 <----------------------------------------修改这里 ' ~+ Z c& V4 Z3 V4 | 注:该修改方式仅适合IAR for ARM 4.xx版本。 8 O8 ?) k) s2 X' p. T6 ?2 o# n; n 0 @8 N% U: }8 k, S$ t 2、IAR编译输出HEX格式的目标文件 1)、Options->C/C++ Compiler->Output->Generate debug information 选项前的钩去掉 % q7 q5 z f8 h1 U: e7 f! u' a 2)、Options->Assembler->Output->Generate debug information 选项前的钩去掉 3)、Options->Linker->Output->Output File->Override default 选项前的钩选上并把文件名的后缀改成.hex 4)、Options->Linker->Output->Output File->Format->Other 选项前的钩选上并把Output格式改为intel-extended 经过以上设置,在Rebuld All之后会在/Debug/Exe下生成.hex格式目标文件 5 ~3 T( Y. H1 \8 }! K. d* }$ P a5 D6 ]1 s, i. o9 u/ o/ B8 O 3、IAR编译输出BIN格式的目标文件 * N! M. G% T1 S6 U7 Y 1)、Options->C/C++ Compiler->Output->Generate debug information 选项前的钩去掉 2)、Options->Assembler->Output->Generate debug information 选项前的钩去掉 3)、Options->Linker->Output->Output File->Override default 选项前的钩选上并把文件名的后缀改成.bin # ` C. a0 X1 M5 n: ?" d! T 4)、Options->Linker->Output->Output File->Format->Other 选项前的钩选上并把Output格式改为row-binary , m5 A6 ^) y% {: w$ g% U @0 l 经过以上设置,在Rebuld All之后会在/Debug/Exe下生成.bin格式目标文件 ================================== MDK =============================== " w* y* ~6 u9 A0 q4 r6 @! q3 j2 z2 { 1、在MDK代码编辑环境下不能使用Goto Definition(用于查找某个变量的类型及定义)、Goto Reference(用于查找某个函数申明的原型)功能? 1 @8 W8 J; L$ K. c' T1 \ % C! {& h T4 V/ l, G& O. ? 解决:打开Project->Target-Options->Output,将Browse Information复选框勾上。 4 q( [# C* l6 b) a$ z% C 2、当使用STM32固件库与RTX Kernel时,使用isr_evt_set(),事件无响应? , ^; X" Y2 `0 O5 {0 o5 U+ q" @ 解决:编辑STM32固件库的“stm32f10x_vector.s”文件: ... IMPORT SVC_Handler ;name changed according to RTX usage 2 M2 e/ U ~+ u% S, p8 Y& r IMPORT DebugMonitor 2 m# A+ x" d: `+ H IMPORT PendSV_Handler ;修改加入 * M! c5 q% }) M% p8 S+ T( I$ [ IMPORT SysTick_Handler ;name changed according to RTX usage ... DCD SVC_Handler & Y3 x* k8 X$ L4 F: ^ DCD DebugMonitor DCD 0 ; Reserved 0 J8 e, ~9 F* D* k( X- W2 v+ S4 g" {1 ` DCD PendSV_Handler ;修改加入 DCD SysTick_Handler 3 ?0 a9 |$ O9 k" p1 E |
实战经验 | 基于STM32G0B1的全桥移相+同步整流PWM解决方案
DMA 原理从 0 到 1:为什么它能解放 CPU?一文讲透 DMA 的工作流程
【福利三:逢7发帖赢大礼】8、基于STM32G070板子的Ymodem串口协议IAP Bootloader开发
【福利三:逢7发帖赢大礼】7、基于STM32G070板子TF卡的FATFS移植
【福利三:逢7发帖赢大礼】6、基于STM32G070板子spiflash的FATFS移植
【福利三:逢7发帖赢大礼】5、基于STM32G070板子IRDA红外遥控接收解码
【福利三:逢7发帖赢大礼】4、基于STM32G070板子SPI flash 移植SFUD库
【福利三:逢7发帖赢大礼】基于STM32G070板子的uart shell移植设计
【福利三:逢7发帖赢大礼】3、基于STM32G070板子的YModem串口协议通信
【福利三:逢7发帖赢大礼】2、基于STM32G070板子的OLED移植U8G2库
微信公众号
手机版