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);
}
}
上一篇:飞思卡尔MC9S12系列单片机地址影射以及分页问题
下一篇:【STM8S】 FLASH与EEPROM读写操作
推荐阅读最新更新时间:2024-11-04 15:02
设计资源 培训 开发板 精华推荐
- SI5324-EVB,使用 SI5324 的评估板,0.002 至 710 MHz 时钟发生器
- LT1117CM-5 具有基准电压源的低压差正稳压器的典型应用
- TCR5SB27U、200mA、2.7V输出电压CMOS低压降稳压器的典型应用
- 涂鸦WiFi红外遥控器
- AN5124,三相 BLDC 汽车 MOSFET 驱动器的电源电压配置 L9907 应用电路
- 使用 LTC2400 的差分桥式数字转换器设计电路
- 使用 ROHM Semiconductor 的 BD5247 的参考设计
- OPA4377运放模块
- LTC2226IUH 演示板,高速 ADC,VDD = +3.0V,25Msps,12 位 1MHz
- #第七届立创电赛#复刻电流表