STM32L系列单片机内部EEPROM的读写
STM32L系列单片机内部提供了EEPROM存储区域,但实质上,其FLASH也是EEPROM类型,只不过有一块区域被开放出来专门用作EEPROM操作而已。STM32L的EEPROM使用寿命设计为100000次擦写以上,容量为2K-4K,这对于一般设备的参数存储来说是非常理想的。但从EEPROM使用方式看,其不适用于被反复修改的数据存储使用,一般作为配置参数,其修改次数往往是比较少量的。
STM32L的EEPROM和FLASH是统一编址,操作共用同一个读写电路,所以在EEPROM读写的时候STM32L核对于FLASH的一切访问和操作都将暂停,只有当EEPROM的操作完成后,才继续执行后续代码,在这期间只有EEPROM的读写电路工作,CPU处于挂起状态。
读操作,和FLASH以及内存一样,EEPROM的数据读取直接用总线读周期读出即可,不需要进行额外操作和设置。
- #define EEPROM_BASE_ADDR 0x08080000
- #define EEPROM_BYTE_SIZE 0x0FFF
#define EEPROM_BASE_ADDR 0x08080000
#define EEPROM_BYTE_SIZE 0x0FFF
以上定义EEPROM区的起始位置和大小,给定偏移量之后,可以按字节/半字/字/双字方式读出,但要注意的是最好偏移地址都按四字节对齐,以免产生总线访问错误或是取不正确:
- /*------------------------------------------------------------
- Func: EEPROM数据按字节读出
- Note:
- -------------------------------------------------------------*/
- void EEPROM_ReadBytes(uint16 Addr,uint8 *Buffer,uint16 Length)
- {
- uint8 *wAddr;
- wAddr=(uint8 *)(EEPROM_BASE_ADDR+Addr);
- while(Length--){
- *Buffer++=*wAddr++;
- }
- }
/*------------------------------------------------------------
Func: EEPROM数据按字节读出
Note:
-------------------------------------------------------------*/
void EEPROM_ReadBytes(uint16 Addr,uint8 *Buffer,uint16 Length)
{
uint8 *wAddr;
wAddr=(uint8 *)(EEPROM_BASE_ADDR+Addr);
while(Length--){
*Buffer++=*wAddr++;
}
}
- /*------------------------------------------------------------
- Func: EEPROM数据读出
- Note:
- -------------------------------------------------------------*/
- void EEPROM_ReadWords(uint16 Addr,uint16 *Buffer,uint16 Length)
- {
- uint32 *wAddr;
- wAddr=(uint32 *)(EEPROM_BASE_ADDR+Addr);
- while(Length--){
- *Buffer++=*wAddr++;
- }
- }
/*------------------------------------------------------------
Func: EEPROM数据读出
Note:
-------------------------------------------------------------*/
void EEPROM_ReadWords(uint16 Addr,uint16 *Buffer,uint16 Length)
{
uint32 *wAddr;
wAddr=(uint32 *)(EEPROM_BASE_ADDR+Addr);
while(Length--){
*Buffer++=*wAddr++;
}
}
以上方法使用字节和字方式读出,在后面方法中,在一个字的存储空间内只使用了16个位,另16位不用,这样以避免产生对齐问题。
EEPROM的编程比读操作要复杂的多,本质上来说,擦除操作和写入操作是一样的,擦除只是在相应的地方写入0x00000000,但在STM32L的实现上,根据其手册说明貌似把这种擦除和写入区分开了,当写入0x00或0x0000或0x00000000时,自动执行一次擦除操作,在值为非0时,才执行一次所谓的写入操作。数据的写入过程先要对EEPROM进行解锁,这通过对特殊寄存器写入特殊序列实现,然后在写入之前进行擦除操作,其擦除是按字/ 双字/页进行的,推荐使用页擦除方式进行,先把参数读到内存,并修改,再进行页擦除,最后将参数写回,这种方式比较通用,否则很容易出现地址对齐或长度问题。在数据擦除完成之后,即可进行写入,每写一字节/半字/双字,都需要判断其是否写入完成,这和内部高压擦写电路有关,只有在上次操作完成之后再进行其它操作才有意义。最后,对EEPROM进行加锁,以保护数据。
下是手册给出的解锁命令码:
- #define PEKEY1 0x89ABCDEF //FLASH_PEKEYR
- #define PEKEY2 0x02030405 //FLASH_PEKEYR
#define PEKEY1 0x89ABCDEF //FLASH_PEKEYR
#define PEKEY2 0x02030405 //FLASH_PEKEYR
以下分别实现按字节和字方式写入:
- /*------------------------------------------------------------
- Func: EEPROM数据按字节写入
- Note:
- -------------------------------------------------------------*/
- void EEPROM_WriteBytes(uint16 Addr,uint8 *Buffer,uint16 Length)
- {
- uint8 *wAddr;
- wAddr=(uint8 *)(EEPROM_BASE_ADDR+Addr);
- DIS_INT
- FLASH->PEKEYR=PEKEY1; //unlock
- FLASH->PEKEYR=PEKEY2;
- while(FLASH->PECR&FLASH_PECR_PELOCK);
- FLASH->PECR|=FLASH_PECR_FTDW; //not fast write
- while(Length--){
- *wAddr++=*Buffer++;
- while(FLASH->SR&FLASH_SR_BSY);
- }
- FLASH->PECR|=FLASH_PECR_PELOCK;
- EN_INT
- }
/*------------------------------------------------------------
Func: EEPROM数据按字节写入
Note:
-------------------------------------------------------------*/
void EEPROM_WriteBytes(uint16 Addr,uint8 *Buffer,uint16 Length)
{
uint8 *wAddr;
wAddr=(uint8 *)(EEPROM_BASE_ADDR+Addr);
DIS_INT
FLASH->PEKEYR=PEKEY1; //unlock
FLASH->PEKEYR=PEKEY2;
while(FLASH->PECR&FLASH_PECR_PELOCK);
FLASH->PECR|=FLASH_PECR_FTDW; //not fast write
while(Length--){
*wAddr++=*Buffer++;
while(FLASH->SR&FLASH_SR_BSY);
}
FLASH->PECR|=FLASH_PECR_PELOCK;
EN_INT
}
- /*------------------------------------------------------------
- Func: EEPROM数据按字写入
- Note: 字当半字用
- -------------------------------------------------------------*/
- void EEPROM_WriteWords(uint16 Addr,uint16 *Buffer,uint16 Length)
- {
- uint32 *wAddr;
- wAddr=(uint32 *)(EEPROM_BASE_ADDR+Addr);
- DIS_INT
- FLASH->PEKEYR=PEKEY1; //unlock
- FLASH->PEKEYR=PEKEY2;
- while(FLASH->PECR&FLASH_PECR_PELOCK);
- FLASH->PECR|=FLASH_PECR_FTDW; //not fast write
- while(Length--){
- *wAddr++=*Buffer++;
- while(FLASH->SR&FLASH_SR_BSY);
- }
- FLASH->PECR|=FLASH_PECR_PELOCK;
- EN_INT
- }
/*------------------------------------------------------------
Func: EEPROM数据按字写入
Note: 字当半字用
-------------------------------------------------------------*/
void EEPROM_WriteWords(uint16 Addr,uint16 *Buffer,uint16 Length)
{
uint32 *wAddr;
wAddr=(uint32 *)(EEPROM_BASE_ADDR+Addr);
DIS_INT
FLASH->PEKEYR=PEKEY1; //unlock
FLASH->PEKEYR=PEKEY2;
while(FLASH->PECR&FLASH_PECR_PELOCK);
FLASH->PECR|=FLASH_PECR_FTDW; //not fast write
while(Length--){
*wAddr++=*Buffer++;
while(FLASH->SR&FLASH_SR_BSY);
}
FLASH->PECR|=FLASH_PECR_PELOCK;
EN_INT
}
以上代码中,在写入数据之前先关闭系统中断DIS_INT,写入完成之后打开系统中断EN_INT,这样避免在执行写操作的过程中被中断过程所打断,引起CPU异常或锁死,在在使用中一定要注意。在MDK环境中,两个可以这样定义:
- #define EN_INT __enable_irq(); //系统开全局中断
- #define DIS_INT __disable_irq(); //系统关全局中断
声明:本文是我转载别人的日志,http://blog.csdn.net/wangsanhuai2010/article/details/7932867原创作者
STM32L系列单片机内部EEPROM的读写的更多相关文章
- 单片机成长之路(51基础篇) - 021 STC89C51系列单片机 内部EEPROM 驱动
最近又看了一下关于stc单片机的知识,感觉在使用中EEPROM是个经常用到的东西,特地学习了一下,给大家分享一下心得,如有不足,多多包涵,废话不多说,一图解千言,先上图: /*------------ ...
- STC89C52单片机内部EEPROM驱动
STC89C52单片机自身带有4K的存储空间,分为8个扇区,每个扇区512字节,第一扇区起始地址为:0x2000, 结束地址为:21FF, 第八扇区起始地址为0x2E00,结束地址是2FFF #inc ...
- STC单片机 IAP(EEPROM)的使用
STC89C51.52内部都自带有2K字节的EEPROM,54.55和58都自带有16K字节的EEPROM,STC单片机是利用IAP技术实现的EEPROM,内部Flash擦写次数可达100,000 次 ...
- 调试单片机内部扩展RAM
51单片机内部只有128字节的RAM(8051),而8052有256字节的RAM,低128字节RAM直接或间接寻址都可以,高128字节RAM与SRF特殊功能寄存器共用地址,SFR只能直接寻址,高128 ...
- AT89C 系列单片机解密原理
单片机解密简单就是擦除单片机片内的加密锁定位.由于AT89C系列单片机擦除操作时序设计上的不合理.使在擦除片内程序之前首先擦除加密锁定位成为可能.AT89C系列单片机擦除操作的时序为:擦除开始---- ...
- 8、16、32-BIT系列单片机区别与特点
一.8位单片机 8031/8051/8751是Intel公司早期的产品 1.8031的特点 8031片内不带程序存储器ROM,使用时用户需外接程序存储器和一片逻辑电路373,外接的程序存储器多为EPR ...
- MSP430FR2系列单片机破解芯片解密多少钱?
MSP430FR2系列单片机破解芯片解密 MSP430FR2xx系列单片机芯片解密型号: MSP430FR2533.MSP430FR2110.MSP430FR2310.MSP430FR2311.MSP ...
- MCS-51系列和80C51系列单片机是否相同
MCS是Intel公司单片机的系列符号.Intel推出有MCS-48.MCS-51.MCS-96系列单片机. MCS-51系列单既包括三个基本型80C31.8051.8751,以及对应的低功耗型号80 ...
- MSP430系列单片机特性及应用领域
概述 MSP430系列单片机是德州仪器1996年开始推向市场的一种16位超低功耗的混合信号处理器,给人们留下的最大的亮点是低功耗而且速度快,汇编语言用起来很灵活,寻址方式很多,指令很少,容易上手.主要 ...
随机推荐
- Linux Shell变量
200 ? "200px" : this.width)!important;} --> 介绍 变量是shell脚本中必不可少的组成部分,在脚本中使用变量不需要提前声明.在ba ...
- 赴美工作常识(Part 3 - 英语)
在<Part 2 - 申请>的评论中有人问英语要达到何种水平,以及如何提高.其实英语也不是我的强项,只是刚刚好做到能够沟通而已.由于我在知乎上回到过一个类似问题,我就基于那个答案简单说一下 ...
- UStore-添加自定义工作流(JDF)到产品
这里使用的是8.2版本.所有的帮助文档可以在可以看到: http://www.xmpie.com/uStore%20Help/uStore_Help_Page.htm 1.登录 首先,登录到ustor ...
- underscore源码阅读记录
这几天有大神推荐读underscore源码,趁着项目测试的空白时间,看了一下. 整个underscore包括了常用的工具函数,下面以1.3.3源码为例分析一下. _.size = function(o ...
- 知方可补不足~SQL2008中的发布与订阅模式~续
回到目录 上一回介绍了如何在sql2008中建立一个数据库的发布者,今天来说一下如何建立一个订阅者,其实订阅者也是一个数据库,而这个数据库是和发布者的数据结构相同的库,它们之间通过SQL代理进行数据上 ...
- EF架构~为BulkInsert引入SET IDENTITY_INSERT ON功能
回到目录 在设计表结构时,我们通常将不是很在乎表现的主键设计成自增长的,大数据量用bigint,一般地用int就可以了,int就是C#里的Int32,它最大可以存储到2147483647,21亿,基本 ...
- [Spring框架]Spring IOC的原理及详解。
这里感谢 CSDN 的原博客:http://blog.csdn.net/m13666368773/article/details/7802126 看后 受益匪浅,这里再重温一遍Spring IOC ...
- 敏捷数据科学:用Hadoop创建数据分析应用
敏捷数据科学:用Hadoop创建数据分析应用(数据分析最佳实践入门敏捷大数据首作分步骤|全流程演示思路.工具与方法) [美]Russell Jurney(拉塞尔·朱尔尼) 著 冯文中 朱洪波 译 ...
- iOS-------应用性能调优的25个建议和技巧
性能对 iOS 应用的开发尤其重要,如果你的应用失去反应或者很慢,失望的用户会把他们的失望写满App Store的评论.然而由于iOS设备的限制,有时搞好性能是一件难事.开发过程中你会有很多需要注意的 ...
- jQuery 滚动条 滚动到底部(下拉到底部) 加载数据(触发事件、处理逻辑)、分页加载数据
1.针对浏览器整个窗口滚动 主要代码: <script type="text/javascript"> ; function GetProductListPageFun ...