打印
[STM8]

STM8S单片机的内部eeprom编程

[复制链接]
1407|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
STM8S单片机芯片内部也集成有EEPROM,容量从640字节到2K字节。最为特色的是,在STM8单片机中,对EEPROM的访问就象常规的RAM一样,非常方便。EEPROM的地址空间与内存是统一编址的,地址从004000H开始,大小根据不同的芯片型号而定。
当然如果有外部EEPROM,自然是不会使用到内部的EEPROM的。但小东西也有大用途,例如做无线应用时,减少成本的情况下,还能保存一些特定设置,如:休眠时间,工作频率,输出功率,密码等。
EEPROM3种编程模式:
l  字节编程 (没有擦除操作)
可对 EEPROM的数据区域进行逐字地编程。应用程序直接向目标地址写入数据。
l  字编程
EEPROM允许字编程(一次编程4个字节),从而缩短EEPROM的编程时间。
l  块编程 (没有擦除操作)
   EEPROM块编程操作允许一次对整个块(64个字节)进行编程,整个块在编程前被自动擦除。但块编程操作一定要在RAM中运行。
下面以字节编程进行讲解:
实验平台:stm8s103k3 + stlink
在stm8s_flash.h中:
#if defined (STM8S103) || defined(STM8S903)
#define FLASH_PROG_END_PHYSICAL_ADDRESS   ((uint32_t)0x9FFF)  
#define FLASH_PROG_BLOCKS_NUMBER          ((uint16_t)128)     
#define FLASH_DATA_START_PHYSICAL_ADDRESS ((uint32_t)0x004000)
#define FLASH_DATA_END_PHYSICAL_ADDRESS   ((uint32_t)0x00427F)
#define FLASH_DATA_BLOCKS_NUMBER          ((uint16_t)10)      
#define FLASH_BLOCK_SIZE                  ((uint8_t)64)      
#endif
从这里可以看出,eeprom的地址为0x004000~0x00427F,这段地址分为10个Block,每个Block有64个Byte,总容量为640Byte.
关于2个秘钥在stm8s_flash.h中已经定义:
#define FLASH_RASS_KEY1 ((uint8_t)0x56)
#define FLASH_RASS_KEY2 ((uint8_t)0xAE)
      中文数据手册上KEY1和KEY2的定义与代码一致,但是英文数据手册上KEY1为0x56和KEY1为)0XAE.暂且不讨论谁搞反了,以代码为准吧!
首先要初始化EEPROM:
我们在eeprom.h中定义:
typedef enum{
  #if defined(STM8S103) || defined(STM8S003) ||  defined(STM8S903)
  Block_0=0x4000,
  Block_1=0x4040,
  Block_2=0x4080,
  Block_3=0x40C0,
  Block_4=0x4100,
  Block_5=0x4140,
  Block_6=0x4180,
  Block_7=0x41C0,
  Block_8=0x4200,
  Block_9=0x4240
  #endif
}BlockStartAddress_TypeDef; //分块存数,方便读写操作!
在eeprom.c中初始化:
初始化操作步骤:
1. 设定编程时间。FIX=1为标准编程时间(一般一次编程时间为6ms)。如果EEPROM被擦除过并且FIX=0,那么变成时间为标准编程时间的一半(一般为3ms)。
2. 向FLASH_DUKR寄存器连续写入两个MASS密钥值来解除DATA区域的写保护。
第一个硬件密钥:0b0101 0110 (0x56)
第二个硬件密钥:0b1010 1110 (0xAE)
如果第二个秘钥匹配正确,FLASH_IAPSR的DUL位自动置位。
3. 等待DATA EEPROM区解锁。
void EEPROM_Init()
{
  FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_TPROG);
  // 注意顺序: FLASH_DUKR = 0xAE为Key2 ,FLASH_DUKR = 0x56;为Key1
   FLASH_Unlock( FLASH_MEMTYPE_DATA);
   //如果第二个秘钥正确,FLASH_IAPSR_DUL=1;
   //直到FLASH_IAPSR_DUL由硬件置位,才跳出while循环
  while((FLASH->IAPSR & FLASH_IAPSR_DUL) == 0);//等待DATA EEPROM区解锁
}

FLASH_Unlock函数原型在stm8s_flash.c中:
void FLASH_Unlock(FLASH_MemType_TypeDef FLASH_MemType)
{
    assert_param(IS_MEMORY_TYPE_OK(FLASH_MemType));
    if (FLASH_MemType == FLASH_MEMTYPE_PROG)
    {
        FLASH->PUKR = FLASH_RASS_KEY1;
        FLASH->PUKR = FLASH_RASS_KEY2;
    }
    else
    {
        FLASH->DUKR = FLASH_RASS_KEY2;
        FLASH->DUKR = FLASH_RASS_KEY1;
    }
}
在main.c中,你就可以进行擦除,读,写操作了!
  FLASH_EraseByte(uint32_t Address);  // 擦除某地址的一个字节
  FLASH_ProgramByte(0x4001,0x08); //写入一个字节
  while((FLASH_IAPSR & 0x04) != 0x00);   //直到EOP=1,EEPROM编程结束
  Rdat= FLASH_ReadByte(0x4000);   // 读出某地址的一个字节

沙发
598330983| | 2016-5-23 20:08 | 只看该作者
FLASH_ProgramByte(0x4001,0x08); //写入一个字节
这两个怎么解释,第一个是写入的地址,第二个8呢,是写入的数据吗?

使用特权

评论回复
板凳
cnsxgh| | 2016-5-23 20:16 | 只看该作者
讲的不错,赞一个。别外想请教楼主个问题
https://bbs.21ic.com/forum.php?mod=viewthread&tid=1593718
希望有时间的时候帮忙看看。谢谢

使用特权

评论回复
地板
捉虫天师| | 2016-5-23 20:23 | 只看该作者
实际上还是有内部够用的,还是不接外部的,浪费钱,另外接的多容易出问题。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

174

主题

3361

帖子

13

粉丝