历史上的今天
今天是:2024年08月31日(星期六)
2021年08月31日 | STM8内部EEPROM的使用详解
2021-08-31 来源:eefocus
1 内存映射
STM8S105集成了多达1K的EEPROM(掉电数据不会丢失)最高可以支持30万次的擦写次数,用户可以将一些数据保存在EEPROM中,具体的memory map如下图所示;

在这里内存一页的大小为64 bytes(1 block), DATA EEPROM的内存地址映射如下图所示;
可以看到,EEPROM的起始地址为0x004000,结束地址为0x00427F,这个在下面编程时会用到,当然具体的大小会因为型号不同而有所差异;

2 程序实现
下面程序基于stm8的标准库,进行实现,相应标准库可以在st官网上下载得到;
eeprom_inner.ch
#ifndef EEPROM_INNER_H
#define EEPROM_INNER_H
#include "stm8s.h"
#define EEPROM_BASE_ADDR 0x4000
#define EEPROM_SIZE 0x07FF
union data32_unit_mod {
uint32_t data32;
uint8_t buf[4];
};
typedef union data32_unit_mod data32_unit_mod_t;
union data16_unit_mod {
uint16_t data16;
uint8_t buf[2];
};
typedef union data16_unit_mod data16_unit_mod_t;
/**
外部函数声明
*/
void eeprom_init(void);
uint8_t eeprom_read_byte(uint16_t addr);
void eeprom_write_byte(uint16_t addr,uint8_t data);
void eeprom_write_data32(uint16_t offset, uint32_t data);
void eeprom_write_data16(uint16_t offset, uint16_t data);
void eeprom_write_data8(uint16_t offset, uint8_t data);
uint32_t eeprom_read_data32(uint16_t offset);
uint16_t eeprom_read_data16(uint16_t offset);
uint8_t eeprom_read_data8(uint16_t offset);
void eeprom_area_clear(void);
#endif
eeprom_inner.c
#include "eeprom_inner.h"
#include "stm8s_clk.h"
#include "stm8s_flash.h"
void eeprom_init(void)
{
FLASH_DeInit();
FLASH_Unlock(FLASH_MEMTYPE_DATA);//EEPROM
FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_TPROG);
}
inline uint8_t eeprom_read_byte(uint16_t addr)
{
return FLASH_ReadByte(addr);
}
inline void eeprom_write_byte(uint16_t addr,uint8_t data)
{
FLASH_Unlock(FLASH_MEMTYPE_DATA);
FLASH_ProgramByte(addr, data);
FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);
FLASH_Lock(FLASH_MEMTYPE_DATA);
}
void eeprom_write_data32(uint16_t offset, uint32_t data){
data32_unit_mod_t tmp;
tmp.data32 = data;
if(offset+4 > EEPROM_SIZE){
//error
return;
}
eeprom_write_byte(EEPROM_BASE_ADDR+offset, tmp.buf[0]);
eeprom_write_byte(EEPROM_BASE_ADDR+offset+1,tmp.buf[1]);
eeprom_write_byte(EEPROM_BASE_ADDR+offset+2,tmp.buf[2]);
eeprom_write_byte(EEPROM_BASE_ADDR+offset+3,tmp.buf[3]);
}
void eeprom_write_data16(uint16_t offset, uint16_t data){
data16_unit_mod_t tmp;
tmp.data16 = data;
if(offset+2 > EEPROM_SIZE){
//error
return;
}
eeprom_write_byte(EEPROM_BASE_ADDR+offset, tmp.buf[0]);
eeprom_write_byte(EEPROM_BASE_ADDR+offset+1,tmp.buf[1]);
}
void eeprom_write_data8(uint16_t offset, uint8_t data){
if(offset+1 > EEPROM_SIZE){
//error
return;
}
eeprom_write_byte(EEPROM_BASE_ADDR+offset, data);
}
uint32_t eeprom_read_data32(uint16_t offset){
data32_unit_mod_t tmp;
if(offset+4 > EEPROM_SIZE){
//error
return 0xEEEEEEEE;
}
tmp.buf[0] = eeprom_read_byte(EEPROM_BASE_ADDR+offset);
tmp.buf[1] = eeprom_read_byte(EEPROM_BASE_ADDR+offset+1);
tmp.buf[2] = eeprom_read_byte(EEPROM_BASE_ADDR+offset+2);
tmp.buf[3] = eeprom_read_byte(EEPROM_BASE_ADDR+offset+3);
return tmp.data32;
}
uint16_t eeprom_read_data16(uint16_t offset){
data16_unit_mod_t tmp;
if(offset+2 > EEPROM_SIZE){
//error
return 0xEEEE;
}
tmp.buf[0] = eeprom_read_byte(EEPROM_BASE_ADDR+offset);
tmp.buf[1] = eeprom_read_byte(EEPROM_BASE_ADDR+offset+1);
return tmp.data16;
}
uint8_t eeprom_read_data8(uint16_t offset){
if(offset+1 > EEPROM_SIZE){
//error
return 0xEE;
}
return eeprom_read_byte(EEPROM_BASE_ADDR+offset);
}
void eeprom_area_clear(void){
uint16_t index = 0;
for( ; index < EEPROM_SIZE; index+=2 ){
eeprom_write_data16(index,0xFFFF);
}
}
史海拾趣
|
原文: 学习方法真的至关重要么 前面已经提到我作为老师经常遇到学生问“老师,这个方法真的有用么?”其 实,我知道学生的问题不止这一个,他们还有更进一步的问题。当然,只有聪明 的人才去关心方法,这没什么不对。然而,学生总是过分关心自 ...… 查看全部问答> |
|
我用的是WinCE5.0的系统,使用的BVDMAIN的bsp。 在driver里面有一个DMA文件夹,里面有一些使用DMA时相关的函数。还有一个例程代码。 但是我用例程代码调试,总是不成功。 请教一下是什么原因,谢谢 代码如下: #define FPGA_DMA_BUFFER_SI ...… 查看全部问答> |
|
本人第1次用CE。。。。 刚装好platform builder时。马上Build了一个NK。BIn 放在目标机上可以好好的运行。目标机上的media player可以打开windows media server编码出来的WMV9的MMS流。 后来我更改了一些东西。。。再BUILd就打不能MMS流了。。连 ...… 查看全部问答> |
|
本人用F412做仪表,设置一个按键P16来关机,关机后进入LPM4,同时设定IO口中断,结果发现进入休眠以后P1IE莫名其妙地被清零,硬件仿真的时候读出来的P1IE为0,从而导致不能再次开机,修改内存把它改为0x40(BIT6)后才能进入中断唤醒,再次进入休眠 ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 09:47 编辑 、基本仪器清单 20MHz普通示波器(双通道,外触发输入,有X轴输入) 60MHz双通道数字示波器 低频信号发生器(1Hz~1MHz) 标准高频信号发生器(1MHz~30MHz,可输出1mV小信号) 函数发生器(10 M ...… 查看全部问答> |
|
我在书上抄的一段程序 #include \"io430.h\" #include<msp430x44x.h>#define Const 100vodi SoftDelay(int Factor){int i,j;for(i=0;i<Factor;i++) for(j=0;j<Const;j++); }void main(void){ _NOP(); SoftDelay ...… 查看全部问答> |
|
白光LED属于电压敏感型的器件,在实际工作中是以20mA的电流为上限,但往往会由于在使用中的各种原因而造成电流增大,如果不采取保护措施,这种增大的电流超过一定的时间和幅度后LED就会损坏。 造成LED损坏的原因主要有:   ...… 查看全部问答> |




