STMCU小助手
发布时间:2022-1-23 15:58
|
1、时钟安全系统(CSS) % p7 n' A1 k3 D2 p U) ~- o 时钟安全系统被激活后,时钟监控器将实时监控外部高速振荡器;如果HSE时钟发生故障,外部振荡器自动被关闭,产生时钟安全中断,该中断被连接到Cortex-M3的NMI的中断;同时CSS将内部RC振荡器切换为STM32的系统时钟源(对于STM32F103,时钟失效事件还将被送到高级定时器TIM1的刹车输入端,用以实现电机保护控制)。 ! f/ C7 l7 }6 { 操作流程: 1)、启动时钟安全系统CSS: RCC_ClockSecuritySystemCmd(ENABLE); (NMI中断是不可屏蔽的!) + W3 ]* d8 o% z/ \8 i8 h 2)外部振荡器失效时,产生NMI中断,对应的中断程序:
# h' q( N6 ~) I# l* d 3)、在RCC的中断处理程序中,再对HSE和PLL进行相应的处理。 1 F. C$ d# g! V# r9 E, n0 F * i" @1 A( P+ @ j 注意:一旦CSS被激活,当HSE时钟出现故障时将产生CSS中断,同时自动产生 NMI。NMI将被不断执行,直到CSS中断挂起位被清除。因此,在NMI的处理程序中 必须通过设置时钟中断寄存器(RCC_CIR)里的CSSC位来清除CSS中断。 2、SysTick工作原理 Cortex-M3的内核中包含一个SysTick时钟。SysTick 为一个24位递减计数器,SysTick设定初值并使能后, 每经过1个系统时钟周期,计数值就减1。计数到0时, SysTick计数器自动重装初值并继续计数,同时内部的 COUNTFLAG标志会置位,触发中断(如果中断使能)。 ( [9 O. }& Q& M" ?* F/ } 8 W* ]4 C( F$ m1 X0 a 3、内部时钟输出PA.8(MCO) 2 n. m! Z- j$ A& e/ ~$ _( w8 @ STM32的PA.8引脚具有复用功能——时钟输出(MCO), 该功能能将STM32内部的时钟通过PA.8输出. 操作流程: 1)、设置PA.8为复用Push-Pull模式。 / {2 }/ Q( L% Y% k% U4 V5 t3 L GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 8 ]1 M8 J( |. Q$ ~+ t- I GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); 2)、选择输出时钟源。 a- Z# @: ?# d3 H0 k" J 时钟的选择由时钟配置寄存器(RCC_CFGR)中的MCO[2:0]位控制。 RCC_MCOConfig(RCC_MCO); ! v% V3 Y5 x4 T 参数RCC_MCO为要输出的内部时钟: % t1 Q; g: H7 j; R8 A% n" |7 U& B RCC_MCO_NoClock --- 无时钟输出 _& M Y9 ? U' c4 w RCC_MCO_SYSCLK --- 输出系统时钟(SysCLK) RCC_MCO_HSI --- 输出内部高速8MHz的RC振荡器的时钟(HSI) RCC_MCO_HSE --- 输出高速外部时钟信号(HSE) ' c |' v$ o2 Q0 G1 o RCC_MCO_PLLCLK_Div2 --- 输出PLL倍频后的二分频时钟(PLLCLK/2) ' H+ l; Q( W9 U4 ^+ A+ F & W+ C% `/ l; n, ^- [. x 注:由于STM32 GPIO输出管脚的最大响应频率为50MHz,如果输出频率超过50MHz,则输出的波形会失真。 : a; f& w; J6 v 4、可编程电压监测器(PVD) - t V; o; z* C4 g$ [ STM32内部自带PVD功能,用于对MCU供电电压VDD进行监控。通过电源控制寄存器中的PLS[2:0]位可以用来设定监控电压的阀值,通过对外部电压进行比较来监控电源。当条件触发,需要系统进入特别保护状态,执行紧急关闭任务:对系统的一些数据保存起来,同时对外设进行相应的保护操作。 : n4 e/ B2 N7 ]) U 操作流程: 1)、系统启动后启动PVD,并开启相应的中断。 ; \# D; l4 \! m9 a( `& `) P3 V/ K PWR_PVDLevelConfig(PWR_PVDLevel_2V8); // 设定监控阀值 & u8 x0 V: }- [, {3 H PWR_PVDCmd(ENABLE); // 使能PVD EXTI_StructInit(&EXTI_InitStructure); EXTI_InitStructure.EXTI_Line = EXTI_Line16; // PVD连接到中断线16上 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //使用中断模式 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Raising;//电压低于阀值时产生中断 EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能中断线 * f9 p; R4 E8 t8 @ EXTI_Init(&EXTI_InitStructure); // 初始 EXTI_InitStructure.EXTI_Trigger的赋值可选项: EXTI_Trigger_Rising---表示电压从高下降到低于设定阀值时产生中断; , b0 {9 {0 b! P) L EXTI_Trigger_Falling---表示电压从低上升到高于设定阀值时产生中断; EXTI_Trigger_Rising_Falling---表示电压上升或下降越过设定阀值时都产生中断。 8 S& O; ~- K6 z Z 2)、当工作电压低于设定阀值时,将产生PVD中断,在中断程序中进行相应的处理: void PVD_IRQHandler(void) 2 j5 f/ x% e! n$ \ { EXTI_ClearITPendingBit(EXTI_Line16); 5 m" l# {6 Z* h …… // 用户添加紧急处理代码处 % e* P! {4 [1 R, _5 _; Q( a } 1 Q& Q$ P/ y% g7 K8 v2 X( A3 T % f! r8 ]2 E O3 ]0 t 5、STM32上不使用外部晶振,OSC_IN和OSC_OUT的接法 1)、对于100脚或144脚的产品,OSC_IN应接地,OSC_OUT应悬空。 2)、对于少于100脚的产品,有2种接法: 2.1)、OSC_IN和OSC_OUT分别通过10K电阻接地。 此方法可提高EMC性能。 2.2)、分别重映射OSC_IN和OSC_OUT至PD0和PD1,再配置PD0和PD1为推挽输出并输出'0'。 & b, ^: g% y3 U. w3 z s& @# G+ t 此方法可以减小功耗并(相对上面2.1),并节省2个外部电阻。 5 \4 G# M3 t. d - S' q9 E. F1 F7 g) J 7 }: Z4 I, h! Z% @5 \( e0 O ============================ Interrupt/Evens ========================= 1、NVIC的优先级概念 6 c% B2 Z5 Q) e; V3 O& C* } 占先式优先级 (pre-emption priority): / c' B$ S% r: H+ v9 F) z+ o 高占先式优先级的中断事件会打断当前的主程序/中断程序运行— —抢断式优先响应,俗称中断嵌套。 副优先级(subpriority): 7 a3 w6 p C$ M A$ \! V 在占先式优先级相同的情况下,高副优先级的中断优先被响应; 0 {( \, { t% S; c$ F! e) e 在占先式优先级相同的情况下,如果有低副优先级中断正在执行, 高副优先级的中断要等待已被响应的低副优先级中断执行结束后才 能得到响应——非抢断式响应(不能嵌套)。 2、判断中断是否会被响应的依据 : C0 ^. e& W: } N( J# d 首先是占先式优先级,其次是副优先级; : f- c6 B" F% F# W2 v- i& N, k 占先式优先级决定是否会有中断嵌套; Reset、NMI、Hard Fault 优先级为负(高于普通中断优先级)且不可调整。 3、STM32中用到的Cortex-M3寄存器说明 在STM32中用到了Cortex-M3定义的三组寄存器,有关这三组寄存器的说明不在STM32的技术手册中,需要参考ARM公司发布的Cortex-M3 Technical Reference Manual (r2p0)。 6 X2 n- j8 L6 Z+ w 在STM32的固件库中定义了三个结构体与这三个寄存器组相对应,这三个结构体与ARM手册中寄存器的对应关系如下: ; }* N- y' H9 c: a 1)、NVIC寄存器组 E- ?; s& x- Q( a7 T STM32的固件库中有如下定义:
它们对应ARM手册中的名称为 6 X0 O$ e' o$ p6 C& z2 c$ s9 d% m ISER = Interrupt Set-Enable Registers + a; g! u6 f/ u$ d: [) m' \" Z ICER = Interrupt Clear-Enable Registers ISPR = Interrupt Set-Pending Register ICPR = Interrupt Clear-Pending Register IABR = Active Bit Register IPR = Interrupt Priority Registers ( b+ v% j9 c* Z( t" M# U 每个寄存器有240位,以Interrupt Set-Enable Registers说明,ISER[0]对应中断源0~31,ISER[1]对应中断源32~63,STM32只有60个中断源,所以没有ISER[2:7]。 # n0 S/ r* [4 w9 q. [1 T+ H \' ~ 参考STM32技术参考手册中的中断向量表,中断源的位置为: 位置0 - WWDG = Window Watchdog interrupt " W% p4 [& ?/ F: d \ 位置1 - PVD = PVD through EXTI Line detection interrupt 位置2 - TAMPER = Tamper interrupt ...... 位置58 - DMA2_Channel3 = DMA2 Channel3 global interrupt 位置59 - DMA2_Channel4_5 = DMA2 Channel4 and DMA2 Channel5 global interrupts f% F$ {$ X2 B, V8 }; N" y 2)、系统控制寄存器组 STM32的固件库中有如下定义:
. _2 E0 M9 e5 _9 P 它们对应ARM手册中的名称为 a; h5 i6 y. m CPUID = CPUID Base Register # K7 C; }" J: G3 z2 _6 U ICSR = Interrupt Control State Register VTOR = Vector Table Offset Register 5 T# Y4 X5 D/ H- [1 G4 a1 J AIRCR = Application Interrupt/Reset Control Register SCR = System Control Register 1 m7 A, U+ X5 E+ |* r" r CCR = Configuration Control Register 6 j( P3 J4 N3 @# z SHPR = System Handlers Priority Register % }1 T+ a# ]" q+ r SHCSR = System Handler Control and State Register CFSR = Configurable Fault Status Registers - S4 c l, E- i. [0 c/ ~ HFSR = Hard Fault Status Register % m4 u* E( q! b7 J0 H DFSR = Debug Fault Status Register ) q; A; |; n: m; C+ f( x8 p, J MMFAR = Mem Manage Address Register BFAR = Bus Fault Address Register & q" I8 E; A& |- w2 f1 b AFSR = Auxiliary Fault Status Register . ^ j: d: s" K 3)、系统时钟寄存器组 STM32的固件库中有如下定义:
它们对应ARM手册中的名称为 CTRL = SysTick Control and Status Register ; @) V8 ~% m8 g! }! J/ X. R LOAD = SysTick Reload Value Register VAL = SysTick Current Value Register CALIB = SysTick Calibration Value Register ; @* @5 ?3 ?( Z/ H E 9 s3 V; H9 p8 t3 K / B# z- z. G* M2 w; C; M+ { ================================= DMA ================================ 4 a) u, @. W, \0 p1 t* Z/ H 1、DMA普通模式和循环模式的区别 ' Z$ S5 f5 C/ S) i# E+ q0 n8 o9 t$ g; g 循环模式:用于处理一个环形的缓冲区,每轮传输结束时数据传输 的配置会自动地更新为初始状态,DMA传输会连续不断地进行。 & P4 ]$ @, _8 i 普通模式:在DMA传输结束时,DMA通道被自动关闭,进一步的 DMA请求将不被满足。 8 c0 W7 B. p+ A7 D& a, V) ` 2、DMA传输需要指定的条件: 传输源:DMA控制器从传输源读出数据; * N6 P; Q, R2 c- Y4 B9 G8 h 传输目标:DMA控制器将数据传输的目标; * p9 w$ u3 N4 A: J, L) p# M) O 触发信号:用于触发一次数据传输的动作,执行一个单位的传输源至传输目标的数据传输。可以用来控制传输的启动条件。 & [$ |$ b7 U8 ? ================================= ADC ================================ 2 N; ]3 s3 o! A7 c& G X3 N9 m; m 1、STM32的内部温度传感器 . W( y( O6 e8 V& V STM32内部温度传感器与ADC的通道16相连,与ADC配 合使用实现温度测量。测量范围–40~125℃,精度 ± 1.5℃ 操作流程: % s7 y7 z/ A8 f# S- u+ K" F6 | 1)、设置ADC相关参数
2)、选中ADC1的通道16作为输入,设置采样时间17.1us ( Ncycle × tADC = 17.1靤 )。 9 ~1 V: d% [0 T. v+ z. M // ADC1 regular channel16 Temp Sensor configuration ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_55Cycles5); 3 K2 X6 h4 q, n. u N 3)、设置寄存器ADC_CR2中的TSVREFE位激活温度传感器 0 \( V8 t- s7 y+ ?! X, U: f // Enable the temperature sensor and vref internal channel 6 Z w/ a" i2 y: Z ADC_TempSensorVrefintCmd(ENABLE); $ c) ]$ d; s7 J9 q/ y- p0 W 4)、转换采样值为温度 6 [9 C- `4 c' E) A ADC转换结束以后,读取ADC_DR寄存器中的结果,转换温度值计算公式如下: F9 @7 y4 u9 U7 d2 c V25 - VSENSE * Y6 x8 m) c! U" a T(℃) = ------------ + 25 & |! R, C8 T! n- \3 t$ p v Avg_Slope 9 e3 d6 M8 }5 L1 J& S V25: 温度传感器在25℃时 的输出电压,典型值1.43 V。 $ G. }) p" N2 g4 { VSENSE:温度传感器的当前输出电压,与ADC_DR 寄存器中的结果ADC_ConvertedValue之间的转换关系为: ADC_ConvertedValue * Vdd VSENSE = -------------------------- 2 H4 {! e {8 d Vdd_convert_value(0xFFF) Avg_Slope:温度传感器输出电压和温度的关联参数,典型值4.3 mV/℃。 //Converted Temperature $ G9 e! m8 [1 h Z7 x6 L# g" }7 U Vtemp_sensor = ADC_ConvertedValue * Vdd / Vdd_convert_value; J7 ^4 s$ V; j0 y Current_Temp = (V25 - Vtemp_sensor)/Avg_Slope + 25; 2、VDDA的电压范围 STM32的数据手册规定,VDD与VDDA之间的压差不能大于300mV。ADC的工作电压范围在2.4V~3.6V,供电电压VDD范围在2.0V~3.6V. 4 c# ], L% L1 U' _ - X9 B }6 Q" |; D u* d ================================= DAC ================================ 3 d9 k6 s) f* F( }# l% N ' {* i" ]; c. g F ============================= Advanced Timer ========================= 6 b; H* g& u9 O$ U4 Y1 ^ ============================== General Timer ========================= $ `( n! D) {+ D9 j |4 B . k% d9 d' ?4 g5 D n* f0 z ================================ Base Timer ========================== & b# U3 N. _$ H& ?6 A2 J ============================= Real-Time Clock ======================== . t$ O6 m& v' z5 b7 e 9 ?7 |5 U5 R" p: [! ~" |' S; M' f* r =========================== Independent watchdog ===================== / P8 h3 Q& M& J ============================= Windows Watchdog ======================= # Z+ i5 L6 D; n$ `5 B& G1 Z9 I) G 0 r+ b7 |- D+ M- | ================================== FSMC ============================== 0 K x. l; H2 C) Z: v" _ ================================== SDIO ============================== ( C9 k6 U( F6 Z }/ L- f6 q+ S ================================== USB =============================== 1、STM32的USB中断说明 ( _+ W# r3 l: c$ B9 Q# {+ P STM32的USB模块可产生三种中断:USB唤醒中断、USB高优先级中断和USB低优先级中断,这三种中断对应事件如下: 1)、USB唤醒中断 - 在中断向量表中的位置是42 这个中断在USB设备从暂停模式唤醒时产生,唤醒事件由USB_ISTR寄存器的WKUP位标识。 2)、USB高优先级中断 - 在中断向量表中的位置是19 % k. j6 D- m+ k 这个中断仅由USB同步(Isochronous)模式传输或双缓冲块(Bulk)传输模式下的正确传输事件产生,正确传输事件由USB_ISTR寄存器的CTR位标识。 5 a7 f% W% u1 B. ~) R) s [% _* E 3)、USB低优先级中断 - 在中断向量表中的位置是20 这个中断由所有其它的USB事件产生,例如正确传输(不包括同步模式和双缓冲块模式)、USB复位等,事件标志位在USB_ISTR寄存器中。 3 C7 r0 w) |4 y1 h, e( z, p1 C 在STM提供的STM32 USB 开发包中的例程包含了上述三种中断的处理方法。例如在USB Speaker例程中,CTR_HP函数处理USB高优先级中断;在所有例子中都有USB_Istr()函数处理USB低优先级中断。 # r6 h; `2 C0 y0 E $ K ~' L. I, f- G0 T' U ================================= bxCAN ============================== 1、CAN波特率的设定计数 8 T6 {5 ^0 S4 f6 [ : i$ P2 F1 l3 l. Q) N- ] ================================ Etherne ============================== * X; k% C$ Z; q$ Y* U * L' q2 Q. A4 `) M3 q$ O 3 W5 ?+ Y+ Y$ B ================================== SPI =============================== ) @' I# j/ ]9 z. z 1、SPI外设的NSS引脚设置为通用IO口 7 s7 D# F0 e* ]% q A7 y' z; v 由于SPI外设的SPI_CR1寄存器中SSM置1时,NSS引脚可被被释放用于GPIO使用,因此无论是在SPI的主模式或是从模式下均可以将NSS引脚释放,由软件或硬件进行NSS管理; 操作流程: ' Z4 O1 Q( m$ P r& @5 | 1)、初始化SPI外设,设置NSS由软件管理: 5 ?# J" y9 ~6 @2 m2 R) c& c SPI_InitStructure.SPI_NSS= SPI_NSS_Soft; 2)、如果NSS引脚用于其他外设时,需要使能NSS输出: SPI_SSOutputCmd(SPIx, ENABLE); 2、SPI 单线传输 此模式下限制:只能用作输入或者输出,或者工作在半双工模式下。 . ?' Z' s% @0 o) [% [3 b 5 v/ ^) i* m- |6 d' C 0 Q! P7 u0 ^/ {4 {- H. ~ ================================== I2C =============================== 3 k0 W% k4 J$ q. p1 J2 h" t ================================= USART ============================== 8 Y, m! X/ P% b- l, L) ^ ============================ Device Signature ======================== , U& X0 p' m* F2 S6 v6 |! d 1、 STM32F10xxx系列MCU内部含有一个出厂被固化的96bit唯一识别ID,该ID可以用于芯片加密、设备识别等一类特殊应用。 $ @( t) L7 I: |! \' B8 f% U# m$ L# k 读取该ID的方法: u32 DevID[3]; DevID[0] = *(vu32*)(0x1ffff7e8); 7 F; v& A: w: S/ b DevID[1] = *(vu32*)(0x1ffff7ec); DevID[2] = *(vu32*)(0x1ffff7f0); / H. m" A4 ~6 _5 {' t/ p7 q' ~ 数组DevID[3]中即保存了MCU的ID。 9 v' O% U2 y( Y8 @ [% N- s' u& z9 T I 注:256K Flash或以上容量的STM32,仅“Z”版本才有,之前的“A”版本没有。 * P. l6 w1 ^8 | H$ b $ T7 G" n9 \, ]- t1 B: Q- O 2、 $ G$ M' S( N/ \9 Z ================================== I2C =============================== # D, m" p2 \. x) h7 ~+ M" Y . k, a+ J1 P0 `( Q/ T& x3 i1 n2 \ 0 U$ J. e8 e; B* K) k ================================= Flash ============================== # X5 A1 E7 {9 `; H0 `* f/ R/ y 1、STM32对内部Flash的保护措施 所有STM32的芯片都提供对Flash的保护,防止对Flash的非法访问 - 写保护和读保护。 1)、读保护即大家通常说的“加密”,是作用于整个Flash存储区域。一旦设置了Flash的读保护,内置的Flash存储区只能通过程序的正常执行才能读出,而不能通过下述任何一种方式读出: 1 W3 U, f) U3 h7 P1 V( C 通过调试器(JTAG或SWD); 从RAM中启动并执行的程序; 2)、写保护是以四页(1KB/页) Flash存储区为单位提供写保护,对被保护的页实施编程或擦除操作将不被执行,同时产生操作错误标志。 5 u L$ ?- C( i e, _! s 读与写设置的效果见下表: 读保护 写保护 对Flash的操作功能 有效 有效 CPU只能读,禁止调试和非法访问。 * r0 T4 V1 f. _3 `3 O5 L( K 有效 无效 CPU可以读写,禁止调试和非法访问,页0~3为写保护。 无效 有效 CPU可读,允许调试和非法访问。 ) ]: k- [1 ]! S" n: Y" [; c7 L 无效 无效 CPU可以读写,允许调试和非法访问。 1 _" ]$ a# ?( p. ^ 2、当Flash读保护生效时,CPU执行程序可以读受保护的Flash区,但存在两个例外情况: + l& {5 E N1 D3 u' ^. q7 U 1)、调试执行程序时; 2)、从RAM启动并执行程序时 / W4 o' l6 f; t9 C3 [: D ' @% K* Y: i! K8 q+ N: ^7 } STM32还提供了一个特别的保护,即对Flash存储区施加读保护后,即使没有启用写保护,Flash的第 0 ~ 3 页也将处于写保护状态,这是为了防止修改复位或中断向量而跳转到RAM区执行非法程序代码。 3、Flash保护相关函数 FLASH_Unlock(); //Flash解锁 FLASH_ReadOutProtection(DISABLE); //Flash读保护禁止 8 s! y! d z; u6 T8 a, t FLASH_ReadOutProtection(ENABLE); //Flash读保护允许 ' y2 k, m2 w9 M ================================== CRC =============================== 1、CRC计算公式 所有的STM32芯片都内置了一个硬件的CRC计算模块,可应用到通信程序中,这个CRC计算模块使用常见的、在以太网中使用的计算多项式: ; [' [$ Y) S- m2 ~. y6 Y X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2 + X + 1 写成16进制就是:0x04C11DB7 ) r' }8 Q$ o d% Q, p' y ; A& k1 j2 E9 v1 J0 N! Y 2、使用这个内置CRC模块操作步骤: 复位CRC模块(设置CRC_CR=0x01),这个操作把CRC计算的余数初始化为0xFFFFFFFF # y- K3 c& u' [9 b 把要计算的数据按每32位分割为一组数据字,并逐个地把这组数据字写入CRC_DR寄存器(既下图中的绿色框) 写完所有的数据字后,就可以从CRC_DR寄存器(既下图中的兰色框)读出计算的结果。 + S4 [% C) ^* T/ Z 注意:虽然读写操作都是针对CRC_DR寄存器,但实际上是访问的不同物理寄存器。 $ g4 [/ n. K- j+ W6 [ 3、C语言描述的这个计算模块算法。可放在通信的另一端,对通信的正确性进行验证: 0 z5 \" W3 q1 ^$ g- h
注意: ' I0 R8 p; g6 M7 I1 c 1)、上述算法中变量CRC,在每次循环结束包含了计算的余数,它始终是向左移位(既从最低位向最高位移动),溢出的数据位被丢弃。 2)、输入的数据始终是以32位为单位,如果原始数据少于32位,需要在低位补0,当然也可以高位补0。 / H9 v9 s% E" m; J" p 3)、假定输入的DWORD数组中每个分量是按小端存储。 4)、输入数据是按照最高位最先计算,最低位最后计算的顺序进行。 例如: : B- G% R8 D1 l2 c2 E 如果输入0x44434241,内存中按字节存放的顺序是:0x41, 0x42, 0x43, 0x44。计算的结果是:0xCF534AE1 如果输入0x41424344,内存中按字节存放的顺序是:0x44, 0x43, 0x42, 0x41。计算的结果是:0xABCF9A63 0 ^' Z: w- e- y: N ====================================================================== 1 M, J3 T+ Y! p/ H$ a 5 T- ~& _% v& K* o. g: o9 P 按照使用编译器 ====================================================================== 1 ~3 M3 N* [! _5 j9 E, q ================================== IAR =============================== ; a2 l) l0 k0 u/ p 1、IAR环境下如果链接工程文件,出现堆栈溢出错误,该如何处理? 6 X/ c3 m) p# [4 ~9 H ! s' b O6 ?: l2 H 打开链接文件lnkarm_flash.xcl或者是lnkarm_ram.xcl 1 u8 {1 u7 c# u$ K% c //************************************************************************* // Stack and heap segments. 2 P0 n: a3 b5 [ //************************************************************************* 1 J5 s) P& {9 P" m/ c -D_CSTACK_SIZE=400 <----------------------------------------修改这里 ! S+ G" a: m( u* u+ e$ U! c, h 注:该修改方式仅适合IAR for ARM 4.xx版本。 ' j v* b. D6 ~) ^ 2、IAR编译输出HEX格式的目标文件 - ^8 ^3 l! ~ J* b( S 1)、Options->C/C++ Compiler->Output->Generate debug information 选项前的钩去掉 2)、Options->Assembler->Output->Generate debug information 选项前的钩去掉 0 u2 J4 ?0 _' L" R! v, U6 C 3)、Options->Linker->Output->Output File->Override default 选项前的钩选上并把文件名的后缀改成.hex 1 ^! n" E$ n" J/ c& @% b' } 4)、Options->Linker->Output->Output File->Format->Other 选项前的钩选上并把Output格式改为intel-extended - D, k1 @' K# O7 Z) U# d8 V$ r 经过以上设置,在Rebuld All之后会在/Debug/Exe下生成.hex格式目标文件 , G) C+ o5 F4 _4 i; h 3、IAR编译输出BIN格式的目标文件 b; z2 i g( }, d" p+ L 1)、Options->C/C++ Compiler->Output->Generate debug information 选项前的钩去掉 2)、Options->Assembler->Output->Generate debug information 选项前的钩去掉 - y6 t8 m3 ^# f, f2 y7 Z 3)、Options->Linker->Output->Output File->Override default 选项前的钩选上并把文件名的后缀改成.bin 4)、Options->Linker->Output->Output File->Format->Other 选项前的钩选上并把Output格式改为row-binary 经过以上设置,在Rebuld All之后会在/Debug/Exe下生成.bin格式目标文件 ================================== MDK =============================== 1、在MDK代码编辑环境下不能使用Goto Definition(用于查找某个变量的类型及定义)、Goto Reference(用于查找某个函数申明的原型)功能? ' K: Y& k5 r0 W8 p' P 解决:打开Project->Target-Options->Output,将Browse Information复选框勾上。 ! `/ I* j. W6 z( t' T9 ? 2、当使用STM32固件库与RTX Kernel时,使用isr_evt_set(),事件无响应? % V1 }% i/ ~5 B5 O 1 p0 H+ b: b# ~2 ^ 解决:编辑STM32固件库的“stm32f10x_vector.s”文件: : p3 s2 a& \; U3 C ... - @4 }! M F# N% Q6 G IMPORT SVC_Handler ;name changed according to RTX usage 3 V a( e. C0 J8 E IMPORT DebugMonitor 7 Y& Z0 J0 f; {6 q" I0 s IMPORT PendSV_Handler ;修改加入 0 S2 a8 D) i; E+ i4 L% a IMPORT SysTick_Handler ;name changed according to RTX usage 8 d/ ?8 d1 i. r0 {7 e" S ... 0 o% \; w/ A' R" p- m DCD SVC_Handler 1 |. H. @# t' ?1 F7 h1 ? DCD DebugMonitor DCD 0 ; Reserved DCD PendSV_Handler ;修改加入 DCD SysTick_Handler |
实战经验 | 基于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库
微信公众号
手机版