|
本帖最后由 yangc9 于 2018-5-27 16:30 编辑 STM32的bitband(位带)是个好东西.但是F0不支持.没关系,想办法给他模拟出来. 在F1中,可以这样使用IO口: __no_init vu32 PA[16] @ 0x42210180; __no_init vu32 PB[16] @ 0x42218180; ....... #define LED1 PA[1] #define LED2 PB[2] ........ LED1 = 0; // 亮灯 LED2 = 1; // 灭灯 ........ 把以上代码复制到F0的工程中,运行. 不出所料,进HardFault了.因为此段地址是保留的. 进HardFault时R1~3,R12,LR,PC,xPSR自动压栈. 低地址 R0 R1 R2 R3 R12 LR PC xPSR 高地址 PC的值为0x08000064,指向flash,里面的内容为0x6048,这是一条指令STR R0, [R1, #0x4] 知道了指令,就可以解读此条指令,并根据寄存器内容将指令转化为BRR和BSRR的动作. F0的写外设的指令是STR: STR Rt, [Rn {,#imm}] STR Rt, [SP {,#imm}] // 此条不用考虑, SP不可能指向外设区 STR Rt, [Rn, Rm] SP不可能指向外设区,不考虑PUSH指令 STMxx似乎也不用来操作外设区. 只需要解2种STR就可以了. 上代码: __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, int R12, int LR, int16* volatile PC, int xPSR) { asm ("PUSH {R3-R7}"); uint16_t ins = *PC; int Rt, Addr; // STR Rt, [Rn {,#imm}] // imm <= 124 // 0x6000 | Rt | Rn << 3 | imm << 4 if ((ins & 0xF800) == 0x6000) { Rt = ins & 7; int Rn = ins >> 3 & 7; int imm = ins >> 4 & 124; if (Rn <= 3) Addr = *(&R0 + Rn) + imm; else Addr = *(&R4 + Rn - 4) + imm; } 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 Addr = *(&R4 + Rn - 4); if (Rm <= 3) Addr += *(&R0 + Rm); else Addr += *(&R4 + Rm - 4); } if (Addr >= 0x42000000 && Addr < 0x44000000) { int port = (Addr >> 15 & 7) - 2; int pin = Addr >> 2 & 15; int RtVal; if (Rt <= 3) RtVal = *(&R0 + Rt); else RtVal = *(&R4 + Rt - 4); *(&GPIOA_BSRR + port * 0x100) = (RtVal & 1 | 0x10000) << pin; PC++; } asm ("POP {R3-R7}"); } 更新:解决R4-R7的bug. 美女说: 回帖送金币哦!
|
牛逼!!!![]() ![]() |
![]() ![]() 传说中的片尾彩蛋 |
| 还好同事不在! |
STM32
超强工具——STM32CubeMX 你会用吗?
集结出发! STM32全国研讨会系列之一:ST智能门铃中国首秀
关于STM32启动文件的几个小问题
【银杏科技ARM+FPGA双核心应用】STM32H7系列35——USB_VCP_FS
【银杏科技ARM+FPGA双核心应用】STM32H7系列28——USB_HID
粉丝分享 | 图说CRC原理应用及STM32硬件CRC外设
STM32L151进入低功耗,并由RTC唤醒的故事
[转]stm32控制NFC模块(PN532)源码(P2P,模拟卡,读写卡等
STM32G070RB+LVGL移植
微信公众号
手机版