STM32F1 标准库源码阅读
CM3 内核文件 #
core_cm3.h #
1#ifndef __CM3_CORE_H__
2#define __CM3_CORE_H__
3
4#ifdef __cplusplus // 如果使用 C++ 编译器,使用 C 链接约定
5 extern "C" {
6#endif
7
8#define __CM3_CMSIS_VERSION_MAIN (0x01) // [31:16] CMSIS HAL 主版本号(Hardware Abstraction Layer)
9#define __CM3_CMSIS_VERSION_SUB (0x30) // [15:0] CMSIS HAL 子版本号
10#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) // CMSIS HAL 版本号
11
12#define __CORTEX_M (0x03) // Cortex 核心
13
14#include <stdint.h> // 包含标准整数类型
15
16#if defined (__ICCARM__)
17 #include <intrinsics.h> // IAR 内置函数
18#endif
19
20#ifndef __NVIC_PRIO_BITS
21 #define __NVIC_PRIO_BITS 4 // NVIC 优先级寄存器实际可用位,STM32F1 系列有 4 位(16级)
22#endif
23
24
25/****************************************************************************************************
26 * IO 定义: 对外设寄存器的访问限制
27 ***************************************************************************************************/
28
29#ifdef __cplusplus
30 #define __I volatile // 定义'只读'权限
31#else
32 #define __I volatile const // 定义'只读'权限
33#endif
34#define __O volatile // 定义'只写'权限
35#define __IO volatile // 定义'读/写'权限
36
37
38
39/****************************************************************************************************
40 * 寄存器抽象
41 ***************************************************************************************************/
42
43typedef struct // 嵌套向量中断控制器的内存映射结构 Nested Vectored Interrupt Controller (NVIC)
44{
45 __IO uint32_t ISER[8]; // 偏移: 0x000 中断设置使能寄存器 Interrupt Set Enable Register
46 uint32_t RESERVED0[24];
47 __IO uint32_t ICER[8]; // 偏移: 0x080 中断清除使能寄存器 Interrupt Clear Enable Register
48 uint32_t RSERVED1[24];
49 __IO uint32_t ISPR[8]; // 偏移: 0x100 中断设置挂起寄存器 Interrupt Set Pending Register
50 uint32_t RESERVED2[24];
51 __IO uint32_t ICPR[8]; // 偏移: 0x180 中断清除挂起寄存器 Interrupt Clear Pending Register
52 uint32_t RESERVED3[24];
53 __IO uint32_t IABR[8]; // 偏移: 0x200 中断活动位寄存器 Interrupt Active bit Register
54 uint32_t RESERVED4[56];
55 __IO uint8_t IP[240]; // 偏移: 0x300 中断优先级寄存器 Interrupt Priority Register (8Bit wide)
56 uint32_t RESERVED5[644];
57 __O uint32_t STIR; // 偏移: 0xE00 软件触发中断寄存器 Software Trigger Interrupt Register
58} NVIC_Type;
59
60typedef struct // 系统控制块的内存映射结构 System Control Block (SCB)
61{
62 __I uint32_t CPUID; // 偏移: 0x00 CPU ID 基地址寄存器 CPU ID Base Register
63 __IO uint32_t ICSR; // 偏移: 0x04 中断控制和状态寄存器 Interrupt Control State Register
64 __IO uint32_t VTOR; // 偏移: 0x08 向量表偏移寄存器 Vector Table Offset Register
65 __IO uint32_t AIRCR; // 偏移: 0x0C 应用中断/复位控制寄存器 Application Interrupt / Reset Control Register
66 __IO uint32_t SCR; // 偏移: 0x10 系统控制寄存器 System Control Register
67 __IO uint32_t CCR; // 偏移: 0x14 配置控制寄存器 Configuration Control Register
68 __IO uint8_t SHP[12]; // 偏移: 0x18 系统处理程序优先级寄存器 System Handlers Priority Registers (4-7, 8-11, 12-15)
69 __IO uint32_t SHCSR; // 偏移: 0x24 系统处理程序控制和状态寄存器 System Handler Control and State Register
70 __IO uint32_t CFSR; // 偏移: 0x28 可配置故障状态寄存器 Configurable Fault Status Register
71 __IO uint32_t HFSR; // 偏移: 0x2C 硬件故障状态寄存器 Hard Fault Status Register
72 __IO uint32_t DFSR; // 偏移: 0x30 调试故障状态寄存器 Debug Fault Status Register
73 __IO uint32_t MMFAR; // 偏移: 0x34 内存管理地址寄存器 Mem Manage Address Register
74 __IO uint32_t BFAR; // 偏移: 0x38 总线故障地址寄存器 Bus Fault Address Register
75 __IO uint32_t AFSR; // 偏移: 0x3C 辅助故障状态寄存器 Auxiliary Fault Status Register
76 __I uint32_t PFR[2]; // 偏移: 0x40 处理器特性寄存器 Processor Feature Register
77 __I uint32_t DFR; // 偏移: 0x48 调试特性寄存器 Debug Feature Register
78 __I uint32_t ADR; // 偏移: 0x4C 辅助特性寄存器 Auxiliary Feature Register
79 __I uint32_t MMFR[4]; // 偏移: 0x50 内存模型特性寄存器 Memory Model Feature Register
80 __I uint32_t ISAR[5]; // 偏移: 0x60 指令集架构特性寄存器 ISA Feature Register
81} SCB_Type;
82
83// SCB CPUID 寄存器定义
84#define SCB_CPUID_IMPLEMENTER_Pos 24 // 厂商 ID
85#define SCB_CPUID_IMPLEMENTER_Msk (0xFFul << SCB_CPUID_IMPLEMENTER_Pos)
86#define SCB_CPUID_VARIANT_Pos 20 // 主版本号
87#define SCB_CPUID_VARIANT_Msk (0xFul << SCB_CPUID_VARIANT_Pos)
88#define SCB_CPUID_PARTNO_Pos 4 // 部件号
89#define SCB_CPUID_PARTNO_Msk (0xFFFul << SCB_CPUID_PARTNO_Pos)
90#define SCB_CPUID_REVISION_Pos 0 // 修订号
91#define SCB_CPUID_REVISION_Msk (0xFul << SCB_CPUID_REVISION_Pos)
92
93// SCB 中断控制状态寄存器定义
94#define SCB_ICSR_NMIPENDSET_Pos 31 // NMI 挂起设置位
95#define SCB_ICSR_NMIPENDSET_Msk (1ul << SCB_ICSR_NMIPENDSET_Pos)
96#define SCB_ICSR_PENDSVSET_Pos 28 // PendSV 设置位
97#define SCB_ICSR_PENDSVSET_Msk (1ul << SCB_ICSR_PENDSVSET_Pos)
98#define SCB_ICSR_PENDSVCLR_Pos 27 // PendSV 清除位
99#define SCB_ICSR_PENDSVCLR_Msk (1ul << SCB_ICSR_PENDSVCLR_Pos)
100#define SCB_ICSR_PENDSTSET_Pos 26 // SysTick 挂起设置位
101#define SCB_ICSR_PENDSTSET_Msk (1ul << SCB_ICSR_PENDSTSET_Pos)
102#define SCB_ICSR_PENDSTCLR_Pos 25 // SysTick 挂起清除位
103#define SCB_ICSR_PENDSTCLR_Msk (1ul << SCB_ICSR_PENDSTCLR_Pos)
104#define SCB_ICSR_ISRPREEMPT_Pos 23 // ISR 抢占位
105#define SCB_ICSR_ISRPREEMPT_Msk (1ul << SCB_ICSR_ISRPREEMPT_Pos)
106#define SCB_ICSR_ISRPENDING_Pos 22 // 外部中断挂起位
107#define SCB_ICSR_ISRPENDING_Msk (1ul << SCB_ICSR_ISRPENDING_Pos)
108#define SCB_ICSR_VECTPENDING_Pos 12 // 当前挂起的中断异常编号
109#define SCB_ICSR_VECTPENDING_Msk (0x1FFul << SCB_ICSR_VECTPENDING_Pos)
110#define SCB_ICSR_RETTOBASE_Pos 11 // 返回到基址位
111#define SCB_ICSR_RETTOBASE_Msk (1ul << SCB_ICSR_RETTOBASE_Pos)
112#define SCB_ICSR_VECTACTIVE_Pos 0 // 当前中断异常编号
113#define SCB_ICSR_VECTACTIVE_Msk (0x1FFul << SCB_ICSR_VECTACTIVE_Pos)
114
115// SCB 向量表偏移寄存器定义
116#define SCB_VTOR_TBLBASE_Pos 29 // 向量表基地址位(0:代码区,1:RAM)
117#define SCB_VTOR_TBLBASE_Msk (0x1FFul << SCB_VTOR_TBLBASE_Pos)
118#define SCB_VTOR_TBLOFF_Pos 7 // 基地址偏移
119#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFul << SCB_VTOR_TBLOFF_Pos)
120
121// SCB 应用中断和复位控制寄存器定义
122#define SCB_AIRCR_VECTKEY_Pos 16 // 向量键,写入 AIRCR 寄存器时必须写入 0x5FA 到 VECTKEY
123#define SCB_AIRCR_VECTKEY_Msk (0xFFFFul << SCB_AIRCR_VECTKEY_Pos)
124#define SCB_AIRCR_VECTKEYSTAT_Pos 16 // 向量键状态
125#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFul << SCB_AIRCR_VECTKEYSTAT_Pos)
126#define SCB_AIRCR_ENDIANESS_Pos 15 // 字节大小端
127#define SCB_AIRCR_ENDIANESS_Msk (1ul << SCB_AIRCR_ENDIANESS_Pos)
128#define SCB_AIRCR_PRIGROUP_Pos 8 // 优先级分组
129#define SCB_AIRCR_PRIGROUP_Msk (7ul << SCB_AIRCR_PRIGROUP_Pos)
130#define SCB_AIRCR_SYSRESETREQ_Pos 2 // 系统复位请求位
131#define SCB_AIRCR_SYSRESETREQ_Msk (1ul << SCB_AIRCR_SYSRESETREQ_Pos)
132#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 // 清除活动向量位
133#define SCB_AIRCR_VECTCLRACTIVE_Msk (1ul << SCB_AIRCR_VECTCLRACTIVE_Pos)
134#define SCB_AIRCR_VECTRESET_Pos 0 // 向量复位位
135#define SCB_AIRCR_VECTRESET_Msk (1ul << SCB_AIRCR_VECTRESET_Pos)
136
137// SCB 系统控制寄存器定义
138#define SCB_SCR_SEVONPEND_Pos 4 // 挂起时发送事件位
139#define SCB_SCR_SEVONPEND_Msk (1ul << SCB_SCR_SEVONPEND_Pos)
140#define SCB_SCR_SLEEPDEEP_Pos 2 // 深度睡眠位
141#define SCB_SCR_SLEEPDEEP_Msk (1ul << SCB_SCR_SLEEPDEEP_Pos)
142#define SCB_SCR_SLEEPONEXIT_Pos 1 // 退出时睡眠位
143#define SCB_SCR_SLEEPONEXIT_Msk (1ul << SCB_SCR_SLEEPONEXIT_Pos)
144
145// SCB 配置控制寄存器定义
146#define SCB_CCR_STKALIGN_Pos 9 // 栈对齐位
147#define SCB_CCR_STKALIGN_Msk (1ul << SCB_CCR_STKALIGN_Pos)
148#define SCB_CCR_BFHFNMIGN_Pos 8 // 总线故障、硬件故障和 NMI 忽略位
149#define SCB_CCR_BFHFNMIGN_Msk (1ul << SCB_CCR_BFHFNMIGN_Pos)
150#define SCB_CCR_DIV_0_TRP_Pos 4 // 除零陷阱位
151#define SCB_CCR_DIV_0_TRP_Msk (1ul << SCB_CCR_DIV_0_TRP_Pos)
152#define SCB_CCR_UNALIGN_TRP_Pos 3 // 非对齐访问陷阱位
153#define SCB_CCR_UNALIGN_TRP_Msk (1ul << SCB_CCR_UNALIGN_TRP_Pos)
154#define SCB_CCR_USERSETMPEND_Pos 1 // 用户级设置挂起位
155#define SCB_CCR_USERSETMPEND_Msk (1ul << SCB_CCR_USERSETMPEND_Pos)
156#define SCB_CCR_NONBASETHRDENA_Pos 0 // 非基级线程使能位
157#define SCB_CCR_NONBASETHRDENA_Msk (1ul << SCB_CCR_NONBASETHRDENA_Pos)
158
159// SCB 系统处理程序控制和状态寄存器定义
160#define SCB_SHCSR_USGFAULTENA_Pos 18 // 用法故障使能位
161#define SCB_SHCSR_USGFAULTENA_Msk (1ul << SCB_SHCSR_USGFAULTENA_Pos)
162#define SCB_SHCSR_BUSFAULTENA_Pos 17 // 总线故障使能位
163#define SCB_SHCSR_BUSFAULTENA_Msk (1ul << SCB_SHCSR_BUSFAULTENA_Pos)
164#define SCB_SHCSR_MEMFAULTENA_Pos 16 // 内存故障使能位
165#define SCB_SHCSR_MEMFAULTENA_Msk (1ul << SCB_SHCSR_MEMFAULTENA_Pos)
166#define SCB_SHCSR_SVCALLPENDED_Pos 15 // SVC 调用挂起位
167#define SCB_SHCSR_SVCALLPENDED_Msk (1ul << SCB_SHCSR_SVCALLPENDED_Pos)
168#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 // 总线故障挂起位
169#define SCB_SHCSR_BUSFAULTPENDED_Msk (1ul << SCB_SHCSR_BUSFAULTPENDED_Pos)
170#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 // 内存故障挂起位
171#define SCB_SHCSR_MEMFAULTPENDED_Msk (1ul << SCB_SHCSR_MEMFAULTPENDED_Pos)
172#define SCB_SHCSR_USGFAULTPENDED_Pos 12 // 用法故障挂起位
173#define SCB_SHCSR_USGFAULTPENDED_Msk (1ul << SCB_SHCSR_USGFAULTPENDED_Pos)
174#define SCB_SHCSR_SYSTICKACT_Pos 11 // SysTick 活动位
175#define SCB_SHCSR_SYSTICKACT_Msk (1ul << SCB_SHCSR_SYSTICKACT_Pos)
176#define SCB_SHCSR_PENDSVACT_Pos 10 // PendSV 活动位
177#define SCB_SHCSR_PENDSVACT_Msk (1ul << SCB_SHCSR_PENDSVACT_Pos)
178#define SCB_SHCSR_MONITORACT_Pos 8 // 监控活动位
179#define SCB_SHCSR_MONITORACT_Msk (1ul << SCB_SHCSR_MONITORACT_Pos)
180#define SCB_SHCSR_SVCALLACT_Pos 7 // SVC 调用活动位
181#define SCB_SHCSR_SVCALLACT_Msk (1ul << SCB_SHCSR_SVCALLACT_Pos)
182#define SCB_SHCSR_USGFAULTACT_Pos 3 // 用法故障活动位
183#define SCB_SHCSR_USGFAULTACT_Msk (1ul << SCB_SHCSR_USGFAULTACT_Pos)
184#define SCB_SHCSR_BUSFAULTACT_Pos 1 // 总线故障活动位
185#define SCB_SHCSR_BUSFAULTACT_Msk (1ul << SCB_SHCSR_BUSFAULTACT_Pos)
186#define SCB_SHCSR_MEMFAULTACT_Pos 0 // 内存故障活动位
187#define SCB_SHCSR_MEMFAULTACT_Msk (1ul << SCB_SHCSR_MEMFAULTACT_Pos)
188
189// SCB 可配置故障状态寄存器定义
190#define SCB_CFSR_USGFAULTSR_Pos 16 // 用法故障状态寄存器
191#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFul << SCB_CFSR_USGFAULTSR_Pos)
192#define SCB_CFSR_BUSFAULTSR_Pos 8 // 总线故障状态寄存器
193#define SCB_CFSR_BUSFAULTSR_Msk (0xFFul << SCB_CFSR_BUSFAULTSR_Pos)
194#define SCB_CFSR_MEMFAULTSR_Pos 0 // 内存管理故障状态寄存器
195#define SCB_CFSR_MEMFAULTSR_Msk (0xFFul << SCB_CFSR_MEMFAULTSR_Pos)
196
197// SCB 硬件故障状态寄存器定义
198#define SCB_HFSR_DEBUGEVT_Pos 31 // 调试事件位
199#define SCB_HFSR_DEBUGEVT_Msk (1ul << SCB_HFSR_DEBUGEVT_Pos)
200#define SCB_HFSR_FORCED_Pos 30 // 强制故障位
201#define SCB_HFSR_FORCED_Msk (1ul << SCB_HFSR_FORCED_Pos)
202#define SCB_HFSR_VECTTBL_Pos 1 // 向量表故障位
203#define SCB_HFSR_VECTTBL_Msk (1ul << SCB_HFSR_VECTTBL_Pos)
204
205// SCB 调试故障状态寄存器定义
206#define SCB_DFSR_EXTERNAL_Pos 4 // 外部调试请求位
207#define SCB_DFSR_EXTERNAL_Msk (1ul << SCB_DFSR_EXTERNAL_Pos)
208#define SCB_DFSR_VCATCH_Pos 3 // 向量捕获位
209#define SCB_DFSR_VCATCH_Msk (1ul << SCB_DFSR_VCATCH_Pos)
210#define SCB_DFSR_DWTTRAP_Pos 2 // DWT 陷阱位
211#define SCB_DFSR_DWTTRAP_Msk (1ul << SCB_DFSR_DWTTRAP_Pos)
212#define SCB_DFSR_BKPT_Pos 1 // 断点位
213#define SCB_DFSR_BKPT_Msk (1ul << SCB_DFSR_BKPT_Pos)
214#define SCB_DFSR_HALTED_Pos 0 // 调试器暂停位
215#define SCB_DFSR_HALTED_Msk (1ul << SCB_DFSR_HALTED_Pos)
216
217/****************************************************************************************************
218 * SysTick 定时器的内存映射结构
219 ***************************************************************************************************/
220typedef struct
221{
222 __IO uint32_t CTRL; // SysTick 控制和状态寄存器 SysTick Control and Status Register
223 __IO uint32_t LOAD; // SysTick 重载值寄存器 SysTick Reload Value Register
224 __IO uint32_t VAL; // SysTick 当前值寄存器 SysTick Current Value Register
225 __I uint32_t CALIB; // SysTick 校准寄存器 SysTick Calibration Register
226} SysTick_Type;
227
228// SysTick 控制/状态寄存器定义
229#define SysTick_CTRL_COUNTFLAG_Pos 16 // 计数标志位
230#define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos)
231#define SysTick_CTRL_CLKSOURCE_Pos 2 // 时钟源选择位
232#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos)
233#define SysTick_CTRL_TICKINT_Pos 1 // 中断使能位
234#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos)
235#define SysTick_CTRL_ENABLE_Pos 0 // 使能位
236#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos)
237
238// SysTick 重载寄存器定义
239#define SysTick_LOAD_RELOAD_Pos 0 // 重载值
240#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)
241
242// SysTick 当前值寄存器定义
243#define SysTick_VAL_CURRENT_Pos 0 // 当前值
244#define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)
245
246// SysTick 校准寄存器定义
247#define SysTick_CALIB_NOREF_Pos 31 // 无参考时钟位
248#define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos)
249#define SysTick_CALIB_SKEW_Pos 30 // 校准值偏斜位
250#define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos)
251#define SysTick_CALIB_TENMS_Pos 0 // 10ms 校准值
252#define SysTick_CALIB_TENMS_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)
253
254/****************************************************************************************************
255 * 仪器化跟踪宏单元 (ITM) 的内存映射结构(用途:调试和跟踪)
256 ***************************************************************************************************/
257typedef struct
258{
259 __O union
260 {
261 __O uint8_t u8;
262 __O uint16_t u16;
263 __O uint32_t u32;
264 } PORT [32];
265 uint32_t RESERVED0[864];
266 __IO uint32_t TER;
267 uint32_t RESERVED1[15];
268 __IO uint32_t TPR;
269 uint32_t RESERVED2[15];
270 __IO uint32_t TCR;
271 uint32_t RESERVED3[29];
272 __IO uint32_t IWR;
273 __IO uint32_t IRR;
274 __IO uint32_t IMCR;
275 uint32_t RESERVED4[43];
276 __IO uint32_t LAR;
277 __IO uint32_t LSR;
278 uint32_t RESERVED5[6];
279 __I uint32_t PID4;
280 __I uint32_t PID5;
281 __I uint32_t PID6;
282 __I uint32_t PID7;
283 __I uint32_t PID0;
284 __I uint32_t PID1;
285 __I uint32_t PID2;
286 __I uint32_t PID3;
287 __I uint32_t CID0;
288 __I uint32_t CID1;
289 __I uint32_t CID2;
290 __I uint32_t CID3;
291} ITM_Type;
292
293// 跟踪特权寄存器定义
294#define ITM_TPR_PRIVMASK_Pos 0
295#define ITM_TPR_PRIVMASK_Msk (0xFul << ITM_TPR_PRIVMASK_Pos)
296
297// 跟踪控制寄存器定义
298#define ITM_TCR_BUSY_Pos 23
299#define ITM_TCR_BUSY_Msk (1ul << ITM_TCR_BUSY_Pos)
300#define ITM_TCR_ATBID_Pos 16
301#define ITM_TCR_ATBID_Msk (0x7Ful << ITM_TCR_ATBID_Pos)
302#define ITM_TCR_TSPrescale_Pos 8
303#define ITM_TCR_TSPrescale_Msk (3ul << ITM_TCR_TSPrescale_Pos)
304#define ITM_TCR_SWOENA_Pos 4
305#define ITM_TCR_SWOENA_Msk (1ul << ITM_TCR_SWOENA_Pos)
306#define ITM_TCR_DWTENA_Pos 3
307#define ITM_TCR_DWTENA_Msk (1ul << ITM_TCR_DWTENA_Pos)
308#define ITM_TCR_SYNCENA_Pos 2
309#define ITM_TCR_SYNCENA_Msk (1ul << ITM_TCR_SYNCENA_Pos)
310#define ITM_TCR_TSENA_Pos 1
311#define ITM_TCR_TSENA_Msk (1ul << ITM_TCR_TSENA_Pos)
312#define ITM_TCR_ITMENA_Pos 0
313#define ITM_TCR_ITMENA_Msk (1ul << ITM_TCR_ITMENA_Pos)
314
315// 集成写寄存器定义
316#define ITM_IWR_ATVALIDM_Pos 0
317#define ITM_IWR_ATVALIDM_Msk (1ul << ITM_IWR_ATVALIDM_Pos)
318
319// 集成读寄存器定义
320#define ITM_IRR_ATREADYM_Pos 0
321#define ITM_IRR_ATREADYM_Msk (1ul << ITM_IRR_ATREADYM_Pos)
322
323// 集成模式控制寄存器定义
324#define ITM_IMCR_INTEGRATION_Pos 0
325#define ITM_IMCR_INTEGRATION_Msk (1ul << ITM_IMCR_INTEGRATION_Pos)
326
327// 锁状态寄存器定义
328#define ITM_LSR_ByteAcc_Pos 2
329#define ITM_LSR_ByteAcc_Msk (1ul << ITM_LSR_ByteAcc_Pos)
330#define ITM_LSR_Access_Pos 1
331#define ITM_LSR_Access_Msk (1ul << ITM_LSR_Access_Pos)
332#define ITM_LSR_Present_Pos 0
333#define ITM_LSR_Present_Msk (1ul << ITM_LSR_Present_Pos)
334
335/****************************************************************************************************
336 * 中断类型的的内存映射结构: memory mapped structure for Interrupt Type
337 ***************************************************************************************************/
338typedef struct
339{
340 uint32_t RESERVED0;
341 __I uint32_t ICTR; // 中断控制类型寄存器 Interrupt Control Type Register
342#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
343 __IO uint32_t ACTLR; // 辅助控制寄存器 Auxiliary Control Register
344#else
345 uint32_t RESERVED1;
346#endif
347} InterruptType_Type;
348
349// 中断控制器类型寄存器定义
350#define InterruptType_ICTR_INTLINESNUM_Pos 0 // 中断线数量
351#define InterruptType_ICTR_INTLINESNUM_Msk (0x1Ful << InterruptType_ICTR_INTLINESNUM_Pos)
352
353// 辅助控制寄存器定义
354#define InterruptType_ACTLR_DISFOLD_Pos 2 // 禁止重叠位
355#define InterruptType_ACTLR_DISFOLD_Msk (1ul << InterruptType_ACTLR_DISFOLD_Pos)
356#define InterruptType_ACTLR_DISDEFWBUF_Pos 1 // 禁止默认写缓冲区位
357#define InterruptType_ACTLR_DISDEFWBUF_Msk (1ul << InterruptType_ACTLR_DISDEFWBUF_Pos)
358#define InterruptType_ACTLR_DISMCYCINT_Pos 0 // 禁止多周期中断位
359#define InterruptType_ACTLR_DISMCYCINT_Msk (1ul << InterruptType_ACTLR_DISMCYCINT_Pos)
360
361
362// __MPU_PRESENT 在 stm32f10x.h 中定义
363#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
364/****************************************************************************************************
365 * 内存保护单元 (MPU) 的内存映射结构
366 ***************************************************************************************************/
367typedef struct
368{
369 __I uint32_t TYPE; // 偏移: 0x00 类型寄存器 MPU Type Register
370 __IO uint32_t CTRL; // 偏移: 0x04 控制寄存器 MPU Control Register
371 __IO uint32_t RNR; // 偏移: 0x08 区域编号寄存器 MPU Region RNRber Register
372 __IO uint32_t RBAR; // 偏移: 0x0C 区域基地址寄存器 MPU Region Base Address Register
373 __IO uint32_t RASR; // 偏移: 0x10 区域属性和大小寄存器 MPU Region Attribute and Size Register
374 __IO uint32_t RBAR_A1; // 偏移: 0x14 别名1区域基地址寄存器 MPU Alias 1 Region Base Address Register
375 __IO uint32_t RASR_A1; // 偏移: 0x18 别名1区域属性和大小寄存器 MPU Alias 1 Region Attribute and Size Register
376 __IO uint32_t RBAR_A2; // 偏移: 0x1C 别名2区域基地址寄存器 MPU Alias 2 Region Base Address Register
377 __IO uint32_t RASR_A2; // 偏移: 0x20 别名2区域属性和大小寄存器 MPU Alias 2 Region Attribute and Size Register
378 __IO uint32_t RBAR_A3; // 偏移: 0x24 别名3区域基地址寄存器 MPU Alias 3 Region Base Address Register
379 __IO uint32_t RASR_A3; // 偏移: 0x28 别名3区域属性和大小寄存器 MPU Alias 3 Region Attribute and Size Register
380} MPU_Type;
381
382// MPU Type Register
383#define MPU_TYPE_IREGION_Pos 16 // IREGION Position
384#define MPU_TYPE_IREGION_Msk (0xFFul << MPU_TYPE_IREGION_Pos)
385#define MPU_TYPE_DREGION_Pos 8 // DREGION Position
386#define MPU_TYPE_DREGION_Msk (0xFFul << MPU_TYPE_DREGION_Pos)
387#define MPU_TYPE_SEPARATE_Pos 0 // SEPARATE Position
388#define MPU_TYPE_SEPARATE_Msk (1ul << MPU_TYPE_SEPARATE_Pos)
389
390// MPU Control Register
391#define MPU_CTRL_PRIVDEFENA_Pos 2 // PRIVDEFENA Position
392#define MPU_CTRL_PRIVDEFENA_Msk (1ul << MPU_CTRL_PRIVDEFENA_Pos)
393#define MPU_CTRL_HFNMIENA_Pos 1 // HFNMIENA Position
394#define MPU_CTRL_HFNMIENA_Msk (1ul << MPU_CTRL_HFNMIENA_Pos)
395#define MPU_CTRL_ENABLE_Pos 0 // ENABLE Position
396#define MPU_CTRL_ENABLE_Msk (1ul << MPU_CTRL_ENABLE_Pos)
397
398// MPU Region Number Register
399#define MPU_RNR_REGION_Pos 0 // REGION Position
400#define MPU_RNR_REGION_Msk (0xFFul << MPU_RNR_REGION_Pos)
401
402// MPU Region Base Address Register
403#define MPU_RBAR_ADDR_Pos 5 // ADDR Position
404#define MPU_RBAR_ADDR_Msk (0x7FFFFFFul << MPU_RBAR_ADDR_Pos)
405#define MPU_RBAR_VALID_Pos 4 // VALID Position
406#define MPU_RBAR_VALID_Msk (1ul << MPU_RBAR_VALID_Pos)
407#define MPU_RBAR_REGION_Pos 0 // REGION Position
408#define MPU_RBAR_REGION_Msk (0xFul << MPU_RBAR_REGION_Pos)
409
410// MPU Region Attribute and Size Register
411#define MPU_RASR_XN_Pos 28 // XN Position
412#define MPU_RASR_XN_Msk (1ul << MPU_RASR_XN_Pos)
413#define MPU_RASR_AP_Pos 24 // AP Position
414#define MPU_RASR_AP_Msk (7ul << MPU_RASR_AP_Pos)
415#define MPU_RASR_TEX_Pos 19 // TEX Position
416#define MPU_RASR_TEX_Msk (7ul << MPU_RASR_TEX_Pos)
417#define MPU_RASR_S_Pos 18 // Shareable bit Position
418#define MPU_RASR_S_Msk (1ul << MPU_RASR_S_Pos)
419#define MPU_RASR_C_Pos 17 // Cacheable bit Position
420#define MPU_RASR_C_Msk (1ul << MPU_RASR_C_Pos)
421#define MPU_RASR_B_Pos 16 // Bufferable bit Position
422#define MPU_RASR_B_Msk (1ul << MPU_RASR_B_Pos)
423#define MPU_RASR_SRD_Pos 8 // Sub-Region Disable Position
424#define MPU_RASR_SRD_Msk (0xFFul << MPU_RASR_SRD_Pos)
425#define MPU_RASR_SIZE_Pos 1 // Region Size Field Position
426#define MPU_RASR_SIZE_Msk (0x1Ful << MPU_RASR_SIZE_Pos)
427#define MPU_RASR_ENA_Pos 0 // Region enable bit Position
428#define MPU_RASR_ENA_Msk (0x1Ful << MPU_RASR_ENA_Pos)
429
430#endif
431
432
433/****************************************************************************************************
434 * 核心调试寄存器的内存映射结构
435 ***************************************************************************************************/
436typedef struct
437{
438 __IO uint32_t DHCSR; // Offset: 0x00 Debug Halting Control and Status Register
439 __O uint32_t DCRSR; // Offset: 0x04 Debug Core Register Selector Register
440 __IO uint32_t DCRDR; // Offset: 0x08 Debug Core Register Data Register
441 __IO uint32_t DEMCR; // Offset: 0x0C Debug Exception and Monitor Control Register
442} CoreDebug_Type;
443
444// Debug Halting Control and Status Register
445#define CoreDebug_DHCSR_DBGKEY_Pos 16 // CoreDebug DHCSR: DBGKEY Position
446#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFul << CoreDebug_DHCSR_DBGKEY_Pos) // CoreDebug DHCSR: DBGKEY Mask
447#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 // CoreDebug DHCSR: S_RESET_ST Position
448#define CoreDebug_DHCSR_S_RESET_ST_Msk (1ul << CoreDebug_DHCSR_S_RESET_ST_Pos) // CoreDebug DHCSR: S_RESET_ST Mask
449#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 // CoreDebug DHCSR: S_RETIRE_ST Position
450#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1ul << CoreDebug_DHCSR_S_RETIRE_ST_Pos) // CoreDebug DHCSR: S_RETIRE_ST Mask
451#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 // CoreDebug DHCSR: S_LOCKUP Position
452#define CoreDebug_DHCSR_S_LOCKUP_Msk (1ul << CoreDebug_DHCSR_S_LOCKUP_Pos) // CoreDebug DHCSR: S_LOCKUP Mask
453#define CoreDebug_DHCSR_S_SLEEP_Pos 18 // CoreDebug DHCSR: S_SLEEP Position
454#define CoreDebug_DHCSR_S_SLEEP_Msk (1ul << CoreDebug_DHCSR_S_SLEEP_Pos) // CoreDebug DHCSR: S_SLEEP Mask
455#define CoreDebug_DHCSR_S_HALT_Pos 17 // CoreDebug DHCSR: S_HALT Position
456#define CoreDebug_DHCSR_S_HALT_Msk (1ul << CoreDebug_DHCSR_S_HALT_Pos) // CoreDebug DHCSR: S_HALT Mask
457#define CoreDebug_DHCSR_S_REGRDY_Pos 16 // CoreDebug DHCSR: S_REGRDY Position
458#define CoreDebug_DHCSR_S_REGRDY_Msk (1ul << CoreDebug_DHCSR_S_REGRDY_Pos) // CoreDebug DHCSR: S_REGRDY Mask
459#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 // CoreDebug DHCSR: C_SNAPSTALL Position
460#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1ul << CoreDebug_DHCSR_C_SNAPSTALL_Pos) // CoreDebug DHCSR: C_SNAPSTALL Mask
461#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 // CoreDebug DHCSR: C_MASKINTS Position
462#define CoreDebug_DHCSR_C_MASKINTS_Msk (1ul << CoreDebug_DHCSR_C_MASKINTS_Pos) // CoreDebug DHCSR: C_MASKINTS Mask
463#define CoreDebug_DHCSR_C_STEP_Pos 2 // CoreDebug DHCSR: C_STEP Position
464#define CoreDebug_DHCSR_C_STEP_Msk (1ul << CoreDebug_DHCSR_C_STEP_Pos) // CoreDebug DHCSR: C_STEP Mask
465#define CoreDebug_DHCSR_C_HALT_Pos 1 // CoreDebug DHCSR: C_HALT Position
466#define CoreDebug_DHCSR_C_HALT_Msk (1ul << CoreDebug_DHCSR_C_HALT_Pos) // CoreDebug DHCSR: C_HALT Mask
467#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 // CoreDebug DHCSR: C_DEBUGEN Position
468#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1ul << CoreDebug_DHCSR_C_DEBUGEN_Pos) // CoreDebug DHCSR: C_DEBUGEN Mask
469
470// Debug Core Register Selector Register
471#define CoreDebug_DCRSR_REGWnR_Pos 16 // CoreDebug DCRSR: REGWnR Position
472#define CoreDebug_DCRSR_REGWnR_Msk (1ul << CoreDebug_DCRSR_REGWnR_Pos) // CoreDebug DCRSR: REGWnR Mask
473#define CoreDebug_DCRSR_REGSEL_Pos 0 // CoreDebug DCRSR: REGSEL Position
474#define CoreDebug_DCRSR_REGSEL_Msk (0x1Ful << CoreDebug_DCRSR_REGSEL_Pos) // CoreDebug DCRSR: REGSEL Mask
475
476// Debug Exception and Monitor Control Register
477#define CoreDebug_DEMCR_TRCENA_Pos 24 // CoreDebug DEMCR: TRCENA Position
478#define CoreDebug_DEMCR_TRCENA_Msk (1ul << CoreDebug_DEMCR_TRCENA_Pos) // CoreDebug DEMCR: TRCENA Mask
479#define CoreDebug_DEMCR_MON_REQ_Pos 19 // CoreDebug DEMCR: MON_REQ Position
480#define CoreDebug_DEMCR_MON_REQ_Msk (1ul << CoreDebug_DEMCR_MON_REQ_Pos) // CoreDebug DEMCR: MON_REQ Mask
481#define CoreDebug_DEMCR_MON_STEP_Pos 18 // CoreDebug DEMCR: MON_STEP Position
482#define CoreDebug_DEMCR_MON_STEP_Msk (1ul << CoreDebug_DEMCR_MON_STEP_Pos) // CoreDebug DEMCR: MON_STEP Mask
483#define CoreDebug_DEMCR_MON_PEND_Pos 17 // CoreDebug DEMCR: MON_PEND Position
484#define CoreDebug_DEMCR_MON_PEND_Msk (1ul << CoreDebug_DEMCR_MON_PEND_Pos) // CoreDebug DEMCR: MON_PEND Mask
485#define CoreDebug_DEMCR_MON_EN_Pos 16 // CoreDebug DEMCR: MON_EN Position
486#define CoreDebug_DEMCR_MON_EN_Msk (1ul << CoreDebug_DEMCR_MON_EN_Pos) // CoreDebug DEMCR: MON_EN Mask
487#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 // CoreDebug DEMCR: VC_HARDERR Position
488#define CoreDebug_DEMCR_VC_HARDERR_Msk (1ul << CoreDebug_DEMCR_VC_HARDERR_Pos) // CoreDebug DEMCR: VC_HARDERR Mask
489#define CoreDebug_DEMCR_VC_INTERR_Pos 9 // CoreDebug DEMCR: VC_INTERR Position
490#define CoreDebug_DEMCR_VC_INTERR_Msk (1ul << CoreDebug_DEMCR_VC_INTERR_Pos) // CoreDebug DEMCR: VC_INTERR Mask
491#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 // CoreDebug DEMCR: VC_BUSERR Position
492#define CoreDebug_DEMCR_VC_BUSERR_Msk (1ul << CoreDebug_DEMCR_VC_BUSERR_Pos) // CoreDebug DEMCR: VC_BUSERR Mask
493#define CoreDebug_DEMCR_VC_STATERR_Pos 7 // CoreDebug DEMCR: VC_STATERR Position
494#define CoreDebug_DEMCR_VC_STATERR_Msk (1ul << CoreDebug_DEMCR_VC_STATERR_Pos) // CoreDebug DEMCR: VC_STATERR Mask
495#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 // CoreDebug DEMCR: VC_CHKERR Position
496#define CoreDebug_DEMCR_VC_CHKERR_Msk (1ul << CoreDebug_DEMCR_VC_CHKERR_Pos) // CoreDebug DEMCR: VC_CHKERR Mask
497#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 // CoreDebug DEMCR: VC_NOCPERR Position
498#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1ul << CoreDebug_DEMCR_VC_NOCPERR_Pos) // CoreDebug DEMCR: VC_NOCPERR Mask
499#define CoreDebug_DEMCR_VC_MMERR_Pos 4 // CoreDebug DEMCR: VC_MMERR Position
500#define CoreDebug_DEMCR_VC_MMERR_Msk (1ul << CoreDebug_DEMCR_VC_MMERR_Pos) // CoreDebug DEMCR: VC_MMERR Mask
501#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 // CoreDebug DEMCR: VC_CORERESET Position
502#define CoreDebug_DEMCR_VC_CORERESET_Msk (1ul << CoreDebug_DEMCR_VC_CORERESET_Pos) // CoreDebug DEMCR: VC_CORERESET Mask
503
504
505/****************************************************************************************************
506 * Cortex-M3 硬件的内存映射
507 ***************************************************************************************************/
508#define SCS_BASE (0xE000E000) // System Control Space Base Address
509#define ITM_BASE (0xE0000000) // ITM Base Address
510#define CoreDebug_BASE (0xE000EDF0) // Core Debug Base Address
511#define SysTick_BASE (SCS_BASE + 0x0010) // SysTick Base Address
512#define NVIC_BASE (SCS_BASE + 0x0100) // NVIC Base Address
513#define SCB_BASE (SCS_BASE + 0x0D00) // System Control Block Base Address
514
515#define InterruptType ((InterruptType_Type *) SCS_BASE) // Interrupt Type Register
516#define SCB ((SCB_Type *) SCB_BASE) // SCB configuration struct
517#define SysTick ((SysTick_Type *) SysTick_BASE) // SysTick configuration struct
518#define NVIC ((NVIC_Type *) NVIC_BASE) // NVIC configuration struct
519#define ITM ((ITM_Type *) ITM_BASE) // ITM configuration struct
520#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) // Core Debug configuration struct
521
522#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
523 #define MPU_BASE (SCS_BASE + 0x0D90) // Memory Protection Unit
524 #define MPU ((MPU_Type*) MPU_BASE) // Memory Protection Unit
525#endif
526
527
528/****************************************************************************************************
529 * 硬件抽象层
530 ***************************************************************************************************/
531#if defined ( __CC_ARM )
532 #define __ASM __asm // asm keyword for ARM Compiler
533 #define __INLINE __inline // inline keyword for ARM Compiler
534
535#elif defined ( __ICCARM__ )
536 #define __ASM __asm // asm keyword for IAR Compiler
537 #define __INLINE inline // inline keyword for IAR Compiler. Only avaiable in High optimization mode!
538
539#elif defined ( __GNUC__ )
540 #define __ASM __asm // asm keyword for GNU Compiler
541 #define __INLINE inline // inline keyword for GNU Compiler
542
543#elif defined ( __TASKING__ )
544 #define __ASM __asm // asm keyword for TASKING Compiler
545 #define __INLINE inline // inline keyword for TASKING Compiler
546
547#endif
548
549
550/****************************************************************************************************
551 * 编译器特定的内置函数
552 ***************************************************************************************************/
553#if defined ( __CC_ARM ) // RealView Compiler
554
555// ARM armcc specific functions
556#define __enable_fault_irq __enable_fiq
557#define __disable_fault_irq __disable_fiq
558
559#define __NOP __nop
560#define __WFI __wfi
561#define __WFE __wfe
562#define __SEV __sev
563#define __ISB() __isb(0)
564#define __DSB() __dsb(0)
565#define __DMB() __dmb(0)
566#define __REV __rev
567#define __RBIT __rbit
568#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr))
569#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr))
570#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr))
571#define __STREXB(value, ptr) __strex(value, ptr)
572#define __STREXH(value, ptr) __strex(value, ptr)
573#define __STREXW(value, ptr) __strex(value, ptr)
574
575extern uint32_t __get_PSP(void); // 返回进程栈指针
576extern void __set_PSP(uint32_t topOfProcStack);A // 设置进程栈指针
577extern uint32_t __get_MSP(void); // 返回主栈指针
578extern void __set_MSP(uint32_t topOfMainStack); // 设置主栈指针
579extern uint32_t __REV16(uint16_t value); // 反转半字中的字节
580extern int32_t __REVSH(int16_t value); // 反转低半字中的字节,并将结果有符号展开
581
582#if (__ARMCC_VERSION < 400000)
583
584extern void __CLREX(void);
585extern uint32_t __get_BASEPRI(void);
586extern void __set_BASEPRI(uint32_t basePri);
587extern uint32_t __get_PRIMASK(void);
588extern void __set_PRIMASK(uint32_t priMask);
589extern uint32_t __get_FAULTMASK(void);
590extern void __set_FAULTMASK(uint32_t faultMask);
591extern uint32_t __get_CONTROL(void);
592extern void __set_CONTROL(uint32_t control);
593
594#else
595
596#define __CLREX __clrex
597
598static __INLINE uint32_t __get_BASEPRI(void)
599{
600 register uint32_t __regBasePri __ASM("basepri");
601 return(__regBasePri);
602}
603
604static __INLINE void __set_BASEPRI(uint32_t basePri)
605{
606 register uint32_t __regBasePri __ASM("basepri");
607 __regBasePri = (basePri & 0xff);
608}
609
610static __INLINE uint32_t __get_PRIMASK(void)
611{
612 register uint32_t __regPriMask __ASM("primask");
613 return(__regPriMask);
614}
615
616static __INLINE void __set_PRIMASK(uint32_t priMask)
617{
618 register uint32_t __regPriMask __ASM("primask");
619 __regPriMask = (priMask);
620}
621
622static __INLINE uint32_t __get_FAULTMASK(void)
623{
624 register uint32_t __regFaultMask __ASM("faultmask");
625 return(__regFaultMask);
626}
627
628static __INLINE void __set_FAULTMASK(uint32_t faultMask)
629{
630 register uint32_t __regFaultMask __ASM("faultmask");
631 __regFaultMask = (faultMask & 1);
632}
633
634static __INLINE uint32_t __get_CONTROL(void)
635{
636 register uint32_t __regControl __ASM("control");
637 return(__regControl);
638}
639
640static __INLINE void __set_CONTROL(uint32_t control)
641{
642 register uint32_t __regControl __ASM("control");
643 __regControl = control;
644}
645
646#endif
647
648// ICC Compiler
649#elif (defined (__ICCARM__))
650
651#define __enable_irq __enable_interrupt
652#define __disable_irq __disable_interrupt
653
654static __INLINE void __enable_fault_irq() { __ASM ("cpsie f"); }
655static __INLINE void __disable_fault_irq() { __ASM ("cpsid f"); }
656
657#define __NOP __no_operation
658static __INLINE void __WFI() { __ASM ("wfi"); }
659static __INLINE void __WFE() { __ASM ("wfe"); }
660static __INLINE void __SEV() { __ASM ("sev"); }
661static __INLINE void __CLREX() { __ASM ("clrex"); }
662
663extern uint32_t __get_PSP(void);
664extern void __set_PSP(uint32_t topOfProcStack);
665extern uint32_t __get_MSP(void);
666extern void __set_MSP(uint32_t topOfMainStack);
667extern uint32_t __REV16(uint16_t value);
668extern uint32_t __RBIT(uint32_t value);
669extern uint8_t __LDREXB(uint8_t *addr);
670extern uint16_t __LDREXH(uint16_t *addr);
671extern uint32_t __LDREXW(uint32_t *addr);
672extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
673extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
674extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
675
676
677// GNU Compiler
678#elif (defined (__GNUC__))
679
680static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); }
681static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); }
682
683static __INLINE void __enable_fault_irq() { __ASM volatile ("cpsie f"); }
684static __INLINE void __disable_fault_irq() { __ASM volatile ("cpsid f"); }
685
686static __INLINE void __NOP() { __ASM volatile ("nop"); }
687static __INLINE void __WFI() { __ASM volatile ("wfi"); }
688static __INLINE void __WFE() { __ASM volatile ("wfe"); }
689static __INLINE void __SEV() { __ASM volatile ("sev"); }
690static __INLINE void __ISB() { __ASM volatile ("isb"); }
691static __INLINE void __DSB() { __ASM volatile ("dsb"); }
692static __INLINE void __DMB() { __ASM volatile ("dmb"); }
693static __INLINE void __CLREX() { __ASM volatile ("clrex"); }
694
695extern uint32_t __get_PSP(void);
696extern void __set_PSP(uint32_t topOfProcStack);
697extern uint32_t __get_MSP(void);
698extern void __set_MSP(uint32_t topOfMainStack);
699extern uint32_t __get_BASEPRI(void);
700extern void __set_BASEPRI(uint32_t basePri);
701extern uint32_t __get_PRIMASK(void);
702extern void __set_PRIMASK(uint32_t priMask);
703extern uint32_t __get_FAULTMASK(void);
704extern void __set_FAULTMASK(uint32_t faultMask);
705extern uint32_t __get_CONTROL(void);
706extern void __set_CONTROL(uint32_t control);
707extern uint32_t __REV(uint32_t value);
708extern uint32_t __REV16(uint16_t value);
709extern int32_t __REVSH(int16_t value);
710extern uint32_t __RBIT(uint32_t value);
711extern uint8_t __LDREXB(uint8_t *addr);
712extern uint16_t __LDREXH(uint16_t *addr);
713extern uint32_t __LDREXW(uint32_t *addr);
714extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
715extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
716extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
717
718
719// TASKING Compiler
720#elif (defined (__TASKING__))
721
722// CMSIS 函数已在编译器中实现为内置函数
723
724#endif
725
726
727/* ################################## NVIC 函数 ############################################ */
728// 设置优先级分组
729static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
730{
731 uint32_t reg_value;
732 uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); // 只取后 3 位,即 0 - 7
733
734 reg_value = SCB->AIRCR; // 读取旧的寄存器配置
735 reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); // 清除对应位
736 reg_value = (reg_value |
737 (0x5FA << SCB_AIRCR_VECTKEY_Pos) | // [31:16], 写入 AIRCR 寄存器时必须要将 0x5FA 写入 VECTKEY,否则写入会被忽略
738 (PriorityGroupTmp << 8)); // [10:8], 优先级分组
739 SCB->AIRCR = reg_value;
740}
741
742// 获取优先级分组
743static __INLINE uint32_t NVIC_GetPriorityGrouping(void)
744{
745 return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos);
746}
747
748// 启用外部中断
749static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
750{
751 NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); // ISER[0] 每一位对应 0 ~ 31 中断
752}
753
754// 禁用外部中断
755static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
756{
757 NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
758}
759
760// 获取外部中断的挂起位
761static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
762{
763 return((uint32_t) (( NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)) )?1:0));
764}
765
766// 设置外部中断的挂起位
767static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
768{
769 NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
770}
771
772// 清除外部中断的挂起位
773static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
774{
775 NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
776}
777
778// 读取外部中断的活动位 (1: 中断程序运行, 0: 未运行)
779static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
780{
781 return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
782}
783
784// 设置中断的优先级
785static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
786{
787 if(IRQn < 0) {
788 // 系统中断,SHP[0] ~ SHP[2] 对应系统异常枚举值 -12 ~ -10,SHP[7](-5),SHP[8](-4),SHP[10](-2),SHP[11](-1),其余未实现
789 // -12 二进制是 1111 0100
790 SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); }
791 else {
792 // 外部中断,IP[0] (8位) 对应外部中断枚举值 0 ,以此类推
793 NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); }
794}
795
796// 读取中断的优先级
797static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
798{
799
800 if(IRQn < 0) {
801 return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); }
802 else {
803 return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); }
804}
805
806
807// 中断的优先级编码
808static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
809{
810 uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); // 优先级分组,3 位
811 uint32_t PreemptPriorityBits; // 主优先级
812 uint32_t SubPriorityBits; // 子优先级
813
814 PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
815 SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
816
817 return (
818 ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
819 ((SubPriority & ((1 << (SubPriorityBits )) - 1)))
820 );
821}
822
823/* 优先级分组 = 5,
824 ↓
825| bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
826 ↑
827 __NVIC_PRIO_BITS = 4,高 4 位有效
828[7:6] -> 主优先级,共 2 位(0-3)
829[5:4] -> 子优先级,共 2 位(0-3) */
830
831// 中断的优先级解码,Priority 参数是中断优先级
832static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
833{
834 uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);
835 uint32_t PreemptPriorityBits;
836 uint32_t SubPriorityBits;
837
838 PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
839 SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
840
841 *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
842 *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1);
843}
844
845
846/* ################################## SysTick 函数 ############################################ */
847#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)
848
849// 初始化和启动 SysTick 计数器及其中断
850static __INLINE uint32_t SysTick_Config(uint32_t ticks)
851{
852 if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); // 重载值超出范围
853
854 SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; // 设置重载寄存器
855 NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); // 为 Cortex-M0 系统中断设置优先级
856 SysTick->VAL = 0; // 加载 SysTick 计数器值
857 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
858 SysTick_CTRL_TICKINT_Msk |
859 SysTick_CTRL_ENABLE_Msk; // 启用 SysTick 中断和 SysTick 定时器
860 return (0);
861}
862
863#endif
864
865
866/* ################################## 复位函数 ############################################ */
867static __INLINE void NVIC_SystemReset(void)
868{
869 SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
870 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
871 SCB_AIRCR_SYSRESETREQ_Msk);
872 __DSB(); // 确保内存访问完成
873 while(1); // 等待直到复位
874}
875
876
877/* ##################################### 调试输入/输出函数 ########################################### */
878extern volatile int ITM_RxBuffer; // 用于接收字符的变量
879#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 // 标识 ITM_RxBuffer 准备好接收下一个字符的值
880
881// 通过 ITM 通道 0 输出一个字符
882static __INLINE uint32_t ITM_SendChar (uint32_t ch)
883{
884 if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && // 跟踪已启用
885 (ITM->TCR & ITM_TCR_ITMENA_Msk) && // ITM 已启用
886 (ITM->TER & (1ul << 0) ) ) // ITM 端口 #0 已启用
887 {
888 while (ITM->PORT[0].u32 == 0);
889 ITM->PORT[0].u8 = (uint8_t) ch;
890 }
891 return (ch);
892}
893
894// 通过变量 ITM_RxBuffer 输入一个字符
895static __INLINE int ITM_ReceiveChar (void) {
896 int ch = -1; // 没有可用字符
897
898 if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
899 ch = ITM_RxBuffer;
900 ITM_RxBuffer = ITM_RXBUFFER_EMPTY; // 准备好接收下一个字符
901 }
902
903 return (ch);
904}
905
906// 检查是否可以通过变量 ITM_RxBuffer 获取字符
907static __INLINE int ITM_CheckChar (void) {
908
909 if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
910 return (0); // 没有可用字符
911 } else {
912 return (1); // 有可用字符
913 }
914}
915
916
917#ifdef __cplusplus // 如果使用 C++ 编译器,结束 C 链接约定
918}
919#endif
920
921// __CM3_CORE_H__
922#endif
内核头文件主要定义了以下内容:
- NVIC,SCB,SysTick,ITM,MPU,CoreDebug 等寄存器内存映射。
- 优先级分组,中断优先级设置函数,SysTick 配置函数等。
- 内核访问函数。
core_cm3.c #
1// 该头文件定义了一系列固定位宽的整数类型,如 int8_t 、uint8_t 、int16_t 等
2#include <stdint.h>
3
4// 定义编译器特定的符号
5#if defined ( __CC_ARM ) // __CC_ARM 是 armcc 编译器的内置预定义宏
6 #define __ASM __asm
7 #define __INLINE __inline
8
9#elif defined ( __ICCARM__ )
10 #define __ASM __asm
11 #define __INLINE inline
12
13#elif defined ( __GNUC__ ) // arm gcc 编译器
14 #define __ASM __asm
15 #define __INLINE inline
16
17#elif defined ( __TASKING__ )
18 #define __ASM __asm
19 #define __INLINE inline
20
21#endif
22
23
24/* ################### 编译器特定的函数 ########################### */
25
26#if defined ( __CC_ARM )
27
28// 获取进程堆栈指针
29__ASM uint32_t __get_PSP(void)
30{
31 mrs r0, psp // 从 PSP 寄存器读取值到 R0 寄存器
32 bx lr // 函数返回(bx 指令跳转到 lr 寄存器中的地址处,lr 寄存器保存的是函数调用处的下一条指令地址)
33}
34
35// 设置进程堆栈指针
36__ASM void __set_PSP(uint32_t topOfProcStack)
37{
38 msr psp, r0 // 将 r0 的值写入 PSP 寄存器(对于有参数的函数,第一个参数(32位或更小)通过 r0 寄存器传递)
39 bx lr
40}
41
42// 获取主堆栈指针
43__ASM uint32_t __get_MSP(void)
44{
45 mrs r0, msp
46 bx lr
47}
48
49// 设置主堆栈指针
50__ASM void __set_MSP(uint32_t mainStackPointer)
51{
52 msr msp, r0
53 bx lr
54}
55
56// 反转半字中的字节,0x12345678 --> 0x34127856
57__ASM uint32_t __REV16(uint16_t value)
58{
59 rev16 r0, r0 // r0 既用作传递函数第一个参数,也用作保存返回值
60 bx lr
61}
62
63// 反转低半字中的字节,并将结果有符号展开,0x33448899 --> 0xFFFF9988
64__ASM int32_t __REVSH(int16_t value)
65{
66 revsh r0, r0
67 bx lr
68}
69
70
71// ARM Compiler 4 之前的版本
72#if (__ARMCC_VERSION < 400000)
73
74// 清除由 ldrex 创建的独占锁
75__ASM void __CLREX(void)
76{
77 clrex
78}
79
80// 获取 basepri 寄存器的值
81__ASM uint32_t __get_BASEPRI(void)
82{
83 mrs r0, basepri
84 bx lr
85}
86
87// 设置 basepri 寄存器的值 (屏蔽优先级低于 basepri 的中断)
88__ASM void __set_BASEPRI(uint32_t basePri)
89{
90 msr basepri, r0
91 bx lr
92}
93
94// 获取 primask 寄存器的值
95__ASM uint32_t __get_PRIMASK(void)
96{
97 mrs r0, primask
98 bx lr
99}
100
101// 设置 primask 寄存器的值 (屏蔽除 NMI 和 HardFault 外的所有中断)
102__ASM void __set_PRIMASK(uint32_t priMask)
103{
104 msr primask, r0
105 bx lr
106}
107
108// 获取 faultmask 寄存器的值
109__ASM uint32_t __get_FAULTMASK(void)
110{
111 mrs r0, faultmask
112 bx lr
113}
114
115// 设置 faultmask 寄存器的值 (屏蔽除 NMI 外的所有中断)
116__ASM void __set_FAULTMASK(uint32_t faultMask)
117{
118 msr faultmask, r0
119 bx lr
120}
121
122// 获取 control 寄存器的值
123__ASM uint32_t __get_CONTROL(void)
124{
125 mrs r0, control
126 bx lr
127}
128
129// 设置 control 寄存器的值 ( control 寄存器用于特权模式的切换、主栈/进程栈的切换)
130__ASM void __set_CONTROL(uint32_t control)
131{
132 msr control, r0
133 bx lr
134}
135
136#endif
137
138
139
140#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
141#pragma diag_suppress=Pe940
142
143uint32_t __get_PSP(void)
144{
145 __ASM("mrs r0, psp");
146 __ASM("bx lr");
147}
148
149void __set_PSP(uint32_t topOfProcStack)
150{
151 __ASM("msr psp, r0");
152 __ASM("bx lr");
153}
154
155uint32_t __get_MSP(void)
156{
157 __ASM("mrs r0, msp");
158 __ASM("bx lr");
159}
160
161void __set_MSP(uint32_t topOfMainStack)
162{
163 __ASM("msr msp, r0");
164 __ASM("bx lr");
165}
166
167uint32_t __REV16(uint16_t value)
168{
169 __ASM("rev16 r0, r0");
170 __ASM("bx lr");
171}
172
173uint32_t __RBIT(uint32_t value)
174{
175 __ASM("rbit r0, r0");
176 __ASM("bx lr");
177}
178
179uint8_t __LDREXB(uint8_t *addr)
180{
181 __ASM("ldrexb r0, [r0]");
182 __ASM("bx lr");
183}
184
185uint16_t __LDREXH(uint16_t *addr)
186{
187 __ASM("ldrexh r0, [r0]");
188 __ASM("bx lr");
189}
190
191uint32_t __LDREXW(uint32_t *addr)
192{
193 __ASM("ldrex r0, [r0]");
194 __ASM("bx lr");
195}
196
197uint32_t __STREXB(uint8_t value, uint8_t *addr)
198{
199 __ASM("strexb r0, r0, [r1]");
200 __ASM("bx lr");
201}
202
203uint32_t __STREXH(uint16_t value, uint16_t *addr)
204{
205 __ASM("strexh r0, r0, [r1]");
206 __ASM("bx lr");
207}
208
209uint32_t __STREXW(uint32_t value, uint32_t *addr)
210{
211 __ASM("strex r0, r0, [r1]");
212 __ASM("bx lr");
213}
214
215#pragma diag_default=Pe940
216
217
218#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
219
220// naked 属性告诉编译器不生成任何序言/尾声代码,即程序员必须自己处理 寄存器保存/恢复, 栈指针调整 , 函数返回
221uint32_t __get_PSP(void) __attribute__( ( naked ) );
222uint32_t __get_PSP(void)
223{
224 uint32_t result=0;
225
226 __ASM volatile ("MRS %0, psp\n\t"
227 "MOV r0, %0 \n\t"
228 "BX lr \n\t" : "=r" (result) );
229 return(result);
230}
231
232void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );
233void __set_PSP(uint32_t topOfProcStack)
234{
235 __ASM volatile ("MSR psp, %0\n\t"
236 "BX lr \n\t" : : "r" (topOfProcStack) );
237}
238
239uint32_t __get_MSP(void) __attribute__( ( naked ) );
240uint32_t __get_MSP(void)
241{
242 uint32_t result=0;
243
244 __ASM volatile ("MRS %0, msp\n\t"
245 "MOV r0, %0 \n\t"
246 "BX lr \n\t" : "=r" (result) );
247 return(result);
248}
249
250void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );
251void __set_MSP(uint32_t topOfMainStack)
252{
253 __ASM volatile ("MSR msp, %0\n\t"
254 "BX lr \n\t" : : "r" (topOfMainStack) );
255}
256
257uint32_t __get_BASEPRI(void)
258{
259 uint32_t result=0;
260
261 __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
262 return(result);
263}
264
265void __set_BASEPRI(uint32_t value)
266{
267 __ASM volatile ("MSR basepri, %0" : : "r" (value) );
268}
269
270uint32_t __get_PRIMASK(void)
271{
272 uint32_t result=0;
273
274 __ASM volatile ("MRS %0, primask" : "=r" (result) );
275 return(result);
276}
277
278void __set_PRIMASK(uint32_t priMask)
279{
280 __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
281}
282
283uint32_t __get_FAULTMASK(void)
284{
285 uint32_t result=0;
286
287 __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
288 return(result);
289}
290
291void __set_FAULTMASK(uint32_t faultMask)
292{
293 __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
294}
295
296uint32_t __get_CONTROL(void)
297{
298 uint32_t result=0;
299
300 __ASM volatile ("MRS %0, control" : "=r" (result) );
301 return(result);
302}
303
304void __set_CONTROL(uint32_t control)
305{
306 __ASM volatile ("MSR control, %0" : : "r" (control) );
307}
308
309uint32_t __REV(uint32_t value)
310{
311 uint32_t result=0;
312
313 __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
314 return(result);
315}
316
317uint32_t __REV16(uint16_t value)
318{
319 uint32_t result=0;
320
321 __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
322 return(result);
323}
324
325int32_t __REVSH(int16_t value)
326{
327 uint32_t result=0;
328
329 __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
330 return(result);
331}
332
333uint32_t __RBIT(uint32_t value)
334{
335 uint32_t result=0;
336
337 __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
338 return(result);
339}
340
341uint8_t __LDREXB(uint8_t *addr)
342{
343 uint8_t result=0;
344
345 __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
346 return(result);
347}
348
349uint16_t __LDREXH(uint16_t *addr)
350{
351 uint16_t result=0;
352
353 __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
354 return(result);
355}
356
357uint32_t __LDREXW(uint32_t *addr)
358{
359 uint32_t result=0;
360
361 __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
362 return(result);
363}
364
365uint32_t __STREXB(uint8_t value, uint8_t *addr)
366{
367 uint32_t result=0;
368
369 __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
370 return(result);
371}
372
373uint32_t __STREXH(uint16_t value, uint16_t *addr)
374{
375 uint32_t result=0;
376
377 __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
378 return(result);
379}
380
381uint32_t __STREXW(uint32_t value, uint32_t *addr)
382{
383 uint32_t result=0;
384
385 __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
386 return(result);
387}
388
389
390#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
391/* TASKING carm specific functions */
392
393/*
394 * The CMSIS functions have been implemented as intrinsics in the compiler.
395 * Please use "carm -?i" to get an up to date list of all instrinsics,
396 * Including the CMSIS ones.
397 */
398
399#endif
STM32F10x 设备文件 #
GCC 启动文件 #
1.syntax unified // 使用统一汇编语言(Unified Assembly Language, UAL)
2.cpu cortex-m3 // 指定架构 Cortex-M3
3.fpu softvfp // 使用软件浮点运算,CM3 没有硬件浮点单元
4.thumb // 使用 thumb 指令集
5
6.global g_pfnVectors // 声明一个全局符号 g_pfnVectors(向量表)
7.global Default_Handler // 声明一个全局符号 Default_Handler(复位函数)
8
9/* .word 语法
10 * .word 0x20001000 ; 分配一个字的空间,值为 0x20001000
11 * .word Reset_Handler ; 为 Reset_Handler 分配一个字的空间,Reset_Handler 为符号地址,可存储一个字 */
12
13.word _sidata // .data 段在 FLASH 中的起始地址,该值在链接脚本中定义(.data 包含已初始化的全局/静态变量)
14.word _sdata // .data 段在 SRAM 中的起始地址,该值在链接脚本中定义
15.word _edata // .data 段在 SRAM 中的结束地址,该值在链接脚本中定义
16.word _sbss // .bss 段在 SRAM 中的起始地址,该值在链接脚本中定义( .bss 包含未初始化的全局/静态变量)
17.word _ebss // .bss 段在 SRAM 中的结束地址,该值在链接脚本中定义
18
19
20.equ BootRAM, 0xF1E0F85F // 定义 BootRAM = 0xF1E0F85F,用于 SRAM 启动
21
22
23.section .text.Reset_Handler // 告诉汇编器将本行之后的代码或数据放入 .text.Reset_Handler 段中,直到遇到下一个 .section
24.weak Reset_Handler // 声明 Reset_Handler 为弱符号,允许用户重写
25.type Reset_Handler, %function // 指定 Reset_Handler 为函数类型
26
27Reset_Handler:
28 movs r1, #0 // r1 = 0
29 b LoopCopyDataInit // 跳转到 LoopCopyDataInit 处
30
31CopyDataInit:
32 ldr r3, =_sidata // r3 = _sidata(.data 段在 FLASH 中的起始地址)
33 ldr r3, [r3, r1] // r3 = *(r3 + r1) = *(_sidata + r1)
34 str r3, [r0, r1] // 存储 r3 -> *(r0 +r1),即 *(_sidata + r1) -> *(_sdata + r1)
35 adds r1, r1, #4 // r1 = r1 + 4,此处执行完继续向下执行 LoopCopyDataInit
36
37LoopCopyDataInit:
38 ldr r0, =_sdata // r0 = _sdata(.data 段在 SRAM 中的起始地址)
39 ldr r3, =_edata // r3 = _edata(.data 段在 SRAM 中的结束地址)
40 adds r2, r0, r1 // r2 = r0 + r1 = _sdata + r1
41 cmp r2, r3 // 比较 r2 和 r3 的值 --> 比较 _sdata+r1 和 _edata 的值
42 bcc CopyDataInit // 如果 _sdata + r1 < _edata 则跳转到 CopyDataInit
43 ldr r2, =_sbss // r2 = _sbss(.bss 段在 SRAM 中的起始地址)
44 b LoopFillZerobss // 跳转到 LoopFillZerobss
45
46FillZerobss:
47 movs r3, #0 // r3 = 0
48 str r3, [r2], #4 // 存储 r3 -> *r2 然后 r2 = r2 + 4 , 即存储 0 -> *_sbss 然后 _sbss = _sbss + 4
49
50LoopFillZerobss:
51 ldr r3, = _ebss // r3 = _ebss(.bss 段在 SRAM 中的结束地址)
52 cmp r2, r3 // 比较 r2 和 r3 --> 比较 _sbss 和 _ebss
53 bcc FillZerobss // 如果 _sbss < _ebss 则跳转到 FillZerobss
54 bl SystemInit // 跳转到 SystemInit 函数,并将返回地址(下一条指令的地址)保存在 LR 寄存器中
55 bl main // 跳转到 main 函数,并将返回地址(下一条指令的地址)保存在 LR 寄存器中
56 bx lr // 从 main 返回后,跳回 LR 存器地址(通常不会执行到这里)
57
58.size Reset_Handler, .-Reset_Handler // 设置 Reset_Handler 的大小为当前位置(.)减去 Reset_Handler 的起始地址
59 // 显式指定符号的大小信息(边界),以便链接器可以检查符号引用是否超出范围
60
61
62.section .text.Default_Handler,"ax",%progbits // 将 Default_Handler 代码放在 .text.Default_Handler 段中,"ax" 表示可分配+可执行
63Default_Handler:
64Infinite_Loop: // 当处理器收到未预期的中断时执行的代码,进入死循环
65 b Infinite_Loop // 跳转到 Infinite_Loop
66.size Default_Handler, .-Default_Handler // 设置 Default_Handler 的大小为当前位置(.)减去 Default_Handler 的起始地址
67
68
69
70.section .isr_vector,"a",%progbits // 告诉汇编器将本行之后的代码或数据(向量表)放入 .isr_vector 段,"a" 表示可分配,直到遇到下一个 .section
71.type g_pfnVectors, %object // 指定 g_pfnVectors 为数据对象类型
72.size g_pfnVectors, .-g_pfnVectors // 设置 g_pfnVectors 的大小,为什么 .size 指令不放向量表后面????存疑。
73
74
75g_pfnVectors:
76 .word _estack // 初始栈指针地址
77 .word Reset_Handler // 复位处理程序
78 .word NMI_Handler
79 .word HardFault_Handler
80 .word MemManage_Handler
81 .word BusFault_Handler
82 .word UsageFault_Handler
83 .word 0
84 .word 0
85 .word 0
86 .word 0
87 .word SVC_Handler
88 .word DebugMon_Handler
89 .word 0
90 .word PendSV_Handler
91 .word SysTick_Handler
92 .word WWDG_IRQHandler
93 .word PVD_IRQHandler
94 .word TAMPER_IRQHandler
95 .word RTC_IRQHandler
96 .word FLASH_IRQHandler
97 .word RCC_IRQHandler
98 .word EXTI0_IRQHandler
99 .word EXTI1_IRQHandler
100 .word EXTI2_IRQHandler
101 .word EXTI3_IRQHandler
102 .word EXTI4_IRQHandler
103 .word DMA1_Channel1_IRQHandler
104 .word DMA1_Channel2_IRQHandler
105 .word DMA1_Channel3_IRQHandler
106 .word DMA1_Channel4_IRQHandler
107 .word DMA1_Channel5_IRQHandler
108 .word DMA1_Channel6_IRQHandler
109 .word DMA1_Channel7_IRQHandler
110 .word ADC1_2_IRQHandler
111 .word USB_HP_CAN1_TX_IRQHandler
112 .word USB_LP_CAN1_RX0_IRQHandler
113 .word CAN1_RX1_IRQHandler
114 .word CAN1_SCE_IRQHandler
115 .word EXTI9_5_IRQHandler
116 .word TIM1_BRK_IRQHandler
117 .word TIM1_UP_IRQHandler
118 .word TIM1_TRG_COM_IRQHandler
119 .word TIM1_CC_IRQHandler
120 .word TIM2_IRQHandler
121 .word TIM3_IRQHandler
122 .word TIM4_IRQHandler
123 .word I2C1_EV_IRQHandler
124 .word I2C1_ER_IRQHandler
125 .word I2C2_EV_IRQHandler
126 .word I2C2_ER_IRQHandler
127 .word SPI1_IRQHandler
128 .word SPI2_IRQHandler
129 .word USART1_IRQHandler
130 .word USART2_IRQHandler
131 .word USART3_IRQHandler
132 .word EXTI15_10_IRQHandler
133 .word RTCAlarm_IRQHandler
134 .word USBWakeUp_IRQHandler
135 .word TIM8_BRK_IRQHandler
136 .word TIM8_UP_IRQHandler
137 .word TIM8_TRG_COM_IRQHandler
138 .word TIM8_CC_IRQHandler
139 .word ADC3_IRQHandler
140 .word FSMC_IRQHandler
141 .word SDIO_IRQHandler
142 .word TIM5_IRQHandler
143 .word SPI3_IRQHandler
144 .word UART4_IRQHandler
145 .word UART5_IRQHandler
146 .word TIM6_IRQHandler
147 .word TIM7_IRQHandler
148 .word DMA2_Channel1_IRQHandler
149 .word DMA2_Channel2_IRQHandler
150 .word DMA2_Channel3_IRQHandler
151 .word DMA2_Channel4_5_IRQHandler
152 .word 0 // 以下为保留中断向量位置,填充为0
153 .word 0
154 .word 0
155 .word 0
156 .word 0
157 .word 0
158 .word 0
159 .word 0
160 .word 0
161 .word 0
162 .word 0
163 .word 0
164 .word 0
165 .word 0
166 .word 0
167 .word 0
168 .word 0
169 .word 0
170 .word 0
171 .word 0
172 .word 0
173 .word 0
174 .word 0
175 .word 0
176 .word 0
177 .word 0
178 .word 0
179 .word 0
180 .word 0
181 .word 0
182 .word 0
183 .word 0
184 .word 0
185 .word 0
186 .word 0
187 .word 0
188 .word 0
189 .word 0
190 .word 0
191 .word 0
192 .word 0
193 .word 0
194 .word 0
195 .word 0
196 .word BootRAM // 偏移:0x1E0;
197 // BootRAM = 0xF1E0F85F = 0xF85F 0xF1E0 = LDR.W PC, [PC, #-0x1E0] -> 即 PC = *(PC - 0x1E0)
198
199
200// .weak 表示弱定义符号,用户函数可覆盖
201// .thumb_set 将一个符号定义为另一个符号的别名 (alias),并且明确指定该别名是 Thumb 指令集的符号
202.weak NMI_Handler
203.thumb_set NMI_Handler,Default_Handler // 设置 NMI_Handler 为 Default_Handler 的弱别名
204
205.weak HardFault_Handler
206.thumb_set HardFault_Handler,Default_Handler
207
208.weak MemManage_Handler
209.thumb_set MemManage_Handler,Default_Handler
210
211.weak BusFault_Handler
212.thumb_set BusFault_Handler,Default_Handler
213
214.weak UsageFault_Handler
215.thumb_set UsageFault_Handler,Default_Handler
216
217.weak SVC_Handler
218.thumb_set SVC_Handler,Default_Handler
219
220.weak DebugMon_Handler
221.thumb_set DebugMon_Handler,Default_Handler
222
223.weak PendSV_Handler
224.thumb_set PendSV_Handler,Default_Handler
225
226.weak SysTick_Handler
227.thumb_set SysTick_Handler,Default_Handler
228
229.weak WWDG_IRQHandler
230.thumb_set WWDG_IRQHandler,Default_Handler
231
232.weak PVD_IRQHandler
233.thumb_set PVD_IRQHandler,Default_Handler
234
235.weak TAMPER_IRQHandler
236.thumb_set TAMPER_IRQHandler,Default_Handler
237
238.weak RTC_IRQHandler
239.thumb_set RTC_IRQHandler,Default_Handler
240
241.weak FLASH_IRQHandler
242.thumb_set FLASH_IRQHandler,Default_Handler
243
244.weak RCC_IRQHandler
245.thumb_set RCC_IRQHandler,Default_Handler
246
247.weak EXTI0_IRQHandler
248.thumb_set EXTI0_IRQHandler,Default_Handler
249
250.weak EXTI1_IRQHandler
251.thumb_set EXTI1_IRQHandler,Default_Handler
252
253.weak EXTI2_IRQHandler
254.thumb_set EXTI2_IRQHandler,Default_Handler
255
256.weak EXTI3_IRQHandler
257.thumb_set EXTI3_IRQHandler,Default_Handler
258
259.weak EXTI4_IRQHandler
260.thumb_set EXTI4_IRQHandler,Default_Handler
261
262.weak DMA1_Channel1_IRQHandler
263.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
264
265.weak DMA1_Channel2_IRQHandler
266.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
267
268.weak DMA1_Channel3_IRQHandler
269.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
270
271.weak DMA1_Channel4_IRQHandler
272.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
273
274.weak DMA1_Channel5_IRQHandler
275.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
276
277.weak DMA1_Channel6_IRQHandler
278.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
279
280.weak DMA1_Channel7_IRQHandler
281.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
282
283.weak ADC1_2_IRQHandler
284.thumb_set ADC1_2_IRQHandler,Default_Handler
285
286.weak USB_HP_CAN1_TX_IRQHandler
287.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
288
289.weak USB_LP_CAN1_RX0_IRQHandler
290.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
291
292.weak CAN1_RX1_IRQHandler
293.thumb_set CAN1_RX1_IRQHandler,Default_Handler
294
295.weak CAN1_SCE_IRQHandler
296.thumb_set CAN1_SCE_IRQHandler,Default_Handler
297
298.weak EXTI9_5_IRQHandler
299.thumb_set EXTI9_5_IRQHandler,Default_Handler
300
301.weak TIM1_BRK_IRQHandler
302.thumb_set TIM1_BRK_IRQHandler,Default_Handler
303
304.weak TIM1_UP_IRQHandler
305.thumb_set TIM1_UP_IRQHandler,Default_Handler
306
307.weak TIM1_TRG_COM_IRQHandler
308.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
309
310.weak TIM1_CC_IRQHandler
311.thumb_set TIM1_CC_IRQHandler,Default_Handler
312
313.weak TIM2_IRQHandler
314.thumb_set TIM2_IRQHandler,Default_Handler
315
316.weak TIM3_IRQHandler
317.thumb_set TIM3_IRQHandler,Default_Handler
318
319.weak TIM4_IRQHandler
320.thumb_set TIM4_IRQHandler,Default_Handler
321
322.weak I2C1_EV_IRQHandler
323.thumb_set I2C1_EV_IRQHandler,Default_Handler
324
325.weak I2C1_ER_IRQHandler
326.thumb_set I2C1_ER_IRQHandler,Default_Handler
327
328.weak I2C2_EV_IRQHandler
329.thumb_set I2C2_EV_IRQHandler,Default_Handler
330
331.weak I2C2_ER_IRQHandler
332.thumb_set I2C2_ER_IRQHandler,Default_Handler
333
334.weak SPI1_IRQHandler
335.thumb_set SPI1_IRQHandler,Default_Handler
336
337.weak SPI2_IRQHandler
338.thumb_set SPI2_IRQHandler,Default_Handler
339
340.weak USART1_IRQHandler
341.thumb_set USART1_IRQHandler,Default_Handler
342
343.weak USART2_IRQHandler
344.thumb_set USART2_IRQHandler,Default_Handler
345
346.weak USART3_IRQHandler
347.thumb_set USART3_IRQHandler,Default_Handler
348
349.weak EXTI15_10_IRQHandler
350.thumb_set EXTI15_10_IRQHandler,Default_Handler
351
352.weak RTCAlarm_IRQHandler
353.thumb_set RTCAlarm_IRQHandler,Default_Handler
354
355.weak USBWakeUp_IRQHandler
356.thumb_set USBWakeUp_IRQHandler,Default_Handler
357
358.weak TIM8_BRK_IRQHandler
359.thumb_set TIM8_BRK_IRQHandler,Default_Handler
360
361.weak TIM8_UP_IRQHandler
362.thumb_set TIM8_UP_IRQHandler,Default_Handler
363
364.weak TIM8_TRG_COM_IRQHandler
365.thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler
366
367.weak TIM8_CC_IRQHandler
368.thumb_set TIM8_CC_IRQHandler,Default_Handler
369
370.weak ADC3_IRQHandler
371.thumb_set ADC3_IRQHandler,Default_Handler
372
373.weak FSMC_IRQHandler
374.thumb_set FSMC_IRQHandler,Default_Handler
375
376.weak SDIO_IRQHandler
377.thumb_set SDIO_IRQHandler,Default_Handler
378
379.weak TIM5_IRQHandler
380.thumb_set TIM5_IRQHandler,Default_Handler
381
382.weak SPI3_IRQHandler
383.thumb_set SPI3_IRQHandler,Default_Handler
384
385.weak UART4_IRQHandler
386.thumb_set UART4_IRQHandler,Default_Handler
387
388.weak UART5_IRQHandler
389.thumb_set UART5_IRQHandler,Default_Handler
390
391.weak TIM6_IRQHandler
392.thumb_set TIM6_IRQHandler,Default_Handler
393
394.weak TIM7_IRQHandler
395.thumb_set TIM7_IRQHandler,Default_Handler
396
397.weak DMA2_Channel1_IRQHandler
398.thumb_set DMA2_Channel1_IRQHandler,Default_Handler
399
400.weak DMA2_Channel2_IRQHandler
401.thumb_set DMA2_Channel2_IRQHandler,Default_Handler
402
403.weak DMA2_Channel3_IRQHandler
404.thumb_set DMA2_Channel3_IRQHandler,Default_Handler
405
406.weak DMA2_Channel4_5_IRQHandler
407.thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
STM32 芯片命名规则 #
启动文件后缀 #
stm32f10x.h #
stm32f10x.h 文件很长,以下截取部分关键代码:
1#ifndef __STM32F10x_H
2#define __STM32F10x_H
3
4#ifdef __cplusplus
5 extern "C" {
6#endif
7
8// 选择目标设备,这里的宏需要用户自己在代码中定义,或者通过编译器参数传递如 -D STM32F10X_HD
9#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
10 // #define STM32F10X_LD
11 // #define STM32F10X_LD_VL
12 // #define STM32F10X_MD
13 // #define STM32F10X_MD_VL
14 // #define STM32F10X_HD
15 // #define STM32F10X_HD_VL
16 // #define STM32F10X_XL
17 // #define STM32F10X_CL
18#endif
19
20
21// 如果没有定义目标设备,这里会报错
22#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
23 #error "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
24#endif
25
26
27// 是否使用标准库外设驱动
28#if !defined (USE_STDPERIPH_DRIVER)
29 #define USE_STDPERIPH_DRIVER
30#endif
31
32
33// 外部晶振频率,在 system_stm32f10x.c 中,系统初始化函数 SystemInit 会设置时钟,需要 HSE_VALUE
34#if !defined HSE_VALUE
35 #ifdef STM32F10X_CL
36 #define HSE_VALUE ((uint32_t)25000000) // 25 MHz
37 #else
38 #define HSE_VALUE ((uint32_t)8000000) // 8 MHz
39 #endif
40#endif
41
42
43// 外部晶振启动的等待时间,当 STM32 尝试启动外部晶振时,需要等待晶振稳定
44#if !defined (HSE_STARTUP_TIMEOUT)
45 #define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) // 这只是大致的一个计数值,约 0.5 秒
46#endif
47
48
49// 内部晶振频率
50#if !defined (HSI_VALUE)
51 #define HSI_VALUE ((uint32_t)8000000) // 8 MHz
52#endif
53
54
55// 定义标准库版本 V3.6.4
56#define __STM32F10X_STDPERIPH_VERSION_MAIN (0x03) // [31:24] main version
57#define __STM32F10X_STDPERIPH_VERSION_SUB1 (0x06) // [23:16] sub1 version
58#define __STM32F10X_STDPERIPH_VERSION_SUB2 (0x04) // [15:8] sub2 version
59#define __STM32F10X_STDPERIPH_VERSION_RC (0x00) // [7:0] release candidate
60#define __STM32F10X_STDPERIPH_VERSION ((__STM32F10X_STDPERIPH_VERSION_MAIN << 24)\
61 |(__STM32F10X_STDPERIPH_VERSION_SUB1 << 16)\
62 |(__STM32F10X_STDPERIPH_VERSION_SUB2 << 8)\
63 |(__STM32F10X_STDPERIPH_VERSION_RC))
64
65
66// CM3 处理器与内核系统组件配置
67#ifdef STM32F10X_XL
68 #define __MPU_PRESENT 1 // STM32 超大容量设备包含 MPU
69#else
70 #define __MPU_PRESENT 0 // 其它设备不含 MPU
71#endif
72
73#define __CM3_REV 0x0200 // 内核修订版本 r2p0
74#define __NVIC_PRIO_BITS 4 // 4 Bits 优先级位宽
75#define __Vendor_SysTickConfig 0 // 针对特定厂商的 SysTick 配置?不太清楚
76
77
78
79// CM3 的中断源编号从 1 开始,1 - 15 是系统异常,16 - 255 是外部中断
80// 枚举值使用负数,是为了区分系统异常与外部中断,提升部分函数效率,如 core_cm3.h 中的 NVIC_SetPriority 函数
81typedef enum IRQn
82{
83/************************ 系统异常枚举值 *******************************************************/
84 NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
85 MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
86 BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
87 UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
88 SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
89 DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
90 PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
91 SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
92
93/************************ 外部中断枚举值 *******************************************************/
94 WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */
95 PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */
96 TAMPER_IRQn = 2, /*!< Tamper Interrupt */
97 RTC_IRQn = 3, /*!< RTC global Interrupt */
98 FLASH_IRQn = 4, /*!< FLASH global Interrupt */
99 RCC_IRQn = 5, /*!< RCC global Interrupt */
100 EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */
101 EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */
102 EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */
103 EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */
104 EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */
105 DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */
106 DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */
107 DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */
108 DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */
109 DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */
110 DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */
111 DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */
112
113#ifdef STM32F10X_LD
114 ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
115 USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
116 USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
117 CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
118 CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
119 EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
120 TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */
121 TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
122 TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */
123 TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
124 TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
125 TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
126 I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
127 I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
128 SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
129 USART1_IRQn = 37, /*!< USART1 global Interrupt */
130 USART2_IRQn = 38, /*!< USART2 global Interrupt */
131 EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
132 RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
133 USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
134#endif /* STM32F10X_LD */
135
136#ifdef STM32F10X_LD_VL
137 ADC1_IRQn = 18, /*!< ADC1 global Interrupt */
138 EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
139 TIM1_BRK_TIM15_IRQn = 24, /*!< TIM1 Break and TIM15 Interrupts */
140 TIM1_UP_TIM16_IRQn = 25, /*!< TIM1 Update and TIM16 Interrupts */
141 TIM1_TRG_COM_TIM17_IRQn = 26, /*!< TIM1 Trigger and Commutation and TIM17 Interrupt */
142 TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
143 TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
144 TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
145 I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
146 I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
147 SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
148 USART1_IRQn = 37, /*!< USART1 global Interrupt */
149 USART2_IRQn = 38, /*!< USART2 global Interrupt */
150 EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
151 RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
152 CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
153 TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
154 TIM7_IRQn = 55 /*!< TIM7 Interrupt */
155#endif /* STM32F10X_LD_VL */
156
157#ifdef STM32F10X_MD
158 ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
159 USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
160 USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
161 CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
162 CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
163 EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
164 TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */
165 TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
166 TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */
167 TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
168 TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
169 TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
170 TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
171 I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
172 I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
173 I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
174 I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
175 SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
176 SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
177 USART1_IRQn = 37, /*!< USART1 global Interrupt */
178 USART2_IRQn = 38, /*!< USART2 global Interrupt */
179 USART3_IRQn = 39, /*!< USART3 global Interrupt */
180 EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
181 RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
182 USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
183#endif /* STM32F10X_MD */
184
185#ifdef STM32F10X_MD_VL
186 ADC1_IRQn = 18, /*!< ADC1 global Interrupt */
187 EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
188 TIM1_BRK_TIM15_IRQn = 24, /*!< TIM1 Break and TIM15 Interrupts */
189 TIM1_UP_TIM16_IRQn = 25, /*!< TIM1 Update and TIM16 Interrupts */
190 TIM1_TRG_COM_TIM17_IRQn = 26, /*!< TIM1 Trigger and Commutation and TIM17 Interrupt */
191 TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
192 TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
193 TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
194 TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
195 I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
196 I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
197 I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
198 I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
199 SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
200 SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
201 USART1_IRQn = 37, /*!< USART1 global Interrupt */
202 USART2_IRQn = 38, /*!< USART2 global Interrupt */
203 USART3_IRQn = 39, /*!< USART3 global Interrupt */
204 EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
205 RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
206 CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
207 TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
208 TIM7_IRQn = 55 /*!< TIM7 Interrupt */
209#endif /* STM32F10X_MD_VL */
210
211#ifdef STM32F10X_HD
212 ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
213 USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
214 USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
215 CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
216 CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
217 EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
218 TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */
219 TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
220 TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */
221 TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
222 TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
223 TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
224 TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
225 I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
226 I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
227 I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
228 I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
229 SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
230 SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
231 USART1_IRQn = 37, /*!< USART1 global Interrupt */
232 USART2_IRQn = 38, /*!< USART2 global Interrupt */
233 USART3_IRQn = 39, /*!< USART3 global Interrupt */
234 EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
235 RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
236 USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
237 TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */
238 TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */
239 TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt */
240 TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */
241 ADC3_IRQn = 47, /*!< ADC3 global Interrupt */
242 FSMC_IRQn = 48, /*!< FSMC global Interrupt */
243 SDIO_IRQn = 49, /*!< SDIO global Interrupt */
244 TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
245 SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
246 UART4_IRQn = 52, /*!< UART4 global Interrupt */
247 UART5_IRQn = 53, /*!< UART5 global Interrupt */
248 TIM6_IRQn = 54, /*!< TIM6 global Interrupt */
249 TIM7_IRQn = 55, /*!< TIM7 global Interrupt */
250 DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
251 DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
252 DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
253 DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
254#endif /* STM32F10X_HD */
255
256#ifdef STM32F10X_HD_VL
257 ADC1_IRQn = 18, /*!< ADC1 global Interrupt */
258 EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
259 TIM1_BRK_TIM15_IRQn = 24, /*!< TIM1 Break and TIM15 Interrupts */
260 TIM1_UP_TIM16_IRQn = 25, /*!< TIM1 Update and TIM16 Interrupts */
261 TIM1_TRG_COM_TIM17_IRQn = 26, /*!< TIM1 Trigger and Commutation and TIM17 Interrupt */
262 TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
263 TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
264 TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
265 TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
266 I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
267 I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
268 I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
269 I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
270 SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
271 SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
272 USART1_IRQn = 37, /*!< USART1 global Interrupt */
273 USART2_IRQn = 38, /*!< USART2 global Interrupt */
274 USART3_IRQn = 39, /*!< USART3 global Interrupt */
275 EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
276 RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
277 CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */
278 TIM12_IRQn = 43, /*!< TIM12 global Interrupt */
279 TIM13_IRQn = 44, /*!< TIM13 global Interrupt */
280 TIM14_IRQn = 45, /*!< TIM14 global Interrupt */
281 TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
282 SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
283 UART4_IRQn = 52, /*!< UART4 global Interrupt */
284 UART5_IRQn = 53, /*!< UART5 global Interrupt */
285 TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */
286 TIM7_IRQn = 55, /*!< TIM7 Interrupt */
287 DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
288 DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
289 DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
290 DMA2_Channel4_5_IRQn = 59, /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
291 DMA2_Channel5_IRQn = 60 /*!< DMA2 Channel 5 global Interrupt (DMA2 Channel 5 is
292 mapped at position 60 only if the MISC_REMAP bit in
293 the AFIO_MAPR2 register is set) */
294#endif /* STM32F10X_HD_VL */
295
296#ifdef STM32F10X_XL
297 ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
298 USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
299 USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
300 CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
301 CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
302 EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
303 TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break Interrupt and TIM9 global Interrupt */
304 TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global Interrupt */
305 TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */
306 TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
307 TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
308 TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
309 TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
310 I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
311 I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
312 I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
313 I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
314 SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
315 SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
316 USART1_IRQn = 37, /*!< USART1 global Interrupt */
317 USART2_IRQn = 38, /*!< USART2 global Interrupt */
318 USART3_IRQn = 39, /*!< USART3 global Interrupt */
319 EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
320 RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
321 USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
322 TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global Interrupt */
323 TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global Interrupt */
324 TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */
325 TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */
326 ADC3_IRQn = 47, /*!< ADC3 global Interrupt */
327 FSMC_IRQn = 48, /*!< FSMC global Interrupt */
328 SDIO_IRQn = 49, /*!< SDIO global Interrupt */
329 TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
330 SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
331 UART4_IRQn = 52, /*!< UART4 global Interrupt */
332 UART5_IRQn = 53, /*!< UART5 global Interrupt */
333 TIM6_IRQn = 54, /*!< TIM6 global Interrupt */
334 TIM7_IRQn = 55, /*!< TIM7 global Interrupt */
335 DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
336 DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
337 DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
338 DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
339#endif /* STM32F10X_XL */
340
341#ifdef STM32F10X_CL
342 ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
343 CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
344 CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
345 CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
346 CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
347 EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
348 TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */
349 TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
350 TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */
351 TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
352 TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
353 TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
354 TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
355 I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
356 I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
357 I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
358 I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
359 SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
360 SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
361 USART1_IRQn = 37, /*!< USART1 global Interrupt */
362 USART2_IRQn = 38, /*!< USART2 global Interrupt */
363 USART3_IRQn = 39, /*!< USART3 global Interrupt */
364 EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
365 RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
366 OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS WakeUp from suspend through EXTI Line Interrupt */
367 TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
368 SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
369 UART4_IRQn = 52, /*!< UART4 global Interrupt */
370 UART5_IRQn = 53, /*!< UART5 global Interrupt */
371 TIM6_IRQn = 54, /*!< TIM6 global Interrupt */
372 TIM7_IRQn = 55, /*!< TIM7 global Interrupt */
373 DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
374 DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
375 DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
376 DMA2_Channel4_IRQn = 59, /*!< DMA2 Channel 4 global Interrupt */
377 DMA2_Channel5_IRQn = 60, /*!< DMA2 Channel 5 global Interrupt */
378 ETH_IRQn = 61, /*!< Ethernet global Interrupt */
379 ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */
380 CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */
381 CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */
382 CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */
383 CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */
384 OTG_FS_IRQn = 67 /*!< USB OTG FS global Interrupt */
385#endif /* STM32F10X_CL */
386} IRQn_Type;
387
388
389#include "core_cm3.h"
390#include "system_stm32f10x.h"
391#include <stdint.h>
392
393
394// 后面都是外设的寄存器结构体 / 外设地址的定义,很长,就省略了...
395
396省略...
397
398typedef struct
399{
400 __IO uint32_t CRL;
401 __IO uint32_t CRH;
402 __IO uint32_t IDR;
403 __IO uint32_t ODR;
404 __IO uint32_t BSRR;
405 __IO uint32_t BRR;
406 __IO uint32_t LCKR;
407} GPIO_TypeDef;
408
409省略...
410#define FLASH_BASE ((uint32_t)0x08000000)
411#define SRAM_BASE ((uint32_t)0x20000000)
412
413#define APB1PERIPH_BASE PERIPH_BASE
414#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
415#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
416
417省略...
418
419#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
420#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
421#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
422#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
423#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
424#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00)
425#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000)
426
427省略...
428
429#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
430#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
431#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
432#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
433#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
434#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)
435#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)
436
437省略...
438
439#ifdef USE_STDPERIPH_DRIVER
440 #include "stm32f10x_conf.h"
441#endif
442
443省略...
预定义宏 #
STM32F10X_LD : 按启动文件后缀,选择一个
STM32F10X_MD :
STM32F10X_HD :
STM32F10X_XL :
STM32F10X_CL :
STM32F10X_LD_VL :
STM32F10X_MD_VL :
STM32F10X_HD_VL :
USE_STDPERIPH_DRIVER : 使用标准库外设驱动
HSE_VALUE : 外部晶振频率
HSE_STARTUP_TIMEOUT : 外部晶振启动的等待时间
HSI_VALUE : 内部晶振频率
一般不直接在 stm32f10x.h 中设置上述宏,而是通过编译器参数传递:
$ arm-none-eabi-gcc -D STM32F10X_HD -D USE_STDPERIPH_DRIVER -D HSE_VALUE=8000000
头文件包含 #
#include "core_cm3.h"
#include "system_stm32f10x.h"
#ifdef USE_STDPERIPH_DRIVER
#include "stm32f10x_conf.h"
#endif
stm32f10x.h 并不调用 core_cm3.h 、system_stm32f10x.h 或 stm32f10x_conf.h 中的任何函数与宏定义。用户程序只需要包含 stm32f10x.h,就可以调用内核/外设函数及宏定义。
system_stm32f10x.h #
1
2#ifndef __SYSTEM_STM32F10X_H
3#define __SYSTEM_STM32F10X_H
4
5#ifdef __cplusplus
6 extern "C" {
7#endif
8
9extern uint32_t SystemCoreClock; // 内核时钟 HCLK 频率,该变量在 system_stm32f10x.c 中定义,用户应用程序可用它来设置 SysTick 定时器或配置其他参数
10extern void SystemInit(void); // 设置系统时钟,该函数在启动文件中会被调用
11extern void SystemCoreClockUpdate(void); // 更新 SystemCoreClock 变量,必须在程序执行期间内核时钟发生变化时调用
12
13#ifdef __cplusplus
14}
15#endif
16
17#endif
system_stm32f10x.c #
1#include "stm32f10x.h"
2
3
4#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
5 // #define SYSCLK_FREQ_HSE HSE_VALUE // 使用 HSE 作为系统时钟源,不进行倍频,最终频率 = HSE_VALUE
6 #define SYSCLK_FREQ_24MHz 24000000 // 定义 24MHz 系统时钟频率
7#else
8 // #define SYSCLK_FREQ_HSE HSE_VALUE // 使用 HSE 作为系统时钟源,不进行倍频,最终频率 = HSE_VALUE
9 // #define SYSCLK_FREQ_24MHz 24000000 // 定义 24MHz 系统时钟频率
10 // #define SYSCLK_FREQ_36MHz 36000000 // 定义 36MHz 系统时钟频率
11 // #define SYSCLK_FREQ_48MHz 48000000 // 定义 48MHz 系统时钟频率
12 // #define SYSCLK_FREQ_56MHz 56000000 // 定义 56MHz 系统时钟频率
13 #define SYSCLK_FREQ_72MHz 72000000 // 定义 72MHz 系统时钟频率
14#endif
15
16
17// 如果需要使用安装在STM3210E-EVAL板(STM32高密度和XL密度设备)
18// 或STM32100E-EVAL板(STM32高密度Value line设备)上的外部SRAM作为数据存储器,请取消注释以下行
19#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
20 // #define DATA_IN_ExtSRAM // 定义使用外部 SRAM
21#endif
22
23
24// 如果需要将向量表重定位到内部SRAM中,请取消注释以下行
25// #define VECT_TAB_SRAM // 定义向量表在SRAM中
26#define VECT_TAB_OFFSET 0x0 // 向量表基址偏移量字段,此值必须是0x200的倍数
27
28
29// 时钟定义
30#ifdef SYSCLK_FREQ_HSE
31 uint32_t SystemCoreClock = SYSCLK_FREQ_HSE;
32#elif defined SYSCLK_FREQ_24MHz
33 uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz;
34#elif defined SYSCLK_FREQ_36MHz
35 uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz;
36#elif defined SYSCLK_FREQ_48MHz
37 uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz;
38#elif defined SYSCLK_FREQ_56MHz
39 uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz;
40#elif defined SYSCLK_FREQ_72MHz
41 uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz;
42#else
43 uint32_t SystemCoreClock = HSI_VALUE; // 使用内部晶振频率作为系统时钟频率,HSI_VALUE 在 stm32f10x.h 被定义
44#endif
45
46
47__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; // AHB 预分频器表
48
49
50static void SetSysClock(void); // 设置系统时钟函数
51
52
53#ifdef SYSCLK_FREQ_HSE
54 static void SetSysClockToHSE(void); // 设置系统时钟为 HSE
55#elif defined SYSCLK_FREQ_24MHz
56 static void SetSysClockTo24(void); // 设置系统时钟为 24MHz
57#elif defined SYSCLK_FREQ_36MHz
58 static void SetSysClockTo36(void); // 设置系统时钟为 36MHz
59#elif defined SYSCLK_FREQ_48MHz
60 static void SetSysClockTo48(void); // 设置系统时钟为 48MHz
61#elif defined SYSCLK_FREQ_56MHz
62 static void SetSysClockTo56(void); // 设置系统时钟为 56MHz
63#elif defined SYSCLK_FREQ_72MHz
64 static void SetSysClockTo72(void); // 设置系统时钟为 72MHz
65#endif
66
67
68// DATA_IN_ExtSRAM 由用户定义,用于指示是否将数据段(全局变量、静态变量等)分配到外部 SRAM 中执行
69#ifdef DATA_IN_ExtSRAM
70 static void SystemInit_ExtMemCtl(void); // 外部存储器控制器初始化
71#endif
72
73
74void SystemInit (void)
75{
76 // 将 RCC 时钟配置重置为默认复位状态(用于调试目的)
77 // 设置 HSION 位,即使能 HSI (内部时钟源)
78 RCC->CR |= (uint32_t)0x00000001;
79
80 // 复位 SW、HPRE、PPRE1、PPRE2、ADCPRE 和 MCO位
81#ifndef STM32F10X_CL
82 RCC->CFGR &= (uint32_t)0xF8FF0000;
83#else
84 RCC->CFGR &= (uint32_t)0xF0FF0000;
85#endif
86
87 // 复位 HSEON、CSSON 和 PLLON 位
88 RCC->CR &= (uint32_t)0xFEF6FFFF;
89 // 复位HSEBYP位
90 RCC->CR &= (uint32_t)0xFFFBFFFF;
91 // 复位PLLSRC、PLLXTPRE、PLLMUL 和 USBPRE / OTGFSPRE 位
92 RCC->CFGR &= (uint32_t)0xFF80FFFF;
93
94#ifdef STM32F10X_CL
95 // 复位 PLL2ON 和 PLL3ON 位
96 RCC->CR &= (uint32_t)0xEBFFFFFF;
97 // 禁用所有中断并清除挂起位
98 RCC->CIR = 0x00FF0000;
99 // 复位CFGR2寄存器
100 RCC->CFGR2 = 0x00000000;
101#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
102 // 禁用所有中断并清除挂起位
103 RCC->CIR = 0x009F0000;
104 // 复位CFGR2寄存器
105 RCC->CFGR2 = 0x00000000;
106#else
107 // 禁用所有中断并清除挂起位
108 RCC->CIR = 0x009F0000;
109#endif
110
111#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
112 #ifdef DATA_IN_ExtSRAM
113 SystemInit_ExtMemCtl(); // 初始化外部存储器控制器
114 #endif
115#endif
116
117 // 配置系统时钟频率、HCLK、PCLK2 和 PCLK1 预分频器
118 // 配置 Flash 等待周期并启用预取缓冲区
119 SetSysClock();
120
121#ifdef VECT_TAB_SRAM
122 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; // 向量表重定位到内部 SRAM 中
123#else
124 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; // 向量表重定位到内部 FLASH 中
125#endif
126}
127
128
129// 根据时钟寄存器值更新 SystemCoreClock 变量
130void SystemCoreClockUpdate (void) {
131 省略...
132}
133
134
135// 设置系统时钟函数,被 SystemInit 函数调用
136static void SetSysClock(void)
137{
138#ifdef SYSCLK_FREQ_HSE
139 SetSysClockToHSE(); // 设置系统时钟为HSE
140#elif defined SYSCLK_FREQ_24MHz
141 SetSysClockTo24(); // 设置系统时钟为24MHz
142#elif defined SYSCLK_FREQ_36MHz
143 SetSysClockTo36(); // 设置系统时钟为36MHz
144#elif defined SYSCLK_FREQ_48MHz
145 SetSysClockTo48(); // 设置系统时钟为48MHz
146#elif defined SYSCLK_FREQ_56MHz
147 SetSysClockTo56(); // 设置系统时钟为56MHz
148#elif defined SYSCLK_FREQ_72MHz
149 SetSysClockTo72(); // 设置系统时钟为72MHz
150#endif // 如果上述定义均未启用,则HSI被用作系统时钟源(复位后的默认值)
151}
152
153
154#ifdef DATA_IN_ExtSRAM
155// 初始化外部存储器控制器
156void SystemInit_ExtMemCtl(void) {
157 省略...
158}
159#endif
160
161
162#ifdef SYSCLK_FREQ_HSE
163static void SetSysClockToHSE(void){ 省略.... }
164
165#elif defined SYSCLK_FREQ_24MHz
166static void SetSysClockTo24(void){ 省略.... }
167
168#elif defined SYSCLK_FREQ_36MHz
169static void SetSysClockTo36(void){ 省略.... }
170
171#elif defined SYSCLK_FREQ_48MHz
172static void SetSysClockTo48(void){ 省略.... }
173
174#elif defined SYSCLK_FREQ_56MHz
175static void SetSysClockTo56(void){ 省略.... }
176
177#elif defined SYSCLK_FREQ_72MHz
178static void SetSysClockTo72(void){ 省略.... }
179
180#endif
预定义宏 #
SYSCLK_FREQ_HSE HSE_VALUE : 使用 HSE 作为系统时钟源,不进行倍频
SYSCLK_FREQ_24MHz 24000000 : 定义 24MHz 系统时钟频率
SYSCLK_FREQ_36MHz 36000000 : 定义 36MHz 系统时钟频率
SYSCLK_FREQ_48MHz 48000000 : 定义 48MHz 系统时钟频率
SYSCLK_FREQ_56MHz 56000000 : 定义 56MHz 系统时钟频率
SYSCLK_FREQ_72MHz 72000000 : 定义 72MHz 系统时钟频率
VECT_TAB_SRAM : 定义向量表在 SRAM 中
VECT_TAB_OFFSET 0x0 : 向量表基址偏移量字段,此值必须是 0x200 的倍数
DATA_IN_ExtSRAM : 定义使用外部 SRAM
通过编译器参数配置时钟频率:
$ arm-none-eabi-gcc -D HSE_VALUE=8000000 -D SYSCLK_FREQ_48MHz=48000000
用户文件 #
以下文件在标准库的工程模板中可以找到。
标准库配置头文件 #
stm32f10x.h 中包含这个头文件。
1#ifndef __STM32F10x_CONF_H
2#define __STM32F10x_CONF_H
3
4#include "stm32f10x_adc.h"
5#include "stm32f10x_bkp.h"
6#include "stm32f10x_can.h"
7#include "stm32f10x_cec.h"
8#include "stm32f10x_crc.h"
9#include "stm32f10x_dac.h"
10#include "stm32f10x_dbgmcu.h"
11#include "stm32f10x_dma.h"
12#include "stm32f10x_exti.h"
13#include "stm32f10x_flash.h"
14#include "stm32f10x_fsmc.h"
15#include "stm32f10x_gpio.h"
16#include "stm32f10x_i2c.h"
17#include "stm32f10x_iwdg.h"
18#include "stm32f10x_pwr.h"
19#include "stm32f10x_rcc.h"
20#include "stm32f10x_rtc.h"
21#include "stm32f10x_sdio.h"
22#include "stm32f10x_spi.h"
23#include "stm32f10x_tim.h"
24#include "stm32f10x_usart.h"
25#include "stm32f10x_wwdg.h"
26#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
27
28// 当启用 USE_FULL_ASSERT 后,标准库函数会对输入参数进行严格的检查
29// #define USE_FULL_ASSERT 1
30
31#ifdef USE_FULL_ASSERT
32 #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
33 void assert_failed(uint8_t* file, uint32_t line);
34#else
35 #define assert_param(expr) ((void)0)
36#endif
37
38#endif
中断函数头文件 #
这会覆盖启动文件中的中断函数。
1#ifndef __STM32F10x_IT_H
2#define __STM32F10x_IT_H
3
4#ifdef __cplusplus
5 extern "C" {
6#endif
7
8#include "stm32f10x.h"
9
10void NMI_Handler(void);
11void HardFault_Handler(void);
12void MemManage_Handler(void);
13void BusFault_Handler(void);
14void UsageFault_Handler(void);
15void SVC_Handler(void);
16void DebugMon_Handler(void);
17void PendSV_Handler(void);
18void SysTick_Handler(void);
19
20#ifdef __cplusplus
21}
22#endif
23
24#endif
中断函数源文件 #
1#include "stm32f10x_it.h"
2
3void NMI_Handler(void)
4{
5}
6
7void HardFault_Handler(void)
8{
9 while (1)
10 {
11 }
12}
13
14void MemManage_Handler(void)
15{
16 while (1)
17 {
18 }
19}
20
21void BusFault_Handler(void)
22{
23 while (1)
24 {
25 }
26}
27
28void UsageFault_Handler(void)
29{
30 while (1)
31 {
32 }
33}
34
35void SVC_Handler(void)
36{
37}
38
39void DebugMon_Handler(void)
40{
41}
42
43void PendSV_Handler(void)
44{
45}
46
47void SysTick_Handler(void)
48{
49}
文件关系图 #
GCC 链接脚本 #
1/* 入口点 - 程序启动后执行的第一条指令地址 */
2ENTRY(Reset_Handler)
3
4/* 初始化栈顶地址 = RAM 区起始地址 + RAM 区大小 */
5_estack = ORIGIN(RAM) + LENGTH(RAM);
6
7/* 所需的最小堆大小 */
8_Min_Heap_Size = 0x1000;
9
10/* 所需的最小栈大小 */
11_Min_Stack_Size = 0x400;
12
13/* 指定存储器区域 */
14MEMORY
15{
16 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K /* RAM: 可执行(x)、可读(r)、可写(w),起始地址0x20000000,长度64KB */
17 FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K /* FLASH: 只读(r)、可执行(x),起始地址0x08000000,长度512KB */
18}
19
20/* 定义输出段 */
21SECTIONS
22{
23 /* 创建一个 .isr_vector 段,用于存放向量表 */
24 .isr_vector :
25 {
26 . = ALIGN(4); /* 4 字节对齐,地址是 4 的倍数 */
27 KEEP(*(.isr_vector)) /* *(.isr_vector) 表示匹配所有 .isr_vector 段;KEEP 表示保留匹配的段(防止被优化掉),.isr_vector 符号在启动文件被中定义(即向量表) */
28 . = ALIGN(4);
29 } >FLASH /* 输出到 FLASH */
30
31 /* 创建一个 .text 段 */
32 .text :
33 {
34 . = ALIGN(4);
35 *(.text) /* 匹配所有 .text 段 */
36 *(.text*) /* 匹配所有以 .text 开头的段 */
37 *(.glue_7)
38 *(.glue_7t)
39 *(.eh_frame)
40
41 KEEP (*(.init))
42 KEEP (*(.fini))
43
44 . = ALIGN(4);
45 _etext = .; /* 定义 .text 段结束位置的全局符号 */
46 } >FLASH /* 输出到 FLASH */
47
48 /* 创建一个 .rodata 段 */
49 .rodata :
50 {
51 . = ALIGN(4);
52 *(.rodata)
53 *(.rodata*)
54 . = ALIGN(4);
55 } >FLASH /* 输出到 FLASH */
56
57 .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
58 .ARM : {
59 __exidx_start = .;
60 *(.ARM.exidx*)
61 __exidx_end = .;
62 } >FLASH
63
64 .preinit_array :
65 {
66 PROVIDE_HIDDEN (__preinit_array_start = .);
67 KEEP (*(.preinit_array*))
68 PROVIDE_HIDDEN (__preinit_array_end = .);
69 } >FLASH
70 .init_array :
71 {
72 PROVIDE_HIDDEN (__init_array_start = .);
73 KEEP (*(SORT(.init_array.*)))
74 KEEP (*(.init_array*))
75 PROVIDE_HIDDEN (__init_array_end = .);
76 } >FLASH
77 .fini_array :
78 {
79 PROVIDE_HIDDEN (__fini_array_start = .);
80 KEEP (*(SORT(.fini_array.*)))
81 KEEP (*(.fini_array*))
82 PROVIDE_HIDDEN (__fini_array_end = .);
83 } >FLASH
84
85 _sidata = LOADADDR(.data); /* .data 段在 FLASH 中的起始地址 */
86
87 /* 创建一个 .data 段 */
88 .data :
89 {
90 . = ALIGN(4);
91 _sdata = .; /* .data 段在 RAM 中的起始地址 */
92 *(.data)
93 *(.data*)
94
95 . = ALIGN(4);
96 _edata = .; /* .data 段在 RAM 中的结束地址 */
97 } >RAM AT> FLASH /* VMA 在 RAM 区,LMA 在 FLASH 区 */
98
99
100 . = ALIGN(4);
101
102 /* 创建一个 .bss 段 */
103 .bss :
104 {
105 _sbss = .; /* .bss 在 RAM 中的起始地址 */
106 __bss_start__ = _sbss;
107 *(.bss)
108 *(.bss*)
109 *(COMMON)
110
111 . = ALIGN(4);
112 _ebss = .; /* .bss 在 RAM 中的结束地址 */
113 __bss_end__ = _ebss;
114 } >RAM /* 输出到 RAM */
115
116
117 /* 用户堆栈段,用于检查剩余 RAM 是否足够 */
118 ._user_heap_stack :
119 {
120 . = ALIGN(8);
121 PROVIDE ( end = . );
122 PROVIDE ( _end = . );
123 . = . + _Min_Heap_Size;
124 . = . + _Min_Stack_Size;
125 . = ALIGN(8);
126 } >RAM
127
128 /* 丢弃标准库中的某些信息(避免链接不需要的库内容) */
129 /DISCARD/ :
130 {
131 libc.a ( * ) /* 丢弃 libc 库所有内容 */
132 libm.a ( * ) /* 丢弃 libm 库所有内容 */
133 libgcc.a ( * ) /* 丢弃 libgcc 库所有内容 */
134 }
135
136 /* ARM 属性段(通常为空,但保留结构) */
137 .ARM.attributes 0 : { *(.ARM.attributes) }
138}
CM3 为满减栈,压栈时:先移动指针再压入数据。
STM32F1 启动流程 #
上电后, CPU 固定从 0x00000000 读取初始栈顶地址到 SP ,从 0x00000004 读取入口程序地址到 PC 。
STM32 可通过配置 BOOT0 和 BOOT1 引脚,将从 0x00000000 地址开始的一块区域(别名区)映射到不同存储器的地址空间,以实现从不同存储器启动。
| BOOT0 | BOOT1 | 启动模式 |
|---|---|---|
| 0 | X | 从 FLASH 启动 |
| 1 | 0 | 从系统存储器启动(ISP 编程) |
| 1 | 1 | 从 SRAM 启动 |
从 FLASH 启动 #
从 FLASH 启动时,地址 0x00000000 被映射到 0x08000000 , CPU 就能从 0x00000000 访问 FLASH 中的向量表从而运行程序。
假设初始栈顶地址为 0x20010000(64K) ,入口函数地址为 0x08000400 ,启动流程如下:
入口函数地址
0x08000401最后一位是 1 表示 thumb 状态,实际地址为0x08000400。
从系统存储器启动 #
从 System Memory 启动时,地址 0x00000000 被映射到 0x1FFF0000 ,此区域存储的是厂商内置的 BootLoader 程序(闭源),
主要功能是从串口下载用户程序到 Flash (ISP 编程)。
从 SRAM 启动 #
从 SRAM 启动时,理论上应该将地址 0x00000000 映射到 0x20000000 ,但对于 STM32F1 系列实际情况并非如此。
对于 STM32F103ZET6 , 从 SRAM 启动时,0x00000000 会被映射到一块内存极小的区域,大约在 0x1FFFF000 附近或略低,仅 16 字节,内容如下:
20005000 200001E1 20000004 20000004
第一个字:初始栈顶地址 0x20005000 (20K)。
第二个字:入口程序地址 0x200001E1 ,最后一位表示 thumb ,实际是 0x200001E0,相对 0x20000000 偏移 0x1E0 。
对于不同容量的产品,其偏移值也有所不同,参考 GCC 的启动文件:
startup_stm32f10x_ld.s: .word BootRAM /* 0x108 */
startup_stm32f10x_md.s: .word BootRAM /* 0x108 */
startup_stm32f10x_hd.s: .word BootRAM /* 0x1E0 */
startup_stm32f10x_xl.s: .word BootRAM /* 0x1E0 */
startup_stm32f10x_cl.s: .word BootRAM /* 0x1E0 */
startup_stm32f10x_ld_vl.s: .word BootRAM /* 0x01CC */
startup_stm32f10x_md_vl.s: .word BootRAM /* 0x01CC */
startup_stm32f10x_hd_vl.s: .word BootRAM /* 0x1E0 */
第三和第四个字分别是 NMI 和 HardFault 向量。它们的最低位为 0 (CM3 不支持 ARM 状态),因此当 VTOR 仍为零时,若发生这些异常中的任何一个,处理器将触发双重异常。
根据 GCC 启动文件 与 GCC 链接脚本 ,地址 0x200001E0 位置是向量表中 BootRAM 所在,且 BootRAM = 0xF1E0F85F ,
0xF1E0F85F 这个值实际是汇编指令 LDR.W PC, [PC, #-0x1E0] 的机器码,作用是 PC = *(PC - 0x1E0) ,指令执行后的 PC 指向真正的入口程序地址,
详情参考
这篇帖子
。
正常从 SRAM 启动,应该需要以下设置(未验证):
- 配置 BOOT0 、BOOT1 引脚均为高电平。
- 设置链接脚本中的 RAM 区起始地址,与 RAM 区大小。
- 设置链接脚本中的 FLASH 区的起始地址为
0x20000000,与 FLASH 区大小。 - 从上图的流程中可以看出,用户向量表中的
_estack栈初始地址没有起到作用,初始栈顶被强制设置为0x20005000, 所以用户需要在 main 函数调用前设置 SP ,可以使用 core_cm3.c 中的__set_MSP函数。 - 设置向量表偏移寄存器
SCB->VTOR的值,可使用 system_stm32f10x.c 中的VECT_TAB_SRAM宏,如下:
// 如果需要将向量表重定位到内部SRAM中,请取消注释以下行
// #define VECT_TAB_SRAM // 定义向量表在SRAM中
#define VECT_TAB_OFFSET 0x0 // 向量表基址偏移量字段,此值必须是0x200的倍数
void SystemInit (void) {
省略...
#ifdef VECT_TAB_SRAM
// SRAM_BASE 在 stm32f10x.h 中定义 0x20000000
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; // 向量表重定位到内部 SRAM 中
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; // 向量表重定位到内部 FLASH 中
#endif
}
对于这种奇怪的启动方式,似乎主要局限于 F103/5/7 系列,较新的芯片应该是正常的,还是参考 这篇帖子 。
另外,我在野火 STM32 文档中也找到了印证,参考 在SRAM中调试代码 一文。 在此文中,单片机复位后 PC 和 SP 指针初始值异常(如下图),恰好印证了上述的启动流程。


除此之外,野火 STM32 文档中使用的 IDE 是 Keil ,默认是 ARMCC 编译器,该编译器的启动文件中并没有定义 BootRAM ,
这也是他们 SRAM 调试失败的原因之一。