本帖最后由 yangc9 于 2018-5-27 16:30 编辑 8 u5 E7 }3 b6 Z7 [$ { STM32的bitband(位带)是个好东西.但是F0不支持.没关系,想办法给他模拟出来. 在F1中,可以这样使用IO口: __no_init vu32 PA[16] @ 0x42210180; __no_init vu32 PB[16] @ 0x42218180;2 A( ?7 d# s+ E .......' x9 m0 M$ i6 z( k6 y #define LED1 PA[1]- y0 S) m' q- A5 X- @& H #define LED2 PB[2], d+ P# u0 S' P5 u' T1 K ........2 s `/ b, H6 L LED1 = 0; // 亮灯9 _) f; q' d, m, { # A/ B, K6 [0 D LED2 = 1; // 灭灯4 L6 ^" V$ r# k2 Z s ........# ?8 k! u, V8 o: W2 B5 G 把以上代码复制到F0的工程中,运行. 不出所料,进HardFault了.因为此段地址是保留的.) j; L0 B9 w. b; H3 i* t" f k: H0 O% d/ Y ?6 h+ r3 Y5 o 进HardFault时R1~3,R12,LR,PC,xPSR自动压栈.$ `5 o& \5 B6 H a) Q 低地址 R0 R1 R22 I' z+ D3 v5 r! E9 [% X R3! @3 C3 c G6 M* H R12% f0 `: F9 ~8 b6 ? LR PC6 C$ Z' X: l3 N, e6 m xPSR 高地址 PC的值为0x08000064,指向flash,里面的内容为0x6048,这是一条指令STR R0, [R1, #0x4] q" E( ^! y" I- ]2 y 知道了指令,就可以解读此条指令,并根据寄存器内容将指令转化为BRR和BSRR的动作. F0的写外设的指令是STR: STR Rt, [Rn {,#imm}], ^2 T1 a: T4 g/ z: P+ _- I" z STR Rt, [SP {,#imm}] // 此条不用考虑, SP不可能指向外设区' H5 _0 n$ f. t STR Rt, [Rn, Rm] SP不可能指向外设区,不考虑PUSH指令 STMxx似乎也不用来操作外设区. 只需要解2种STR就可以了.( A! X3 I+ N! v) B' Q4 z( o 上代码:+ }, B( g$ v* P 4 [9 Y1 T3 L6 G. G __task void HardFault_Handler(int uu1, int uu2, int uu3, int uu4,+ F9 \: W- [) z: S0 D- L, `9 m# c int R4, int R5, int R6, int R7, int HFLR, int R0, int R1, int R2, int R3, int R12, int LR, int16* volatile PC, int xPSR)* \8 E" u( v3 o& P- N {8 G5 w- p' Z- M& } S5 t asm ("PUSH {R3-R7}"); uint16_t ins = *PC; int Rt, Addr; // STR Rt, [Rn {,#imm}] // imm <= 124( h3 d5 u p+ \7 { // 0x6000 | Rt | Rn << 3 | imm << 4 if ((ins & 0xF800) == 0x6000)9 g) a0 n5 C& Q* [* m { Rt = ins & 7;& p1 w, `+ H! ]2 T9 T int Rn = ins >> 3 & 7;! u# z2 q+ C/ j Z: F3 j int imm = ins >> 4 & 124; if (Rn <= 3) Addr = *(&R0 + Rn) + imm;/ t5 j; X+ u8 @7 j1 _ else: ], q: y' I, @ Addr = *(&R4 + Rn - 4) + imm;, S& n* n% X, D } else if ((ins & 0xFE00) == 0x5000) { Rt = ins & 7; int Rn = ins >> 3 & 7; int Rm = ins >> 6 & 7; if (Rn <= 3) Addr = *(&R0 + Rn); else$ h: i: s# L& n# [& x; `" }. q* R1 K l! P Addr = *(&R4 + Rn - 4);) `! z3 N) u) P1 o. S9 R if (Rm <= 3)" G8 y7 { y) v$ W% \# K. ~ Addr += *(&R0 + Rm); else Addr += *(&R4 + Rm - 4);3 R3 _/ Q/ @ ^ }% Z( d9 k& |8 C if (Addr >= 0x42000000 && Addr < 0x44000000) { int port = (Addr >> 15 & 7) - 2;! F2 i! F+ b" [2 e6 r# O4 _( \6 d int pin = Addr >> 2 & 15; int RtVal;7 P. B+ ?" D9 p2 P" } if (Rt <= 3) RtVal = *(&R0 + Rt);' _' {- b- ~/ P else$ \7 H; M9 l4 r! [! P RtVal = *(&R4 + Rt - 4);' T* ~$ M2 ]# v6 i *(&GPIOA_BSRR + port * 0x100) = (RtVal & 1 | 0x10000) << pin;5 W* R" Q/ h! h" i( x4 k* i PC++; } asm ("POP {R3-R7}"); } l( A$ s5 z) Z* \, O6 D4 P 更新:解决R4-R7的bug. 1 E0 h9 |5 l+ B3 j. ~$ y: P 美女说: 回帖送金币哦! |
牛逼!!! |
还好同事不在! |
STM32固件库分享,超全系列整理
三创电子(Tcreate)-STM32F030核心板代码
STM32F0 ADC(DMA中断)多通道,注释超详细
FreeRTOS在STM32F030上的移植
基于STM32移植而引发的疑问经验分享
分享STM32F051中文参考手册(重制书签版)
游名:STM32F0+Trinamic智能步进驱动芯片TMC5160(最高20A)参考原...
【MCU实战经验】+STM32F030的步进电机加减速
STM32F0的中文技术参考手册(标签处理过)
基于STM32F030硬件SPI经验分享