STM32F207笔记
/******************************** NVIC ***********************************/
主要特征:
拥有81个中断源 //不包括16个内部异常;标准M3可最多拥有240个中断源
16级可编程优先级 //标准M3可最多拥有128级可编程优先级
优先级又被分为抢占优先级和亚优先级两段
NVIC模块寄存器地址列表: //NVIC模块基址0xE000E100
地址偏移量 寄存器
0x000 NVIC_ISER0 //中断使能/除能寄存器数组,标准M3共有8对(32*8=256)(不用满),STM32F2只用3对(32*3=96)(不用满)
0x004 NVIC_ISER1
0x008 NVIC_ISER2
RESERVED
0x080 NVIC_ICER0
0x084 NVIC_ICER1
0x088 NVIC_ICER2
RESERVED
0x100 NVIC_ISPR0 //中断悬起/解悬寄存器数组,标准M3共有8对(32*8=256)(不用满),STM32F2只用3对(32*3=96)(不用满)
0x104 NVIC_ISPR1
0x108 NVIC_ISPR2
RESERVED
0x180 NVIC_ICPR0
0x184 NVIC_ICPR1
0x188 NVIC_ICPR0
RESERVED
0x200 NVIC_IABR0 //中断活动状态寄存器数组,标准M3共有8个(32*8=256)(不用满),STM32F2只用3个(32*3=96)(不用满)
0x204 NVIC_IABR1
0x208 NVIC_IABR2
RESERVED
0x300~0x320 NVIC_IPR0~NVIC_IPR80 //中断优先级寄存器数组,标准M3共有240个,STM32F2只有81个
1个特例寄存器:
NVIC_STIR:软件触发中断寄存器 //地址:0xE000EF00,该功能需要在SCB->CCR中使能
//用于触发外部中断,[7:0]位有效,对应0~239号中断
异常和中断优先级配置:
1. 除了NMI,其余异常和中断的优先级均可自由编程 //标准M3还要除了复位、硬fault这两个异常
2. 异常和中断优先级寄存器NVIC_IPRn只使用高4位,所以拥有16级可编程优先级: //标准M3最少使用3位,MSB对齐
0x00;0x10;0x20;0x30;0x40;0x50;0x60;0x70;0x80;0x90;0xa0;0xb0;0xc0;0xd0;0xe0;0xf0
3. 16级优先级又被分为抢占优先级和亚优先级,分法跟SCB模块中AIRCR寄存器内的“优先级组”段位设置有关,详见PM
4. 抢占优先级的方法即实现了中断嵌套机制
5. 当抢占优先级相同时,响应亚优先级最高的异常或中断,但不会再发生抢占
6. 异常和中断优先级寄存器都可按字节读写
7. 固件库中misc.c中NVIC_Init()函数存在小BUG:由于SCB_AIRCR寄存器中“优先级分组”段复位值为0b000,所以调用该函数前必须先设定优先级分组值
8. 不同中断源优先级可以设为相同!!!
/******************************** SCB ***********************************/
SCB模块寄存器地址列表: //SCB模块基址0xE000ED00
地址偏移量 寄存器
0x00 SCB_CPUID
0x04 SCB_ICSR //中断控制及状态寄存器,主要用于悬起/解悬系统异常
0x08 SCB_VTOR //向量表偏移量寄存器,包含向量表基址(也就是RAM/ROM地址中选择) + 偏移值(必须确保是0x200的倍数)
//STM32F2默认值为0x08000000,正好对在ROM基址上
0x0C SCB_AIRCR //中断和复位控制寄存器,任何对该寄存器的写入,都必须同时写入0x05FA(访问钥匙)主要用于配置优先级分组
0x10 SCB_SCR //系统控制寄存器,跟睡眠/唤醒相关
0x14 SCB_CCR //配置和控制寄存器,主要跟异常响应相关
//注意点,STM32F2此处跟F1存在区别:复位值为0x00000200,即默认开启双字对齐管理机制
0x18 SCB_SHPR1 //系统异常优先级寄存器1~3,STM32F2使用了6个系统异常
0x1C SCB_SHPR2
0x20 SCB_SHPR3
0x24 SCB_SHCRS //系统异常控制和状态寄存器,功能类似于NVIC_IABRn
0x28 SCB_CFSR //以下几个暂时不管
0x2C SCB_HFSR
0x34 SCB_MMAR
0x38 SCB_BFAR
/******************************** 特殊功能寄存器组 ***********************************/
CONTROL:控制寄存器
仅当在特权级下操作时才允许写该寄存器 !!!
1. CONTROL[0]: 用于选择处理器模式为特权级/非特权级
特权级非特权级切换流程如下:
特权级——————————>非特权级———————————————————————————————————>特权级
CONTROL寄存器 |= 0x01 调用系统服务呼叫指令SVC产生一个SVC异常,从而从thread模式进入handler模式,
而handler模式永远是特权级,也就可以改写CONTROL寄存器,真正回到特权级
2. CONTROL[1]: 用于选择当前使用哪个堆栈指针
仅当在线程模式下操作时才允许写该位,而handler模式永远是MSP堆栈,该位写入无效
MSP/PSP切换流程如下:
MSP(特权级、线程模式)——————————————>PSP(特权级、线程模式)——————————————> MSP(特权级、线程模式)
线程模式下操作CONTROL[1] / \ 线程模式下操作CONTROL[1]
/ \
操作CONTROL[0]/ \触发中断/异常
/ \
PSP(非特权级、线程模式) MSP(特权级、handler模式)
/ \
调用SVC,在handler下改写CONTROL[0]/ \ 中断/异常返回
/ \
MSP(特权级、线程模式)<——————————————PSP(特权级、线程模式) PSP(特权级、线程模式) ————————————> MSP(特权级、线程模式)
线程模式下操作CONTROL[1] 线程模式下操作CONTROL[1]
操作模式总结:
1. 复位后处理器进入线程模式+特权级
2. 线程模式+非特权级下,对SCB、NVIC、Systick、MPU模块的访问被拒绝;同时不能用MSR访问特殊功能寄存器(APSR例外)
/******************************** Flash ***********************************/
主要特征:
1. 1Mbyte容量
2. 128bits位宽读取
3. 字节、半字、字、双字写入
4. 可按扇区/块擦除
5. 存储区块架构:
主存储区: 扇区 基址 尺寸
Sector0 0x08000000 16kbytes
Sector1 0x08004000 16kbytes
Sector2 0x08008000 16kbytes
Sector3 0x0800C000 16kbytes
Sector4 0x08010000 64kbytes
Sector5 0x08020000 128kbytes
Sector6 0x08040000 128kbytes
Sector7 0x08060000 128kbytes
Sector8 0x08080000 128kbytes
Sector9 0x080A0000 128kbytes
Sector10 0x080C0000 128kbytes
Sector11 0x080E0000 128kbytes
系统存储区: 0x1FFF0000 30kbytes
一次性编程区: 0x1FFF7800 528bytes
Flash配置字节: 0x1FFFC000 16bytes
CPU时钟和Flash读取延时关系:根据时钟频率和供电电压需要在FLASH_ACR寄存器配置相应的延迟LATENCY,详见RM手册。
复位时FLASH_ACR中默认配置为16MHZ时钟和0延迟。
更改时钟频率的标准顺序:
1. 增加时钟频率:
修改FLASH_ACR寄存器中的延时位LATENCY
确认延时是否修改成功
修改时钟源/预分频
确认是否修改成功(看RCC_CFGR中SWS标志位)
2. 减小时钟频率:
修改时钟源/预分频
修改延时位LATENCY
确认延时是否修改成功
FLASH寄存器:
FLASH_ACR: FLASH访问控制寄存器 //用于设置访问延时
FLASH_KEYR: 密钥寄存器 //用于FLASH解锁
FLASH_OPTKEYR: 配置字节密钥寄存器
FLASH_SR: FLASH状态寄存器 //FLASH相关标志位
FLASH_CR: FLASH控制寄存器 //FLASH上锁、编程设置
FLASH_OPTCR: 配置字节控制寄存器
FLASH操作:
1. 解锁/上锁
对FLASH进行任何编程操作前都必须先进行解锁;
完成FLASH编程后建议上锁
2. 写入单位设置
写入单位跟供电电压和Vpp有关,详见RM手册
此设置必须在任何擦除/编程操作前进行
3. 擦除
扇擦除:
擦除前确认当前无FLASH操作
扇擦除位使能、选择擦除扇区
开始擦除
等待擦除完毕
整块擦除:
擦除前确认当前无FLASH操作
块擦除位使能
开始擦除
等待擦除完毕
4. 写入
写入前确认当前FLASH无操作
写入位使能
根据写入单位设置执行写入
等待写入完毕
/******************************** EXTI ***********************************/
主要特征:
拥有23个边沿检测中断/事件控制器 //该模块类似于I/O中断
可以检测脉冲宽度低于APB2时钟宽度的外部信号
EXTI寄存器:
EXTI_IMR: 中断屏蔽寄存器
EXTI_EMR: 事件屏蔽寄存器
EXTI_RTSR: 上升沿触发选择寄存器
EXTI_FTSR: 下降沿触发选择寄存器
EXTI_SWIER: 软件中断事件寄存器
EXTI_PR: 挂起寄存器
初始化流程:
1. 使能GPIOx端口时钟
2. 使能SYSCFG模块时钟
3. 配置GPIOx的某个管脚n(n:0~15)为输入模式(无上下拉)
4. 将EXTI的n号中断线跟管脚n相连
5. 配置EXTI的n号中断线
6. 配置EXTI的n号中断的优先级并使能中断
/******************************** NVIC ***********************************/
主要特征:
拥有81个中断源 //不包括16个内部异常;标准M3可最多拥有240个中断源
16级可编程优先级 //标准M3可最多拥有128级可编程优先级
优先级又被分为抢占优先级和亚优先级两段
NVIC模块寄存器地址列表: //NVIC模块基址0xE000E100
地址偏移量 寄存器
0x000 NVIC_ISER0 //中断使能/除能寄存器数组,标准M3共有8对(32*8=256)(不用满),STM32F2只用3对(32*3=96)(不用满)
0x004 NVIC_ISER1
0x008 NVIC_ISER2
RESERVED
0x080 NVIC_ICER0
0x084 NVIC_ICER1
0x088 NVIC_ICER2
RESERVED
0x100 NVIC_ISPR0 //中断悬起/解悬寄存器数组,标准M3共有8对(32*8=256)(不用满),STM32F2只用3对(32*3=96)(不用满)
0x104 NVIC_ISPR1
0x108 NVIC_ISPR2
RESERVED
0x180 NVIC_ICPR0
0x184 NVIC_ICPR1
0x188 NVIC_ICPR0
RESERVED
0x200 NVIC_IABR0 //中断活动状态寄存器数组,标准M3共有8个(32*8=256)(不用满),STM32F2只用3个(32*3=96)(不用满)
0x204 NVIC_IABR1
0x208 NVIC_IABR2
RESERVED
0x300~0x320 NVIC_IPR0~NVIC_IPR80 //中断优先级寄存器数组,标准M3共有240个,STM32F2只有81个
1个特例寄存器:
NVIC_STIR:软件触发中断寄存器 //地址:0xE000EF00,该功能需要在SCB->CCR中使能
//用于触发外部中断,[7:0]位有效,对应0~239号中断
异常和中断优先级配置:
1. 除了NMI,其余异常和中断的优先级均可自由编程 //标准M3还要除了复位、硬fault这两个异常
2. 异常和中断优先级寄存器NVIC_IPRn只使用高4位,所以拥有16级可编程优先级: //标准M3最少使用3位,MSB对齐
0x00;0x10;0x20;0x30;0x40;0x50;0x60;0x70;0x80;0x90;0xa0;0xb0;0xc0;0xd0;0xe0;0xf0
3. 16级优先级又被分为抢占优先级和亚优先级,分法跟SCB模块中AIRCR寄存器内的“优先级组”段位设置有关,详见PM
4. 抢占优先级的方法即实现了中断嵌套机制
5. 当抢占优先级相同时,响应亚优先级最高的异常或中断,但不会再发生抢占
6. 异常和中断优先级寄存器都可按字节读写
7. 固件库中misc.c中NVIC_Init()函数存在小BUG:由于SCB_AIRCR寄存器中“优先级分组”段复位值为0b000,所以调用该函数前必须先设定优先级分组值
8. 不同中断源优先级可以设为相同!!!
/******************************** SCB ***********************************/
SCB模块寄存器地址列表: //SCB模块基址0xE000ED00
地址偏移量 寄存器
0x00 SCB_CPUID
0x04 SCB_ICSR //中断控制及状态寄存器,主要用于悬起/解悬系统异常
0x08 SCB_VTOR //向量表偏移量寄存器,包含向量表基址(也就是RAM/ROM地址中选择) + 偏移值(必须确保是0x200的倍数)
//STM32F2默认值为0x08000000,正好对在ROM基址上
0x0C SCB_AIRCR //中断和复位控制寄存器,任何对该寄存器的写入,都必须同时写入0x05FA(访问钥匙)主要用于配置优先级分组
0x10 SCB_SCR //系统控制寄存器,跟睡眠/唤醒相关
0x14 SCB_CCR //配置和控制寄存器,主要跟异常响应相关
//注意点,STM32F2此处跟F1存在区别:复位值为0x00000200,即默认开启双字对齐管理机制
0x18 SCB_SHPR1 //系统异常优先级寄存器1~3,STM32F2使用了6个系统异常
0x1C SCB_SHPR2
0x20 SCB_SHPR3
0x24 SCB_SHCRS //系统异常控制和状态寄存器,功能类似于NVIC_IABRn
0x28 SCB_CFSR //以下几个暂时不管
0x2C SCB_HFSR
0x34 SCB_MMAR
0x38 SCB_BFAR
/******************************** 特殊功能寄存器组 ***********************************/
CONTROL:控制寄存器
仅当在特权级下操作时才允许写该寄存器 !!!
1. CONTROL[0]: 用于选择处理器模式为特权级/非特权级
特权级非特权级切换流程如下:
特权级——————————>非特权级———————————————————————————————————>特权级
CONTROL寄存器 |= 0x01 调用系统服务呼叫指令SVC产生一个SVC异常,从而从thread模式进入handler模式,
而handler模式永远是特权级,也就可以改写CONTROL寄存器,真正回到特权级
2. CONTROL[1]: 用于选择当前使用哪个堆栈指针
仅当在线程模式下操作时才允许写该位,而handler模式永远是MSP堆栈,该位写入无效
MSP/PSP切换流程如下:
MSP(特权级、线程模式)——————————————>PSP(特权级、线程模式)——————————————> MSP(特权级、线程模式)
线程模式下操作CONTROL[1] / \ 线程模式下操作CONTROL[1]
/ \
操作CONTROL[0]/ \触发中断/异常
/ \
PSP(非特权级、线程模式) MSP(特权级、handler模式)
/ \
调用SVC,在handler下改写CONTROL[0]/ \ 中断/异常返回
/ \
MSP(特权级、线程模式)<——————————————PSP(特权级、线程模式) PSP(特权级、线程模式) ————————————> MSP(特权级、线程模式)
线程模式下操作CONTROL[1] 线程模式下操作CONTROL[1]
操作模式总结:
1. 复位后处理器进入线程模式+特权级
2. 线程模式+非特权级下,对SCB、NVIC、Systick、MPU模块的访问被拒绝;同时不能用MSR访问特殊功能寄存器(APSR例外)
/******************************** Flash ***********************************/
主要特征:
1. 1Mbyte容量
2. 128bits位宽读取
3. 字节、半字、字、双字写入
4. 可按扇区/块擦除
5. 存储区块架构:
主存储区: 扇区 基址 尺寸
Sector0 0x08000000 16kbytes
Sector1 0x08004000 16kbytes
Sector2 0x08008000 16kbytes
Sector3 0x0800C000 16kbytes
Sector4 0x08010000 64kbytes
Sector5 0x08020000 128kbytes
Sector6 0x08040000 128kbytes
Sector7 0x08060000 128kbytes
Sector8 0x08080000 128kbytes
Sector9 0x080A0000 128kbytes
Sector10 0x080C0000 128kbytes
Sector11 0x080E0000 128kbytes
系统存储区: 0x1FFF0000 30kbytes
一次性编程区: 0x1FFF7800 528bytes
Flash配置字节: 0x1FFFC000 16bytes
CPU时钟和Flash读取延时关系:根据时钟频率和供电电压需要在FLASH_ACR寄存器配置相应的延迟LATENCY,详见RM手册。
复位时FLASH_ACR中默认配置为16MHZ时钟和0延迟。
更改时钟频率的标准顺序:
1. 增加时钟频率:
修改FLASH_ACR寄存器中的延时位LATENCY
确认延时是否修改成功
修改时钟源/预分频
确认是否修改成功(看RCC_CFGR中SWS标志位)
2. 减小时钟频率:
修改时钟源/预分频
修改延时位LATENCY
确认延时是否修改成功
FLASH寄存器:
FLASH_ACR: FLASH访问控制寄存器 //用于设置访问延时
FLASH_KEYR: 密钥寄存器 //用于FLASH解锁
FLASH_OPTKEYR: 配置字节密钥寄存器
FLASH_SR: FLASH状态寄存器 //FLASH相关标志位
FLASH_CR: FLASH控制寄存器 //FLASH上锁、编程设置
FLASH_OPTCR: 配置字节控制寄存器
FLASH操作:
1. 解锁/上锁
对FLASH进行任何编程操作前都必须先进行解锁;
完成FLASH编程后建议上锁
2. 写入单位设置
写入单位跟供电电压和Vpp有关,详见RM手册
此设置必须在任何擦除/编程操作前进行
3. 擦除
扇擦除:
擦除前确认当前无FLASH操作
扇擦除位使能、选择擦除扇区
开始擦除
等待擦除完毕
整块擦除:
擦除前确认当前无FLASH操作
块擦除位使能
开始擦除
等待擦除完毕
4. 写入
写入前确认当前FLASH无操作
写入位使能
根据写入单位设置执行写入
等待写入完毕
/******************************** EXTI ***********************************/
主要特征:
拥有23个边沿检测中断/事件控制器 //该模块类似于I/O中断
可以检测脉冲宽度低于APB2时钟宽度的外部信号
EXTI寄存器:
EXTI_IMR: 中断屏蔽寄存器
EXTI_EMR: 事件屏蔽寄存器
EXTI_RTSR: 上升沿触发选择寄存器
EXTI_FTSR: 下降沿触发选择寄存器
EXTI_SWIER: 软件中断事件寄存器
EXTI_PR: 挂起寄存器
初始化流程:
1. 使能GPIOx端口时钟
2. 使能SYSCFG模块时钟
3. 配置GPIOx的某个管脚n(n:0~15)为输入模式(无上下拉)
4. 将EXTI的n号中断线跟管脚n相连
5. 配置EXTI的n号中断线
6. 配置EXTI的n号中断的优先级并使能中断