STM32 FLASH做EEPROM用
STM32?本身没有自带?EEPROM,但是?STM32?具有?IAP(在应用编程)功能,所以我们可以把它的?FLASH?当成?EEPROM?来使用 STM32?FLASH?简介 不同型号的?STM32,其?FLASH?容量也有所不同,最小的只有?16K?字节,最大的则达到了1024K?字节。战舰?STM32?开发板选择的?STM32F103ZET6?的?FLASH?容量为?512K?字节,属于大容量产品(另外还有中容量和小容量产品), STM32?的闪存模块由:主存储器、信息块和闪存存储器接口寄存器等?3?部分组成。 主存储器,该部分用来存放代码和数据常数(如?const?类型的数据)。对于大容量产品,其被划分为?256?页,每页?2K?字节。注意,小容量和中容量产品则每页只有?1K?字节。从上图可以看出主存储器的起始地址就是?0X08000000,??B0、B1?都接?GND?的时候,就是从?0X08000000开始运行代码的。 信息块,该部分分为?2?个小部分,其中启动程序代码,是用来存储?ST?自带的启动程序,用于串口下载代码,当?B0?接?V3.3,B1?接?GND?的时候,运行的就是这部分代码。用户选择字节,则一般用于配置写保护、读保护等功能, 闪存存储器接口寄存器,该部分用于控制闪存读写等,是整个闪存模块的控制机构。 闪存的读取 内置闪存模块可以在通用地址空间直接寻址,任何?32?位数据的读操作都能访问闪存模块的内容并得到相应的数据。读接口在闪存端包含一个读控制器,还包含一个?AHB?接口与?CPU?衔接。这个接口的主要工作是产生读闪存的控制信号并预取?CPU?要求的指令块,预取指令块仅用于在?I-Code?总线上的取指操作,数据常量是通过?D-Code?总线访问的。这两条总线的访问目标是相同的闪存模块,访问?D-Code?将比预取指令优先级高 这里要特别留意一个闪存等待时间,因为?CPU?运行速度比?FLASH?快得多,STM32F103的?FLASH?最快访问速度≤24Mhz,如果?CPU?频率超过这个速度,那么必须加入等待时间,比如我们一般使用?72Mhz?的主频,那么?FLASH?等待周期就必须设置为?2,该设置通过?FLASH_ACR寄存器设置。 使用?STM32?的官方固件库操作?FLASH?的几个常用函数。这些函数和定义分布在文件?stm32f10x_flash.c?以及?stm32f10x_flash.h?文件中。 1.??锁定解锁函数 在对?FLASH?进行写操作前必须先解锁,解锁操作也就是必须在?FLASH_KEYR?寄存器写入特定的序列(KEY1?和?KEY2),固件库函数实现很简单: void?FLASH_Unlock(void); 同样的道理,在对?FLASH?写操作完成之后,我们要锁定?FLASH,使用的库函数是: FLASH_Lock(void); 2.??写操作函数 固件库提供了三个?FLASH?写函数: FLASH_Status?FLASH_ProgramWord(uint32_t?Address,?uint32_t?Data); FLASH_Status?FLASH_ProgramHalfWord(uint32_t?Address,?uint16_t?Data); FLASH_Status?FLASH_ProgramOptionByteData(uint32_t?Address,?uint8_t?Data); 顾名思义分别为:FLASH_ProgramWord?为??32?位字写入函数,其他分别为?16?位半字写入和用户选择字节写入函数。这里需要说明,32?位字节写入实际上是写入的两次?16?位数据,写完第一次后地址+2,这与我们前面讲解的?STM32?闪存的编程每次必须写入?16?位并不矛盾。写入?8位实际也是占用的两个地址了,跟写入?16?位基本上没啥区别。 3.??擦除函数 固件库提供三个?FLASH?擦除函数: FLASH_Status?FLASH_ErasePage(uint32_t?Page_Address); FLASH_Status?FLASH_EraseAllPages(void); FLASH_Status?FLASH_EraSEOptionBytes(void); 这三个函数可以顾名思义了,非常简单。 4.??获取?FLASH?状态 主要是用的函数是: FLASH_Status?FLASH_GetStatus(void); 返回值是通过枚举类型定义的: typedef?enum {? FLASH_BUSY?=?1,//忙 FLASH_ERROR_PG//编程错误 FLASH_ERROR_WRP//写保护错误 FLASH_COMPLETE//操作完成 FLASH_TIMEOUT//操作超时 }FLASH_Status; 从这里面我们可以看到?FLASH?操作的?5?个状态,每个代表的意思我们在后面注释了。 5.??等待操作完成函数 在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作。所以在每次操作之前,我们都要等待上一次操作完成这次操作才能开始。使用的函数是: FLASH_WaitForLastOperation(uint32_t?Timeout) 入口参数为等待时间,返回值是?FLASH?的状态,这个很容易理解,这个函数本身我们在固件库中使用得不多,但是在固件库函数体中间可以多次看到。 6.??读?FLASH?特定地址数据函数 有写就必定有读,而读取?FLASH?指定地址的半字的函数固件库并没有给出来,这里我们自己写的一个函数: u16?STMFLASH_ReadHalfWord(u32?faddr) { return?*(vu16*)faddr;? } 点击(此处)折叠或打开
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |