STM32的内部Flash操作
我们在设计单片机程序的时候,部分的需求是需要有掉电不丢失的功能。我们可能会使用EEPROM这种存储设备来进行数据的存储保证数据掉电不丢失。而在实际的应用场景中,我们并没有太多的数据量需要进行存储,可能只是一些程序上的参数需要保存。这个使用使用EEPROM就显得有点大材小用,从产品的角度思考这个模块也会给整个项目增加较大的成本。
此时使用单片机内部自带的flash来进行部分数据的掉电不丢失就非常极具性价比(虽然内部flash的读写寿命要少于EEPROM)
1 内部储存空间
stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小,不同的芯片flash大小不同。
RAM起始地址是0x2000 0000,结束地址是0x2000 0000加上芯片的RAM大小。不同的芯片RAM也不同。
stm32的外设地址从0x4000 0000开始,可以看到在库文件中,是通过基于0x4000 0000地址的偏移量来操作寄存器以及外设的。
一般情况下,程序文件是从 0x0800 0000 地址写入,这个是STM32开始执行的地方,0x0800 0004是STM32的中断向量表的起始地址。
程序的写入地址从0x0800 0000开始的,其大小为0x80000也就是512K的空间,换句话说就是告诉编译器flash的空间是从0x0800 0000-0x0808 0000,RAM的地址从0x2000 0000开始,大小为0x10000也就是64K的RAM。这与STM32的内存地址映射关系是对应的。
M3复位后,从0x08000004取出复位中断的地址,并且跳转到复位中断程序,中断执行完之后会跳到我们的main函数,main函数里边一般是一个死循环,进去后就不会再退出,当有中断发生的时候,M3将PC指针强制跳转回中断向量表,然后根据中断源进入对应的中断函数,执行完中断函数之后,再次返回main函数中。
2 内部Flash的构成
以STM32F103C8T6为例。它的Flash大小为64K x 8bit,即64k个字节的数据。
我们通常Page的方式来区分这些存储空间。在STM32的中容量和小容量的型号中,一般以1K字节作为一个扇区;在大容量的型号中,会以2K作为一个扇区的容量。
内部Flash的启始地址是0x8000 0000,那么以1K作为扇区的容量,那么第0页的范围就是0x8000 0000 ~ 0x8000 03FF(即是1024-1=1023=0x03FF)。那么STM32F103C8T6的内部Flash空间是64K的大小,所以它的最大页为。以下是部分页的范围:
page0: 0x8000 0000 ~ 0x8000 03FF
page1: 0x8000 0400 ~ 0x8000 07FF
page2: 0x8000 0800 ~ 0x8000 0BFF
page3: 0x8000 0C00 ~ 0x8000 0FFF
page4: 0X8000 1000 ~ 0X8000 13FF
…….
page62: 0x8000 F800 ~ 0x8000 FBFF
page63: 0x8000 FC00 ~ 0x8000 FFFF
3 Flash的读写操作
3.1 Flash写入
3.1.1解锁
为了防止误操作,在修改内存的时候需要我们对控制寄存器FLASH_CR进行解锁。解锁的方法是对FPEC键寄存器FLASH_KEYR写入解锁的秘钥。
秘钥的内容是0x4567 0123 CDEF 89AB,需要按顺序分别写入才能进行解锁。
1 |
|
3.1.2 擦除操作
擦除和写入操作都需要先对Flash进行解锁,毕竟Flash擦除写入是一个比较严谨的过程,操作不当可能会导致系统故障单片机卡死。
1 | /*Flash擦除函数*/ |
在程序中,擦除操作其实是以扇区为单位进行的,上方的代码中则是固定的擦除操作。其实原理就是首先将擦除控制位置位,接着讲扇区的启始地址写入ADDR寄存器(代码中是AR),扇区的单位是以单片机型号界定。接着置位擦除开始寄存器。等待擦除完成即可。完成后需要重新上锁。
3.1.3 写入操作
写入操作建立在擦除之后,因为在写入之前需要进行擦除。
1 | /*Flash写入函数*/ |
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1186703947@qq.com