1.STM32的存储器映像
32通常是写1 清零的
Cortex™-M3内核DCode总线(D-bus)数据总线,和系统总线(S-bus)
AHB(Advanced High performance Bus)系统总线和APB(Advanced Peripheral Bus)
DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。当CPU初始化这个传输动作,传输动作本身是由DMA控制器来实现和完成的。DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场过程,通过硬件为RAM和IO设备开辟一条直接传输数据的通道,使得CPU的效率大大提高。
STM32是32位CPU,数据总线是32位
STM32的地址总线是32位的(地址总线是32位的不是由数据总线是32位决定的)
STM32可以访问的地址容量是:4G(2的32次方Byte)
stm32用不完4GB的空间,逻辑上的地址和实际的地址
存储器映像就是告诉我们STM32设计时是如何使用这4GB的逻辑地址的 很有必要了解
1.1 存储器映像图
ARM的内存与IO统一编址的
STM32的实际地址安排:
0x00000000 - 0x07FFFFFF 128MB 映射区 不同的地方启动(不同的启动方式),映射到不同的范围
0x08000000 - 0x0807FFFF 512KB Flash 外部flash
0x1FFFF000 - 0x1FFFF7FF 2KB System Memory 系统存储区
0x1FFFF800 - 0x1FFFF80F 16B option bytes
- 1 byte (B) = 8 bits (b) 字节=8个二进制位
- 1 Kilobyte(K/KB)=2^10 bytes=1,024 bytes 千字节
- 1 Megabyte(M/MB)=2^20 bytes=1,048,576 bytes 兆字节
- 1 Gigabyte(G/GB)=2^30 bytes=1,073,741,824 bytes 千兆字节
- 1 Terabyte(T/TB)=2^40 bytes=1,099,511,627,776 bytes吉字节
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 16
2^5 = 32
2^6 = 64
2^7 = 128
2^8 = 256
2^9 = 512
2 ^ 10 = 1024
2.stm32的位段操作
bitband,有时翻译为位带操作
别名存储器区, 字(32位) (内存在逻辑地址的区域)
映射
位段存储区, 位
1字节(byte) = 8位(bit)
在16位的系统中(比如8086微机) 1字 (word)= 2字节(byte)= 16(bit)
在32位的系统中(比如win32) 1字(word)= 4字节(byte)=32(bit)
在64位的系统中(比如win64)1字(word)= 8字节(byte)=64(bit)
为什么要有位带操作?因为STM32本身只支持8、16、32位的操作,而不支持位操作。
但是我们实际编程中有对1位单独操作的需求。一般是这么做的:因为STM32不支持位操作,所以我们需要对32位进行整体操作。我们一般是读出整个的32位,然后对其中一位做操作后再整体32位写回去。这么做是可以的,但是效率低。
如何改进效率?
答案肯定是想一个办法能够直接一次性修改那一位同时还不影响其他位。如果硬件不支持是没办法的,除非硬件给你支持位操作。
而ARM又不支持位操作,所以发明了位带操作来替代。位带操作的思路是不让你直接单独操作这一位,而是把这一位给你映射到别的某个地方的32位,然后你在别的地方操作那个32位就相当于是操作这里的这1位。
如何操作?
内存地址是以字节为单位的
AliasAddr= 0x22000000 + ((A‐0x20000000)8+n)4 =0x22000000+(A-0x20000000)32 + n4
http://www.elecfans.com/d/1153602.html
别名存储器区大小等于位段存储器区大小的32倍。
位带操作的核心问题就是:如何由位段存储器区地址,计算出别名存储器区的地址
3.启动模式
(1)启动模式:研究STM32上电复位后从哪里去执行程序的问题
序号 | BOOT0 | BOOT1 | 启动模式 | 说明 |
---|---|---|---|---|
1 | 0 | X | 用户闪存存储器 | 用户闪存存储器,也就是 FLASH启动 |
2 | 1 | 0 | 系统存储器 | 系统存储器 启动,用于 串口下载 |
3 | 1 | 1 | SRAM启动 | SRAM 启动,用于在 SRAM中调试代码 |
(2)用户闪存存储器区是给我们设计来放置用户写的代码的,我们程序员写的代码烧录时就被烧录到这里了,正常工作状态下就要把STM32设置为从这里启动。
(3)系统存储器区在非常规情况下用,用来实现ISP功能的。
(4)内嵌SRAM区,这种也是非常规的,用来实现调试器调试功能的。
3.1 ISP和IAP
(1)ISP就是in-system programming(在系统烧录,在系统编程)。以前要烧录代码bin文件到单片机内部的flash中是需要借助专用的烧录器的,比较麻烦。后来我们就需要一种不用烧录器也不用把单片机从板子上卸下来的烧录方法,这种方法就是ISP。一般ISP都是PC机通过串口把bin/hex文件直接isp到单片机内部flash中。烧录的方法存储在system momery,然后下载到FLASH
(2)IAP就是in-application programming(在应用编程,在应用烧录,在线升级),IAP的核心是用户需要在自己的应用程序中去操作单片机内部flash的控制器的寄存器,实现对内部flash的烧录功能。然后IAP的时候用户程序通过串口(usb、ethernet)来接收PC发送过来的bin/hex文件,然后将之烧录到内部flash中去完成IAP。完成后再次启动后就会从用户存储器区执行,更新就会起效果。一般实现iAP需要人为的将用户存储器区分为2部分:bootloader(启动代码)+app(功能程序) bootloader=>app
4.电源管理系统
STM32F10xxx有三种低功耗模式:
● 睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时
钟(SysTick)等仍在运行)
● 停止模式(所有的时钟都已停止)
● 待机模式(1.8V电源关闭)
此外,在运行模式下,可以通过以下方式中的一种降低功耗:
● 降低系统时钟
● 关闭APB和AHB总线上未被使用的外设时钟。
睡眠SLEEP模式:CPU停,外设运行,唤醒源为所有中断
停机STOP模式:CPU停,时钟停,外设停,只有SRAM和寄存器还能保持原来的值,唤醒源是外部中断
待机SUSPEND模式:CPU停、外设停、时钟停、SRM和寄存器停(相当于整个都断电关机了),只有备份寄存器和待机电路还能工作,唤醒源:WKUP引脚的上升沿、 RTC闹钟、 NRST引脚上外部复位、 IWDG复位
5.复位和时钟控制
5.1 复位
STM32F10xxx支持三种复位形式,分别为系统复位、上电复位和备份区域复位(低功耗)。
除了时钟控制器的RCC_CSR寄存器中的复位标志位和备份区域中的寄存器(见图4)以外,系统复位将复位所有寄存器至它们的复位状态。
当发生以下任一事件时,产生一个系统复位:
1. NRST引脚上的低电平(外部复位) N低电平有效 复位按键
2. 窗口看门狗计数终止(WWDG复位) 内部复位
3. 独立看门狗计数终止(IWDG复位) 内部复位
4. 软件复位(SW复位)
5. 低功耗管理复位
复位后CPU都会被强制到复位向量中去执行程序。
5.2 STM32的时钟总体设计
(1)时钟源:纯内部(不能特别精准)
内外部(晶振在外部,内部震荡电路,常见12M,24M进去进行倍频,然后分频)=> 大部分使用的情况
纯外部(外部产生时钟,输入到单片机内部,必须有现成的时钟,eg:同步CPU(如4个CPU同步))
(2)PLL(锁相环电路),功能就是倍频
(3)时钟通道(怎么走,时钟树)与流向、分频
(4)完全独立的多个时钟
如32.768Khz的晶振
6. 时钟图详解
6.1、总体配置
(1)独立时钟:HSx和LSx
(2)纯内部:HSI(Heigh Speed Interal signal)、LSI (Low Speed Interal signal)时钟精度差 上电是HSI,CPU有了时钟之后会用外部时钟
(3)内外部:HSE(Heigh Speed External signal)、LSE(Low Speed External signal)
(4)纯外部:OSC_IN、OSC32_IN
6.2、PLL
(1)2个可选PLL源(PLLSRC控制)
(2)倍频可设置(PLLMUL控制)
6.3、分频
(1)注意时钟节点名称:
HSI、HSE、LSI、LSE、
PLLCLK、SYSCLK、USBCLK、HCLK(AHB)、FCLK、PCLK1(APB1)、PCLK2(APB2)、ADCCLK、RTCCLK、IWDGCLK、
systick(系统滴答时钟)和MCO(时钟输出)
6.4 时钟相关寄存器
基地址,查memory map图得到,然后配合偏移量得到寄存器地址。
(1)RCC_CR 0x40021000 重要
(2)RCC_CFGR 0x40021004 重要(时钟配置寄存器)
(3)RCC_CIR 时钟中断
(4)RCC_APB2RSTR 复位外设时钟
(5)RCC_APB1RSTR
(6)RCC_AHBENR 外设时钟开关 重要
(7)RCC_APB2ENR 重要
(8)RCC_APB1ENR 重要
(9)RCC_BDCR 备份
(10)RCC_CSR 状态(复位状态,告诉我们哪个复位 还有一些时钟)
理想效果:我们编程时不需要考虑CPU的软浮点或者硬浮点特性,然后我自己就直接用C编程实现功能,然后设置好后直接编译,按照这样的规则帮我编译:我的浮点运算可以用硬浮点时用FPU,如果不能用硬浮点就自动用软浮点来实现。
寄存器位一般有三种:状态位(读取,查看状态)、开关位(使能)、设置值位(如分频)