[15-1]FLASH闪存
同为闪存,它们的特性基本一样,写入前必须擦除,擦除必须以最小单位进行,擦除后数据位全变为1,数据只能1写0,不能0写1,除和写入之后都需要等待忙
地址只要以000、400、800、C00结尾的,都一定是页的起始地址,对吧
打一步 自的,都是为了防止误操作
也就是复位后,FLASH默认是锁着的
那编译器优化有什么用呢可以去除无用的繁杂代码,降低代码空间,提升运行效率,但优化之后,编译器在某些地方可能会弄巧成拙
比如,你想用变量计数空循环的方式实现延时函数,那编译器优化的时候,可能会说你这設延时函数好像没用啊,还自自浪费时间,给你优化掉了
另外,编译器还会利用缓存来加速代码,比如如果你要频繁读写內存的某个变量,那最常见的优化方式就是先把变量转移到高速缓存里来,在STM32内核里,有一个类似缓存的工作组寄存器,这些寄存器的访问速度最快,我先把变量放在缓存里,需要读写的时候,直接访问缓存就行了,用完之后,再写回内存,但是,如果你的程序里有多个线程,比如中断函数,在中断函数里,你改变了这个原始变量,那可能缓存并不知道你更改了,下次程序还看缓存的变量,就会造成数据更改不同步的问题,这时,我们的做法也是,读取变量定义的前面,加上一个volatile,告诉编译器这个变量是易变的,每次读取你都得执行到位,要直接从内存里找,不要再用缓存优化了,所以总结一下就是如果开启了编译器优化,在无意义加减变量,多线程更改变量,读写与硬件相关的存储器时,都需要加上volatile,防止被编译器优化,如果你默认,不开编译器优化,那就无所谓了,加不加都一样,所以这里,我们要直接读取存储器
使用指针写指定地址下的存储器,这个语句的意思就很明显了,左边,和上面一样,先给定地址,再强转为指针,最后指针取内容,这样就是指定地址的值,因为这个语句是写入数据,并且指定的是闪存的地址,闪存在程序运行时,是只读的,不能轻易更改,而我们本节需要对㭎存进行更改,这个所需的权限就比较高,需要提前解锁
SRAM在程序运行时是可读可写的
写入操作只能以半字的形式写入
STM32的闪存在写入之前会检查指定地址有没有擦除,如果没有擦除就写入,STM32则不执行写入操作,其中字,Word,就是32位数据,半字,HalfWord,就是16位数据,字节,Byte,就是8位数据
所以,如果你想像SRAM一样随心所欲的读写,那最好的办法就是先把闪存的一页读到SRAM中,读写完成后,再擦除一页,整体写回去
擦除之后,所有的数据位变为1,擦除的最小单位就是一页,1K,1024字节。除非写入的全是0,这一个数据是例外,因为不擦除就写入,可能会写入错误,但全写入0的话,写入肯定是没问题的
