/*
**********************************************************************************************************************************
* Name : STM8S存储器的读写操作
* Author : MingMing
* Release : 2014/1/2
* Update : 2014/1/2
* E-mail : clint.wang@foxmail.com
**********************************************************************************************************************************
*/
在芯片中存储器一般分为两种:一种是EEPROM(数据存储器),另一种是FLASH ROM(程序存储器)。它们都是非易失性存储器,但是在特性上有一些差别。EEPROM读写最小单元为字节,在同一个地址重复写入数据时允许不进行擦除操作。FLASH ROM是按照扇区读写的,在同一个地址重复写入数据时需要擦除该地址才能再次写入。
STM8S的芯片集成了EEPROM和FLASH ROM两种存储器,前者负责存储数据和Option Byte(选项字节),后者负责存储代码。
Stm8s_flash.h文件中代码如下所示:
/*
***************************************************************************
* @file stm8s_flash.h
* @brief This file is used to configure the Library.
* @author clint.wang
* @platform IAR For STM8S 1.31 + STM8S105C6
* @date 12/27/2013
******************************************************************************
*/
#ifndef __STM8S_FLASH_H__
#define __STM8S_FLASH_H__
//
#include #include "stm8s_type.h" // #define STM8S105 #ifdef STM8S105 #define FLASH_PROG_PHYSICAL_ADDR_START 0x8000 /* 程序存储区首端地址 */ #define FLASH_PROG_PHYSICAL_ADDR_END 0xFFFF /* 程序存储区末端地址 */ #define FLASH_PROG_BLOCKS_NUMBER 256 /* 程序存储区的块数 */ #define FLASH_DATA_PHYSICAL_ADDR_START 0x4000 /* 数据存储区首端地址 */ #define FLASH_DATA_PHYSICAL_ADDR_END 0x43FF /* 数据存储区末端地址 */ #define FLASH_DATA_BLOCKS_NUMBER 8 /* 数据存储区的块数 */ #define OPTION_BYTE_PHYSICAL_ADDR_START 0x4800 /* 选项字节首端地址 */ #define OPTION_BYTE_PHYSICAL_ADDR_END 0x487F /* 选项字节末端地址 */ #define OPTION_BYTE_NUMBER 15 /* 选项字节的长度 */ #define FLASH_BLOCK_SIZE 128 /* 每块存储所含的字节 */ #endif /* STM8S105 */ // #define FLASH_RASS_KEY1 0x56 /* FLASH解除写保护密钥 */ #define FLASH_RASS_KEY2 0xAE /* FLASH解除写保护密钥 */ #define FLASH_CLR_BYTE 0x00 #define FLASH_SET_BYTE 0xFF // typedef enum{ FLASH_PROG = 0, FLASH_DATA = 1 }PLASH_TYPE; // #define ADDR_FLASH(addr) *((INT8U*)addr) #define ADDR_PROG(offset) ADDR_FLASH(FLASH_PROG_PHYSICAL_ADDR_START + offset) #define ADDR_DATA(offset) ADDR_FLASH(FLASH_DATA_PHYSICAL_ADDR_START + offset) #define ADDR_OPTION(offset) ADDR_FLASH(OPTION_BYTE_PHYSICAL_ADDR_START + offset) // /* Flash写操作的锁定和解除 */ void FLASH_WirteLock(PLASH_TYPE memoryType); void FLASH_WirteUnlock(PLASH_TYPE memoryType); // /* Flash 程序存储器的读写和擦除 */ void FLASH_ProgWirteByte(INT16U addrOffset, INT8U iuData); void FLASH_ProgEraseByte(INT16U addrOffset); INT8U FLASH_ProgReadByte(INT16U addrOffset); // /* EEPROM 数据存储器的读写和擦除 */ void FLASH_DataWirteByte(INT16U addrOffset, INT8U iuData); void FLASH_DataEraseByte(INT16U addrOffset); INT8U FLASH_DataReadByte(INT16U addrOffset); // /* 选项字节的读写 */ void FLASH_OptionWirteByte(INT16U addrOffset, INT8U iuData); INT8U FLASH_OptionReadByte(INT16U addrOffset); // /* Flash在halt状态下进入低功耗模式 */ void FLASH_LowPowerMode(void); /* 擦除一块存储区 */ void FLASH_EraseBlock(INT8U BlockNum, PLASH_TYPE MemType); // #endif Stm8s_flash.c文件中代码如下所示: #include "stm8s_flash.h" /******************************************************************************* * 函数名:FLASH_WirteLock * 描 述:Flash写保护使能 * 参 数:memoryType :写保护对象,程序存储器或者数据存储器 * 返回值:无 *******************************************************************************/ void FLASH_WirteLock(PLASH_TYPE memoryType) { if (memoryType == FLASH_DATA) FLASH_IAPSR &= ~MASK_FLASH_IAPSR_DUL; else FLASH_IAPSR &= ~MASK_FLASH_IAPSR_PUL; } /******************************************************************************* * 函数名:FLASH_WirteUnlock * 描 述:Flash写保护解锁 * 参 数:memoryType :解保护对象,程序存储器或者数据存储器 * 返回值:无 *******************************************************************************/ void FLASH_WirteUnlock(PLASH_TYPE memoryType) { if(memoryType == FLASH_DATA) { do{ FLASH_DUKR = FLASH_RASS_KEY2; /* 写入第二个密钥 */ FLASH_DUKR = FLASH_RASS_KEY1; /* 写入第一个密钥 */ }while(!(FLASH_IAPSR & MASK_FLASH_IAPSR_DUL)); /* 判断解锁是否成功 */ } else { do{ FLASH_PUKR = FLASH_RASS_KEY1; /* 写入第一个密钥 */ FLASH_PUKR = FLASH_RASS_KEY2; /* 写入第二个密钥 */ }while(!(FLASH_IAPSR & MASK_FLASH_IAPSR_PUL)); /* 判断解锁是否成功 */ } } /******************************************************************************* * 函数名:FLASH_ProgWirteByte * 描 述:写一个字节到程序存储区 * 参 数:addrOffset :相对程序存储区首地址的偏移量,从0开始 iuData :写入存储区的数据 * 返回值:无 *******************************************************************************/ void FLASH_ProgWirteByte(INT16U addrOffset, INT8U iuData) { if(FLASH_IAPSR & MASK_FLASH_IAPSR_PUL) /* 是否处于解锁状态 */ { if(addrOffset < ((INT16U)FLASH_PROG_BLOCKS_NUMBER * 128)) { ADDR_PROG(addrOffset) = iuData; while(!(FLASH_IAPSR & MASK_FLASH_IAPSR_EOP)); } } } /******************************************************************************* * 函数名:FLASH_ProgEraseByte * 描 述:擦除程序存储区指定地址的数据,写入0x00即可 * 参 数:addrOffset :相对程序存储区首地址的偏移量,从0开始 * 返回值:无 *******************************************************************************/ void FLASH_ProgEraseByte(INT16U addrOffset) { FLASH_ProgWirteByte(addrOffset,FLASH_CLR_BYTE );//FLASH_CLR_BYTE } /******************************************************************************* * 函数名:FLASH_ProgReadByte * 描 述:读取程序存储区指定地址的数据 * 参 数:addrOffset :相对程序存储区首地址的偏移量,从0开始 * 返回值:偏移地址存储的数据 *******************************************************************************/ INT8U FLASH_ProgReadByte(INT16U addrOffset) { if(addrOffset < ((INT16U)FLASH_PROG_BLOCKS_NUMBER * FLASH_BLOCK_SIZE)) return (ADDR_PROG(addrOffset)); return 0; } /******************************************************************************* * 函数名:FLASH_DataWirteByte * 描 述:写一个字节到数据存储区 * 参 数:addrOffset :相对数据存储区首地址的偏移量,从0开始 iuData :写入存储区的数据 * 返回值:无 *******************************************************************************/ void FLASH_DataWirteByte(INT16U addrOffset, INT8U iuData) { if(FLASH_IAPSR & MASK_FLASH_IAPSR_DUL) /* 是否处于解锁状态 */ { if(addrOffset < (FLASH_DATA_BLOCKS_NUMBER*FLASH_BLOCK_SIZE)) { ADDR_DATA(addrOffset) = iuData; while(!(FLASH_IAPSR & MASK_FLASH_IAPSR_EOP)); } } } /******************************************************************************* * 函数名:FLASH_DataEraseByte * 描 述:擦除数据存储区指定地址的数据,写入0x00即可 * 参 数:addrOffset :相对程序存储区首地址的偏移量,从0开始 * 返回值:无 *******************************************************************************/ void FLASH_DataEraseByte(INT16U addrOffset) { FLASH_DataWirteByte(addrOffset, FLASH_CLR_BYTE); } /******************************************************************************* * 函数名:FLASH_DataReadByte * 描 述:读取数据存储区指定地址的数据 * 参 数:addrOffset :相对数据存储区首地址的偏移量,从0开始 * 返回值:偏移地址存储的数据 *******************************************************************************/ INT8U FLASH_DataReadByte(INT16U addrOffset) { if(addrOffset < (FLASH_DATA_BLOCKS_NUMBER*FLASH_BLOCK_SIZE)) { return (ADDR_DATA(addrOffset));} return 0; } /******************************************************************************* * 函数名:FLASH_OptionWirteByte * 描 述:写一个字节到选项字节存储区 * 参 数:addrOffset :相对选项字节存储区首地址的偏移量,从0开始 iuData :写入存储区的数据 * 返回值:无 *******************************************************************************/ void FLASH_OptionWirteByte(INT16U addrOffset, INT8U iuData) { if(addrOffset < OPTION_BYTE_NUMBER) { FLASH_CR2 |= MASK_FLASH_CR2_OPT; /* 解除OPT写保护 */ FLASH_NCR2 &=~MASK_FLASH_CR2_OPT; /* 解除OPT写保护 */ ADDR_OPTION(addrOffset) |= iuData; /* 写入选项字节 */ ADDR_OPTION(addrOffset+1) &=~iuData; /* 写入选项字节 */ while(!(FLASH_IAPSR & MASK_FLASH_IAPSR_EOP)); FLASH_CR2 &=~MASK_FLASH_CR2_OPT; /* 锁定OPT写保护 */ FLASH_NCR2 |= MASK_FLASH_CR2_OPT; /* 锁定OPT写保护 */ } } /*******************************************************************************
设计资源 培训 开发板 精华推荐
- 使用 Analog Devices 的 LT1317BCS8 的参考设计
- 用于 MCU 系统负载感应的 NCP300LSN34T1 3.4V 电压检测器的典型应用
- AM1D-0509S-RZ 9V 1W DC/DC 转换器的典型应用
- L7824C 功率 AM 调制器的典型应用(单位电压增益,IO = 0.5)
- CN0225
- YJSNPI-Zoomer V1
- 使用 Endicott Research Group 的 SFD2EB4187F 的参考设计
- 根据 EN50121-3-2(双输出)使用具有 EMC 滤波的 RP40-4815DFR DC/DC 转换器的典型应用
- LTC3622HDE-2 5V/3.3V Vout 突发模式操作应用同步降压稳压器的典型应用电路
- 基于nanopi neo air的业余无线电aprs模块