本帖最后由 yangc9 于 2018-5-27 16:30 编辑 % }* \% _7 O* x& w # ~8 U: o; E1 |" b" v$ d STM32的bitband(位带)是个好东西.但是F0不支持.没关系,想办法给他模拟出来. 在F1中,可以这样使用IO口: __no_init vu32 PA[16] @ 0x42210180;7 I* O9 F, S. w m7 s __no_init vu32 PB[16] @ 0x42218180;+ {( s$ ~+ Z2 D1 Q) R0 e( U ....... #define LED1 PA[1]" l; w- k+ L n; O! u: k #define LED2 PB[2]0 T, }5 F4 N7 F. { ........ LED1 = 0; // 亮灯* V# s" j" k3 l8 ~) w" ], r2 K 8 l. Q/ s$ r$ } LED2 = 1; // 灭灯 ......../ @3 t. ]. v1 ]- D C: s$ k1 k 把以上代码复制到F0的工程中,运行.: ^- W$ v/ h4 l 不出所料,进HardFault了.因为此段地址是保留的. : r& v1 F: J' v7 o0 o6 h, @1 Z 进HardFault时R1~3,R12,LR,PC,xPSR自动压栈. 低地址& |, v. O' {0 N9 p7 U4 W R0 R1 R2: y) Z3 D! L5 z9 q R3. D0 H" y, l, Y% P, ]. F- U R12- y( Z& L/ T" `8 t' v2 b8 W LR PC xPSR# e1 k+ \8 ?( h+ T# z0 g: u, J8 @: C 高地址 PC的值为0x08000064,指向flash,里面的内容为0x6048,这是一条指令STR R0, [R1, #0x4]* F4 |! ^7 x+ J$ G! f9 H 知道了指令,就可以解读此条指令,并根据寄存器内容将指令转化为BRR和BSRR的动作.+ y) m3 N9 x3 W* k1 f F0的写外设的指令是STR:, d7 J9 i( y( R% Z0 p STR Rt, [Rn {,#imm}] STR Rt, [SP {,#imm}] // 此条不用考虑, SP不可能指向外设区3 H1 k, u! z B {/ e* K1 X STR Rt, [Rn, Rm]: m$ u* k% o2 O; z8 t/ ` c4 Z SP不可能指向外设区,不考虑PUSH指令 STMxx似乎也不用来操作外设区. 只需要解2种STR就可以了. 上代码:+ R& y, K3 Q' G 9 M9 P+ v! N4 ?* `5 a. o, _/ }5 } __task void HardFault_Handler(int uu1, int uu2, int uu3, int uu4, int R4, int R5, int R6, int R7, int HFLR, int R0, int R1, int R2, int R3,# D% g# E( a8 {; u% ~* R3 ] int R12, int LR, int16* volatile PC, int xPSR)! F3 K% u8 k& K" i& h: b' a { u, ^5 g/ Q& b6 B0 F. e asm ("PUSH {R3-R7}");% l/ d0 d/ r. F' E uint16_t ins = *PC;* O B3 A" Q: r" x int Rt, Addr; // STR Rt, [Rn {,#imm}] // imm <= 124 // 0x6000 | Rt | Rn << 3 | imm << 4& g! j$ E# C' M. k6 Q: y if ((ins & 0xF800) == 0x6000) { Rt = ins & 7;# Q8 [, {( z4 S! x! a int Rn = ins >> 3 & 7; int imm = ins >> 4 & 124; if (Rn <= 3) Addr = *(&R0 + Rn) + imm; else3 t$ c8 O0 ^. A `$ B( } Addr = *(&R4 + Rn - 4) + imm;+ N4 Z4 q+ ~& k$ A }2 \$ E7 f, @7 o: l8 a5 } else if ((ins & 0xFE00) == 0x5000) { Rt = ins & 7; int Rn = ins >> 3 & 7; int Rm = ins >> 6 & 7;/ Y5 b8 G+ {3 }* [" P, H if (Rn <= 3)/ C% a" k7 v, n$ Y0 ]& v( G; E Addr = *(&R0 + Rn); else Addr = *(&R4 + Rn - 4); if (Rm <= 3) Addr += *(&R0 + Rm);; X, H2 f8 I9 i" X$ d" g$ r else/ p% f) p0 S( j( c+ O6 w0 o" I Addr += *(&R4 + Rm - 4); }- d3 j; U/ U4 I if (Addr >= 0x42000000 && Addr < 0x44000000) {1 O0 h/ V) z8 S& S! K7 l5 _: e w int port = (Addr >> 15 & 7) - 2; int pin = Addr >> 2 & 15; int RtVal; O) [7 l# K1 u8 a1 ?, k* t) n if (Rt <= 3)/ G, S# ]0 B' b2 _3 j( {& y RtVal = *(&R0 + Rt); else RtVal = *(&R4 + Rt - 4); *(&GPIOA_BSRR + port * 0x100) = (RtVal & 1 | 0x10000) << pin;, P! ~9 h h8 j* T: P! p PC++;/ C0 H6 |* C& a f) p2 A } asm ("POP {R3-R7}"); }9 K3 ]3 p7 ?" C$ C7 o. r+ m" a# h. @ # Z* B4 L& G) V) Y6 Q6 Q& D; ] 更新:解决R4-R7的bug. 美女说: 回帖送金币哦! |
牛逼!!! |
还好同事不在! |
三创电子(Tcreate)-STM32F030核心板代码
STM32F0 ADC(DMA中断)多通道,注释超详细
FreeRTOS在STM32F030上的移植
STM32固件库分享,超全系列整理
基于STM32移植而引发的疑问经验分享
分享STM32F051中文参考手册(重制书签版)
游名:STM32F0+Trinamic智能步进驱动芯片TMC5160(最高20A)参考原...
【MCU实战经验】+STM32F030的步进电机加减速
STM32F0的中文技术参考手册(标签处理过)
基于STM32F030硬件SPI经验分享