EEPROM它是单片机应用系统中常用的存储器,主要用于保存一些断电后需要保持不变的数据。在以前的单片机系统中,通常在单片机外扩展另一个EEPROM芯片,这种方法除了增加成本外,也降低了可靠性。现在,很多单片机的公司都推出了集成有小容量EEPROM单片机使用方便,降低成本,提高可靠性。
STM8单片机芯片内部也集成了EEPROM,容量从640字节到2K字节。最有特色的是,在STM8在单片机中,对EEPROM访问就像常规RAM一样,很方便。EEPROM地址空间和内存统一编制,地址从004000H一开始,尺寸取决于不同的芯片型号。
下面的实验程序是先给出EEPROM第一个单004000H写入55H,然后读取全局变量ch中。
同样使用ST生成开发工具的开发工具C然后修改语言程序的框架main.c,修改后的代码如下。
// 程序描述:芯片内部EEPROM存储单元进行实验
#include "STM8S207C_S.h"
unsigned char ch;
main()
{
unsigned char *p;
p = (unsigned char *)0x4000; // 指针p指向芯片内部EEPROM第一个单元
// 对数据EEPROM进行解锁
do
{
FLASH_DUKR = 0xae; // 写入第一个密钥
FLASH_DUKR = 0x56; // 写入第二个密钥
} while((FLASH_IAPSR & 0x08) == 0); // 若解锁未成功,则重新再来
*p = 0xaa; // 写入第一个字节
while((FLASH_IAPSR & 0x04) == 0); // 等待写操作成功
ch = *p; // 将写入的内容读到变量ch中
while(1)
{
;
}
}
这里要注意的是,2个密钥的顺序,与STM8的用户手册上是相反的,如果按照手册上的顺序,就会停留在do…while循环中。具体原因,也不是很清楚,也可能是我拿到的手册(中文和英文的都一样)太旧了,或者是理解有误。
另外,上面的实验程序中,ch不能为局部变量,否则的话,在调试环境中跟踪ch变量时,显示的结果就不对,通过反汇编,我觉得是编译有问题,当定义成局部变量时,ch = *p的汇编代码如下:
main.c:23 ch = *p; // 将写入的内容读到变量ch中
0x80f0 <main+34> 0x7B01 LD A,(0x01,SP) LD A,(0x01,SP)
0x80f2 <main+36> 0x97 LD XL,A LD XL,A
0x80f3 <main+37> 0x1E02 LDW X,(0x02,SP) LDW X,(0x02,SP)
0x80f5 <main+39> 0xF6 LD A,(X) LD A,(X)
0x80f6 <main+40> 0x97 LD XL,A LD XL,A
如果将ch定义成全局变量,则汇编代码为:
main.c:22 ch = *p; // 将写入的内容读到变量ch中
0x80ef <main+33> 0x1E01 LDW X,(0x01,SP) LDW X,(0x01,SP)
0x80f1 <main+35> 0xF6 LD A,(X) LD A,(X)
0x80f2 <main+36> 0xB700 LD 0x00,A LD 0x00,A
这一段代码的分析仅供参考,本人使用的开发环境为STVD4.1.0,编译器版本号为:COSMIC的CxSTM84.2.4。